Skip to content

Commit

Permalink
Update GeoIP2 extension to new GeoLite2 .mmdb database format (#1245)
Browse files Browse the repository at this point in the history
* Add support for Maxmind GeoIP2 database files (#913).

* Copy/paste error.

* Mark GeoipCode3 as deprecated.

* Fix build when compiling with AMBuild.

* Replace loose libmaxminddb files with submodule.

* Fix Linux build.

* One more hack for submodule.

* Actually fix Linux build.

* GeoIP2 extension to sourcemod

* Update basevotes

When a player leaves during a voteban, he will be banned anyway. Also added a cvar with a ban time setting.

* Update basevotes.sp

* Update AMBuilder

* ke::AString to std::string

* Update extension.cpp

* Update AMBuilder

* Added coordination natives

Added GeoipLatitude, GeoipLongitude, GeoipDistance natives.

* Create osdefs.h

* Update maxminddb_config.h

* Update extension.cpp

* Update extension.cpp

* Added automatic search for database file

* Fix automatic search for database file

* Update extension.cpp

* Update geoip.inc

* .gitmodules revert

* Update geoip.inc

* Update libmaxminddb to version 1.5.2

* Update extension.cpp

* Check language in the DB

* Removed langCount variable

* Determination of the client's language

* Update geoip.inc

* Update geoip.inc

* Update extension.cpp

* Update geoip.inc

* Update extension.cpp

* space instead of tab in .inc

* Update extension.cpp

* Update geoip.inc

* Optimizing length measurement region code

* Update package script to fetch the new GeoLite2 database

This package is the last CC-BY-SA licensed GeoLite2-City database extracted from https://src.fedoraproject.org/rpms/geolite2 from december 2019.

This doubles the download size for SM packages, but it's what we have to deal with atm :(

* Fix potentially returning uninitialized memory in GeoipRegionCode

If the lookup failed, we'd copy back whatever is on the stack in the ccode buffer.

Co-authored-by: Nick Hastings <nshastings@gmail.com>
Co-authored-by: Headline <michaelwflaherty@me.com>
Co-authored-by: Accelerator74 <dmitry@447751-accele74.tmweb.ru>
Co-authored-by: Peace-Maker <peace-maker@wcfan.de>
  • Loading branch information
5 people committed Jun 30, 2021
1 parent c38d45b commit b0563a4
Show file tree
Hide file tree
Showing 17 changed files with 3,526 additions and 1,208 deletions.
9 changes: 5 additions & 4 deletions extensions/geoip/AMBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ for cxx in builder.targets:
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if binary.compiler.target.platform == 'windows':
binary.compiler.postlink += ['wsock32.lib']
binary.compiler.postlink += ['wsock32.lib', 'ws2_32.lib']

binary.sources += [
'extension.cpp',
'GeoIP.c',
'../../public/smsdk_ext.cpp'
'geoip_util.cpp',
'../../public/smsdk_ext.cpp',
'data-pool.c',
'maxminddb.c',
]

SM.extensions += [builder.Add(binary)]

969 changes: 0 additions & 969 deletions extensions/geoip/GeoIP.c

This file was deleted.

169 changes: 0 additions & 169 deletions extensions/geoip/GeoIP.h

This file was deleted.

169 changes: 169 additions & 0 deletions extensions/geoip/data-pool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#include "data-pool.h"
#include "maxminddb.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>

static bool can_multiply(size_t const, size_t const, size_t const);

// Allocate an MMDB_data_pool_s. It initially has space for size
// MMDB_entry_data_list_s structs.
MMDB_data_pool_s *data_pool_new(size_t const size) {
MMDB_data_pool_s *const pool = calloc(1, sizeof(MMDB_data_pool_s));
if (!pool) {
return NULL;
}

if (size == 0 ||
!can_multiply(SIZE_MAX, size, sizeof(MMDB_entry_data_list_s))) {
data_pool_destroy(pool);
return NULL;
}
pool->size = size;
pool->blocks[0] = calloc(pool->size, sizeof(MMDB_entry_data_list_s));
if (!pool->blocks[0]) {
data_pool_destroy(pool);
return NULL;
}
pool->blocks[0]->pool = pool;

pool->sizes[0] = size;

pool->block = pool->blocks[0];

return pool;
}

// Determine if we can multiply m*n. We can do this if the result will be below
// the given max. max will typically be SIZE_MAX.
//
// We want to know if we'll wrap around.
static bool can_multiply(size_t const max, size_t const m, size_t const n) {
if (m == 0) {
return false;
}

return n <= max / m;
}

// Clean up the data pool.
void data_pool_destroy(MMDB_data_pool_s *const pool) {
if (!pool) {
return;
}

for (size_t i = 0; i <= pool->index; i++) {
free(pool->blocks[i]);
}

free(pool);
}

// Claim a new struct from the pool. Doing this may cause the pool's size to
// grow.
MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const pool) {
if (!pool) {
return NULL;
}

if (pool->used < pool->size) {
MMDB_entry_data_list_s *const element = pool->block + pool->used;
pool->used++;
return element;
}

// Take it from a new block of memory.

size_t const new_index = pool->index + 1;
if (new_index == DATA_POOL_NUM_BLOCKS) {
// See the comment about not growing this on DATA_POOL_NUM_BLOCKS.
return NULL;
}

if (!can_multiply(SIZE_MAX, pool->size, 2)) {
return NULL;
}
size_t const new_size = pool->size * 2;

if (!can_multiply(SIZE_MAX, new_size, sizeof(MMDB_entry_data_list_s))) {
return NULL;
}
pool->blocks[new_index] = calloc(new_size, sizeof(MMDB_entry_data_list_s));
if (!pool->blocks[new_index]) {
return NULL;
}

// We don't need to set this, but it's useful for introspection in tests.
pool->blocks[new_index]->pool = pool;

pool->index = new_index;
pool->block = pool->blocks[pool->index];

pool->size = new_size;
pool->sizes[pool->index] = pool->size;

MMDB_entry_data_list_s *const element = pool->block;
pool->used = 1;
return element;
}

// Turn the structs in the array-like pool into a linked list.
//
// Before calling this function, the list isn't linked up.
MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const pool) {
if (!pool) {
return NULL;
}

if (pool->index == 0 && pool->used == 0) {
return NULL;
}

for (size_t i = 0; i <= pool->index; i++) {
MMDB_entry_data_list_s *const block = pool->blocks[i];

size_t size = pool->sizes[i];
if (i == pool->index) {
size = pool->used;
}

for (size_t j = 0; j < size - 1; j++) {
MMDB_entry_data_list_s *const cur = block + j;
cur->next = block + j + 1;
}

if (i < pool->index) {
MMDB_entry_data_list_s *const last = block + size - 1;
last->next = pool->blocks[i + 1];
}
}

return pool->blocks[0];
}

#ifdef TEST_DATA_POOL

#include <libtap/tap.h>
#include <maxminddb_test_helper.h>

static void test_can_multiply(void);

int main(void) {
plan(NO_PLAN);
test_can_multiply();
done_testing();
}

static void test_can_multiply(void) {
{ ok(can_multiply(SIZE_MAX, 1, SIZE_MAX), "1*SIZE_MAX is ok"); }

{ ok(!can_multiply(SIZE_MAX, 2, SIZE_MAX), "2*SIZE_MAX is not ok"); }

{
ok(can_multiply(SIZE_MAX, 10240, sizeof(MMDB_entry_data_list_s)),
"1024 entry_data_list_s's are okay");
}
}

#endif

0 comments on commit b0563a4

Please sign in to comment.