-
-
Notifications
You must be signed in to change notification settings - Fork 420
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update GeoIP2 extension to new GeoLite2 .mmdb database format (#1245)
* 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
1 parent
c38d45b
commit b0563a4
Showing
17 changed files
with
3,526 additions
and
1,208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
Oops, something went wrong.