1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00

Update MaxMind DB library to current master.

This commit is contained in:
Sandu Liviu Catalin 2019-08-17 15:47:43 +03:00
parent 33ed902a72
commit 8769051980
8 changed files with 436 additions and 524 deletions

View File

@ -410,8 +410,8 @@
<Compiler>
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-std=c99" />
<Add option="-std=c++14" />
<Add option="-std=c99" />
<Add option="-DSQMOD_PLUGIN_API" />
<Add option="-DSCRAT_USE_EXCEPTIONS" />
<Add option="-DSCRAT_USE_CXX11_OPTIMIZATIONS" />
@ -421,6 +421,10 @@
<Add directory="../config/common" />
<Add directory="../external/MaxmindDB" />
</Compiler>
<Unit filename="../external/MaxmindDB/data-pool.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../external/MaxmindDB/data-pool.h" />
<Unit filename="../external/MaxmindDB/maxminddb.c">
<Option compilerVar="CC" />
<Option compiler="gcc" use="1" buildCommand="$compiler -Wno-unused-parameter -Wno-sign-compare $options $includes -c $file -o $object" />
@ -445,7 +449,7 @@
<Unit filename="../modules/mmdb/SearchNode.cpp" />
<Unit filename="../modules/mmdb/SearchNode.hpp" />
<Unit filename="../modules/mmdb/SockAddr.cpp" />
<Unit filename="../modules/mmdb/Sockaddr.hpp" />
<Unit filename="../modules/mmdb/SockAddr.hpp" />
<Unit filename="../shared/Base/Buffer.cpp" />
<Unit filename="../shared/Base/Buffer.hpp" />
<Unit filename="../shared/Base/Module.cpp" />
@ -456,6 +460,7 @@
<envvars />
<debugger />
<lib_finder disable_auto="1" />
<fortran_project />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -0,0 +1,14 @@
#ifndef MAXMINDDB_CONFIG_H
#define MAXMINDDB_CONFIG_H
#ifndef MMDB_UINT128_USING_MODE
/* Define as 1 if we we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
#define MMDB_UINT128_USING_MODE 1
#endif
#ifndef MMDB_UINT128_IS_BYTE_ARRAY
/* Define as 1 if we don't have an unsigned __int128 type */
#undef MMDB_UINT128_IS_BYTE_ARRAY
#endif
#endif /* MAXMINDDB_CONFIG_H */

View File

@ -1,193 +0,0 @@
/* include/maxminddb_config.h. Generated from maxminddb_config.h.in by configure. */
#ifndef MAXMINDDB_CONFIG_H
#define MAXMINDDB_CONFIG_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if the system has the type `boolean'. */
/* #undef HAVE_BOOLEAN */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <libgen.h> header file. */
#define HAVE_LIBGEN_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have a working `mmap' system call. */
/* #undef HAVE_MMAP */
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Has an open_memstream() function */
/* #undef HAVE_OPEN_MEMSTREAM */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Missing the unsigned __int128 type */
#define MMDB_UINT128_IS_BYTE_ARRAY 1
/* int128 types are available with __attribute__((mode(TI))) */
/* #undef MMDB_UINT128_USING_MODE */
/* Name of package */
#define PACKAGE "libmaxminddb"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "support@maxmind.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libmaxminddb"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libmaxminddb 1.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libmaxminddb"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.2.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.2.1"
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT64_T */
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is
supported directly. */
#define restrict __restrict
/* Work around a bug in Sun C++: it does not support _Restrict or
__restrict__, even though the corresponding Sun C compiler ends up with
"#define restrict _Restrict" or "#define restrict __restrict__" in the
previous line. Perhaps some future version of Sun C++ will work with
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
#if defined __SUNPRO_CC && !defined __RESTRICT
# define _Restrict
# define __restrict__
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint64_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
#ifndef MMDB_UINT128_USING_MODE
/* Define as 1 if we we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
#define MMDB_UINT128_USING_MODE 0
#endif
#ifndef MMDB_UINT128_IS_BYTE_ARRAY
/* Define as 1 if we don't have an unsigned __int128 type */
#define MMDB_UINT128_IS_BYTE_ARRAY 0
#endif
#endif /* MAXMINDDB_CONFIG_H */

View File

@ -1,193 +0,0 @@
/* include/maxminddb_config.h. Generated from maxminddb_config.h.in by configure. */
#ifndef MAXMINDDB_CONFIG_H
#define MAXMINDDB_CONFIG_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */
/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define to 1 if the system has the type `boolean'. */
/* #undef HAVE_BOOLEAN */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <libgen.h> header file. */
#define HAVE_LIBGEN_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <math.h> header file. */
#define HAVE_MATH_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have a working `mmap' system call. */
/* #undef HAVE_MMAP */
/* Define to 1 if you have the <netdb.h> header file. */
/* #undef HAVE_NETDB_H */
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Has an open_memstream() function */
/* #undef HAVE_OPEN_MEMSTREAM */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Missing the unsigned __int128 type */
#define MMDB_UINT128_IS_BYTE_ARRAY 0
/* int128 types are available with __attribute__((mode(TI))) */
/* #undef MMDB_UINT128_USING_MODE */
/* Name of package */
#define PACKAGE "libmaxminddb"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "support@maxmind.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libmaxminddb"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libmaxminddb 1.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libmaxminddb"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.2.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.2.1"
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT64_T */
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is
supported directly. */
#define restrict __restrict
/* Work around a bug in Sun C++: it does not support _Restrict or
__restrict__, even though the corresponding Sun C compiler ends up with
"#define restrict _Restrict" or "#define restrict __restrict__" in the
previous line. Perhaps some future version of Sun C++ will work with
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
#if defined __SUNPRO_CC && !defined __RESTRICT
# define _Restrict
# define __restrict__
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint64_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
#ifndef MMDB_UINT128_USING_MODE
/* Define as 1 if we we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
#define MMDB_UINT128_USING_MODE 0
#endif
#ifndef MMDB_UINT128_IS_BYTE_ARRAY
/* Define as 1 if we don't have an unsigned __int128 type */
#define MMDB_UINT128_IS_BYTE_ARRAY 0
#endif
#endif /* MAXMINDDB_CONFIG_H */

180
external/MaxmindDB/data-pool.c vendored Normal file
View File

@ -0,0 +1,180 @@
#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

52
external/MaxmindDB/data-pool.h vendored Normal file
View File

@ -0,0 +1,52 @@
#ifndef DATA_POOL_H
#define DATA_POOL_H
#include "maxminddb.h"
#include <stdbool.h>
#include <stddef.h>
// This should be large enough that we never need to grow the array of pointers
// to blocks. 32 is enough. Even starting out of with size 1 (1 struct), the
// 32nd element alone will provide 2**32 structs as we exponentially increase
// the number in each block. Being confident that we do not have to grow the
// array lets us avoid writing code to do that. That code would be risky as it
// would rarely be hit and likely not be well tested.
#define DATA_POOL_NUM_BLOCKS 32
// A pool of memory for MMDB_entry_data_list_s structs. This is so we can
// allocate multiple up front rather than one at a time for performance
// reasons.
//
// The order you add elements to it (by calling data_pool_alloc()) ends up as
// the order of the list.
//
// The memory only grows. There is no support for releasing an element you take
// back to the pool.
typedef struct MMDB_data_pool_s {
// Index of the current block we're allocating out of.
size_t index;
// The size of the current block, counting by structs.
size_t size;
// How many used in the current block, counting by structs.
size_t used;
// The current block we're allocating out of.
MMDB_entry_data_list_s *block;
// The size of each block.
size_t sizes[DATA_POOL_NUM_BLOCKS];
// An array of pointers to blocks of memory holding space for list
// elements.
MMDB_entry_data_list_s *blocks[DATA_POOL_NUM_BLOCKS];
} MMDB_data_pool_s;
MMDB_data_pool_s *data_pool_new(size_t const);
void data_pool_destroy(MMDB_data_pool_s *const);
MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const);
MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const);
#endif

View File

@ -1,6 +1,7 @@
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "data-pool.h"
#include "maxminddb.h"
#include "maxminddb-compat-util.h"
#include <assert.h>
@ -13,6 +14,9 @@
#include <sys/stat.h>
#ifdef _WIN32
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <ws2ipdef.h>
#else
@ -26,8 +30,6 @@
#ifdef MMDB_DEBUG
#define LOCAL
#define NO_PROTO
#define DEBUG_FUNC
#define DEBUG_MSG(msg) fprintf(stderr, msg "\n")
#define DEBUG_MSGF(fmt, ...) fprintf(stderr, fmt "\n", __VA_ARGS__)
#define DEBUG_BINARY(fmt, byte) \
@ -43,7 +45,6 @@
#define DEBUG_NL fprintf(stderr, "\n")
#else
#define LOCAL static
#define NO_PROTO static
#define DEBUG_MSG(...)
#define DEBUG_MSGF(...)
#define DEBUG_BINARY(...)
@ -51,7 +52,7 @@
#endif
#ifdef MMDB_DEBUG
DEBUG_FUNC char *byte_to_binary(uint8_t byte)
char *byte_to_binary(uint8_t byte)
{
char *bits = malloc(sizeof(char) * 9);
if (NULL == bits) {
@ -66,7 +67,7 @@ DEBUG_FUNC char *byte_to_binary(uint8_t byte)
return bits;
}
DEBUG_FUNC char *type_num_to_name(uint8_t num)
char *type_num_to_name(uint8_t num)
{
switch (num) {
case 0:
@ -130,13 +131,14 @@ typedef struct record_info_s {
/* This is 128kb */
#define METADATA_BLOCK_MAX_SIZE 131072
/* *INDENT-OFF* */
/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
// 64 leads us to allocating 4 KiB on a 64bit system.
#define MMDB_POOL_INIT_SIZE 64
LOCAL int map_file(MMDB_s *const mmdb);
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
ssize_t file_size, uint32_t *metadata_size);
LOCAL int read_metadata(MMDB_s *mmdb);
LOCAL MMDB_s make_fake_metadata_db(MMDB_s *mmdb);
LOCAL MMDB_s make_fake_metadata_db(const MMDB_s *const mmdb);
LOCAL int value_for_key_as_uint16(MMDB_entry_s *start, char *key,
uint16_t *value);
LOCAL int value_for_key_as_uint32(MMDB_entry_s *start, char *key,
@ -150,34 +152,38 @@ LOCAL int populate_languages_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
MMDB_entry_s *metadata_start);
LOCAL int resolve_any_address(const char *ipstr, struct addrinfo **addresses);
LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
LOCAL int find_address_in_search_tree(const MMDB_s *const mmdb,
uint8_t *address,
sa_family_t address_family,
MMDB_lookup_result_s *result);
LOCAL record_info_s record_info_for_database(MMDB_s *mmdb);
LOCAL int find_ipv4_start_node(MMDB_s *mmdb);
LOCAL uint8_t maybe_populate_result(MMDB_s *mmdb, uint32_t record,
LOCAL record_info_s record_info_for_database(const MMDB_s *const mmdb);
LOCAL int find_ipv4_start_node(MMDB_s *const mmdb);
LOCAL uint8_t maybe_populate_result(const MMDB_s *const mmdb, uint32_t record,
uint16_t netmask,
MMDB_lookup_result_s *result);
LOCAL uint8_t record_type(MMDB_s *const mmdb, uint64_t record);
LOCAL uint8_t record_type(const MMDB_s *const mmdb, uint64_t record);
LOCAL uint32_t get_left_28_bit_record(const uint8_t *record);
LOCAL uint32_t get_right_28_bit_record(const uint8_t *record);
LOCAL uint32_t data_section_offset_for_record(MMDB_s *const mmdb,
LOCAL uint32_t data_section_offset_for_record(const MMDB_s *const mmdb,
uint64_t record);
LOCAL int path_length(va_list va_path);
LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
LOCAL int lookup_path_in_array(const char *path_elem, const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data);
LOCAL int lookup_path_in_map(const char *path_elem, MMDB_s *mmdb,
LOCAL int lookup_path_in_map(const char *path_elem, const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data);
LOCAL int skip_map_or_array(MMDB_s *mmdb, MMDB_entry_data_s *entry_data);
LOCAL int decode_one_follow(MMDB_s *mmdb, uint32_t offset,
LOCAL int skip_map_or_array(const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data);
LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset,
LOCAL int decode_one_follow(const MMDB_s *const mmdb, uint32_t offset,
MMDB_entry_data_s *entry_data);
LOCAL int decode_one(const MMDB_s *const mmdb, uint32_t offset,
MMDB_entry_data_s *entry_data);
LOCAL int get_ext_type(int raw_ext_type);
LOCAL uint32_t get_ptr_from(uint8_t ctrl, uint8_t const *const ptr,
int ptr_size);
LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
LOCAL int get_entry_data_list(const MMDB_s *const mmdb,
uint32_t offset,
MMDB_entry_data_list_s *const entry_data_list,
MMDB_data_pool_s *const pool,
int depth);
LOCAL float get_ieee754_float(const uint8_t *restrict p);
LOCAL double get_ieee754_double(const uint8_t *restrict p);
@ -186,7 +192,6 @@ LOCAL uint32_t get_uint24(const uint8_t *p);
LOCAL uint32_t get_uint16(const uint8_t *p);
LOCAL uint64_t get_uintX(const uint8_t *p, int length);
LOCAL int32_t get_sintX(const uint8_t *p, int length);
LOCAL MMDB_entry_data_list_s *new_entry_data_list(void);
LOCAL void free_mmdb_struct(MMDB_s *const mmdb);
LOCAL void free_languages_metadata(MMDB_s *mmdb);
LOCAL void free_descriptions_metadata(MMDB_s *mmdb);
@ -195,8 +200,6 @@ LOCAL MMDB_entry_data_list_s *dump_entry_data_list(
int *status);
LOCAL void print_indentation(FILE *stream, int i);
LOCAL char *bytes_to_hex(uint8_t *bytes, uint32_t size);
/* --prototypes end - don't remove this comment-- */
/* *INDENT-ON* */
#define CHECKED_DECODE_ONE(mmdb, offset, entry_data) \
do { \
@ -228,6 +231,7 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
mmdb->data_section = NULL;
mmdb->metadata.database_type = NULL;
mmdb->metadata.languages.count = 0;
mmdb->metadata.languages.names = NULL;
mmdb->metadata.description.count = 0;
mmdb->filename = mmdb_strdup(filename);
@ -241,7 +245,7 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
}
mmdb->flags = flags;
if (MMDB_SUCCESS != (status = map_file(mmdb)) ) {
if (MMDB_SUCCESS != (status = map_file(mmdb))) {
goto cleanup;
}
@ -297,6 +301,15 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
mmdb->ipv4_start_node.node_value = 0;
mmdb->ipv4_start_node.netmask = 0;
// We do this immediately as otherwise there is a race to set
// ipv4_start_node.node_value and ipv4_start_node.netmask.
if (mmdb->metadata.ip_version == 6) {
status = find_ipv4_start_node(mmdb);
if (status != MMDB_SUCCESS) {
goto cleanup;
}
}
cleanup:
if (MMDB_SUCCESS != status) {
int saved_errno = errno;
@ -308,12 +321,32 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
#ifdef _WIN32
LOCAL LPWSTR utf8_to_utf16(const char *utf8_str)
{
int wide_chars = MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, NULL, 0);
wchar_t *utf16_str = (wchar_t *)malloc(wide_chars * sizeof(wchar_t));
if (MultiByteToWideChar(CP_UTF8, 0, utf8_str, -1, utf16_str,
wide_chars) < 1) {
free(utf16_str);
return NULL;
}
return utf16_str;
}
LOCAL int map_file(MMDB_s *const mmdb)
{
DWORD size;
int status = MMDB_SUCCESS;
HANDLE mmh = NULL;
HANDLE fd = CreateFileA(mmdb->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
HANDLE fd = INVALID_HANDLE_VALUE;
LPWSTR utf16_filename = utf8_to_utf16(mmdb->filename);
if (!utf16_filename) {
status = MMDB_FILE_OPEN_ERROR;
goto cleanup;
}
fd = CreateFile(utf16_filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd == INVALID_HANDLE_VALUE) {
status = MMDB_FILE_OPEN_ERROR;
@ -324,7 +357,7 @@ LOCAL int map_file(MMDB_s *const mmdb)
status = MMDB_FILE_OPEN_ERROR;
goto cleanup;
}
mmh = CreateFileMappingA(fd, NULL, PAGE_READONLY, 0, size, NULL);
mmh = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL);
/* Microsoft documentation for CreateFileMapping indicates this returns
NULL not INVALID_HANDLE_VALUE on error */
if (NULL == mmh) {
@ -350,18 +383,23 @@ LOCAL int map_file(MMDB_s *const mmdb)
CloseHandle(mmh);
}
errno = saved_errno;
free(utf16_filename);
return status;
}
#else
#else // _WIN32
LOCAL int map_file(MMDB_s *const mmdb)
{
ssize_t size;
int status = MMDB_SUCCESS;
int fd = open(mmdb->filename, O_RDONLY);
int flags = O_RDONLY;
#ifdef O_CLOEXEC
flags |= O_CLOEXEC;
#endif
int fd = open(mmdb->filename, flags);
struct stat s;
if (fd < 0 || fstat(fd, &s)) {
status = MMDB_FILE_OPEN_ERROR;
@ -398,7 +436,7 @@ LOCAL int map_file(MMDB_s *const mmdb)
return status;
}
#endif
#endif // _WIN32
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
ssize_t file_size, uint32_t *metadata_size)
@ -548,7 +586,7 @@ LOCAL int read_metadata(MMDB_s *mmdb)
return MMDB_SUCCESS;
}
LOCAL MMDB_s make_fake_metadata_db(MMDB_s *mmdb)
LOCAL MMDB_s make_fake_metadata_db(const MMDB_s *const mmdb)
{
MMDB_s fake_metadata_db = {
.data_section = mmdb->metadata_section,
@ -796,7 +834,7 @@ LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
return status;
}
MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
MMDB_lookup_result_s MMDB_lookup_string(const MMDB_s *const mmdb,
const char *const ipstr,
int *const gai_error,
int *const mmdb_error)
@ -842,7 +880,7 @@ LOCAL int resolve_any_address(const char *ipstr, struct addrinfo **addresses)
}
MMDB_lookup_result_s MMDB_lookup_sockaddr(
MMDB_s *const mmdb,
const MMDB_s *const mmdb,
const struct sockaddr *const sockaddr,
int *const mmdb_error)
{
@ -882,7 +920,8 @@ MMDB_lookup_result_s MMDB_lookup_sockaddr(
return result;
}
LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
LOCAL int find_address_in_search_tree(const MMDB_s *const mmdb,
uint8_t *address,
sa_family_t address_family,
MMDB_lookup_result_s *result)
{
@ -899,10 +938,7 @@ LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
uint16_t start_bit = max_depth0;
if (mmdb->metadata.ip_version == 6 && address_family == AF_INET) {
int mmdb_error = find_ipv4_start_node(mmdb);
if (MMDB_SUCCESS != mmdb_error) {
return mmdb_error;
}
/* ipv4 start node values set at open */
DEBUG_MSGF("IPv4 start node is %u (netmask %u)",
mmdb->ipv4_start_node.node_value,
mmdb->ipv4_start_node.netmask);
@ -966,7 +1002,7 @@ LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
return MMDB_CORRUPT_SEARCH_TREE_ERROR;
}
LOCAL record_info_s record_info_for_database(MMDB_s *mmdb)
LOCAL record_info_s record_info_for_database(const MMDB_s *const mmdb)
{
record_info_s record_info = {
.record_length = mmdb->full_record_byte_size,
@ -992,7 +1028,7 @@ LOCAL record_info_s record_info_for_database(MMDB_s *mmdb)
return record_info;
}
LOCAL int find_ipv4_start_node(MMDB_s *mmdb)
LOCAL int find_ipv4_start_node(MMDB_s *const mmdb)
{
/* In a pathological case of a database with a single node search tree,
* this check will be true even after we've found the IPv4 start node, but
@ -1026,7 +1062,7 @@ LOCAL int find_ipv4_start_node(MMDB_s *mmdb)
return MMDB_SUCCESS;
}
LOCAL uint8_t maybe_populate_result(MMDB_s *mmdb, uint32_t record,
LOCAL uint8_t maybe_populate_result(const MMDB_s *const mmdb, uint32_t record,
uint16_t netmask,
MMDB_lookup_result_s *result)
{
@ -1048,7 +1084,7 @@ LOCAL uint8_t maybe_populate_result(MMDB_s *mmdb, uint32_t record,
return type;
}
LOCAL uint8_t record_type(MMDB_s *const mmdb, uint64_t record)
LOCAL uint8_t record_type(const MMDB_s *const mmdb, uint64_t record)
{
uint32_t node_count = mmdb->metadata.node_count;
@ -1088,7 +1124,7 @@ LOCAL uint32_t get_right_28_bit_record(const uint8_t *record)
return value & 0xfffffff;
}
int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
int MMDB_read_node(const MMDB_s *const mmdb, uint32_t node_number,
MMDB_search_node_s *const node)
{
record_info_s record_info = record_info_for_database(mmdb);
@ -1125,7 +1161,7 @@ int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
return MMDB_SUCCESS;
}
LOCAL uint32_t data_section_offset_for_record(MMDB_s *const mmdb,
LOCAL uint32_t data_section_offset_for_record(const MMDB_s *const mmdb,
uint64_t record)
{
return (uint32_t)record - mmdb->metadata.node_count -
@ -1192,7 +1228,7 @@ int MMDB_aget_value(MMDB_entry_s *const start,
MMDB_entry_data_s *const entry_data,
const char *const *const path)
{
MMDB_s *mmdb = start->mmdb;
const MMDB_s *const mmdb = start->mmdb;
uint32_t offset = start->offset;
memset(entry_data, 0, sizeof(MMDB_entry_data_s));
@ -1245,7 +1281,8 @@ int MMDB_aget_value(MMDB_entry_s *const start,
return MMDB_SUCCESS;
}
LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
LOCAL int lookup_path_in_array(const char *path_elem,
const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data)
{
uint32_t size = entry_data->data_size;
@ -1254,12 +1291,20 @@ LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
int saved_errno = errno;
errno = 0;
int array_index = strtol(path_elem, &first_invalid, 10);
if (array_index < 0 || ERANGE == errno) {
if (ERANGE == errno) {
errno = saved_errno;
return MMDB_INVALID_LOOKUP_PATH_ERROR;
}
errno = saved_errno;
if (array_index < 0) {
array_index += size;
if (array_index < 0) {
return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
}
}
if (*first_invalid || (uint32_t)array_index >= size) {
return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
}
@ -1281,7 +1326,8 @@ LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
return MMDB_SUCCESS;
}
LOCAL int lookup_path_in_map(const char *path_elem, MMDB_s *mmdb,
LOCAL int lookup_path_in_map(const char *path_elem,
const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data)
{
uint32_t size = entry_data->data_size;
@ -1322,7 +1368,8 @@ LOCAL int lookup_path_in_map(const char *path_elem, MMDB_s *mmdb,
return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
}
LOCAL int skip_map_or_array(MMDB_s *mmdb, MMDB_entry_data_s *entry_data)
LOCAL int skip_map_or_array(const MMDB_s *const mmdb,
MMDB_entry_data_s *entry_data)
{
if (entry_data->type == MMDB_DATA_TYPE_MAP) {
uint32_t size = entry_data->data_size;
@ -1348,7 +1395,7 @@ LOCAL int skip_map_or_array(MMDB_s *mmdb, MMDB_entry_data_s *entry_data)
return MMDB_SUCCESS;
}
LOCAL int decode_one_follow(MMDB_s *mmdb, uint32_t offset,
LOCAL int decode_one_follow(const MMDB_s *const mmdb, uint32_t offset,
MMDB_entry_data_s *entry_data)
{
CHECKED_DECODE_ONE(mmdb, offset, entry_data);
@ -1378,7 +1425,7 @@ LOCAL int decode_one_follow(MMDB_s *mmdb, uint32_t offset,
}
#if !MMDB_UINT128_IS_BYTE_ARRAY
NO_PROTO mmdb_uint128_t get_uint128(const uint8_t *p, int length)
LOCAL mmdb_uint128_t get_uint128(const uint8_t *p, int length)
{
mmdb_uint128_t value = 0;
while (length-- > 0) {
@ -1389,7 +1436,7 @@ NO_PROTO mmdb_uint128_t get_uint128(const uint8_t *p, int length)
}
#endif
LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset,
LOCAL int decode_one(const MMDB_s *const mmdb, uint32_t offset,
MMDB_entry_data_s *entry_data)
{
const uint8_t *mem = mmdb->data_section;
@ -1619,7 +1666,7 @@ LOCAL uint32_t get_ptr_from(uint8_t ctrl, uint8_t const *const ptr,
}
int MMDB_get_metadata_as_entry_data_list(
MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list)
const MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list)
{
MMDB_s metadata_db = make_fake_metadata_db(mmdb);
@ -1634,15 +1681,33 @@ int MMDB_get_metadata_as_entry_data_list(
int MMDB_get_entry_data_list(
MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list)
{
*entry_data_list = new_entry_data_list();
if (NULL == *entry_data_list) {
MMDB_data_pool_s *const pool = data_pool_new(MMDB_POOL_INIT_SIZE);
if (!pool) {
return MMDB_OUT_OF_MEMORY_ERROR;
}
return get_entry_data_list(start->mmdb, start->offset, *entry_data_list, 0);
MMDB_entry_data_list_s *const list = data_pool_alloc(pool);
if (!list) {
data_pool_destroy(pool);
return MMDB_OUT_OF_MEMORY_ERROR;
}
int const status = get_entry_data_list(start->mmdb, start->offset, list,
pool, 0);
*entry_data_list = data_pool_to_list(pool);
if (!*entry_data_list) {
data_pool_destroy(pool);
return MMDB_OUT_OF_MEMORY_ERROR;
}
return status;
}
LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
LOCAL int get_entry_data_list(const MMDB_s *const mmdb,
uint32_t offset,
MMDB_entry_data_list_s *const entry_data_list,
MMDB_data_pool_s *const pool,
int depth)
{
if (depth >= MAXIMUM_DATA_STRUCTURE_DEPTH) {
@ -1672,7 +1737,7 @@ LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
int status =
get_entry_data_list(mmdb, last_offset, entry_data_list,
depth);
pool, depth);
if (MMDB_SUCCESS != status) {
DEBUG_MSG("get_entry_data_list on pointer failed.");
return status;
@ -1685,26 +1750,22 @@ LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
{
uint32_t array_size = entry_data_list->entry_data.data_size;
uint32_t array_offset = entry_data_list->entry_data.offset_to_next;
MMDB_entry_data_list_s *previous = entry_data_list;
while (array_size-- > 0) {
MMDB_entry_data_list_s *entry_data_list_to = previous->next =
new_entry_data_list();
if (NULL == entry_data_list_to) {
MMDB_entry_data_list_s *entry_data_list_to =
data_pool_alloc(pool);
if (!entry_data_list_to) {
return MMDB_OUT_OF_MEMORY_ERROR;
}
int status =
get_entry_data_list(mmdb, array_offset, entry_data_list_to,
depth);
pool, depth);
if (MMDB_SUCCESS != status) {
DEBUG_MSG("get_entry_data_list on array element failed.");
return status;
}
array_offset = entry_data_list_to->entry_data.offset_to_next;
while (previous->next) {
previous = previous->next;
}
}
entry_data_list->entry_data.offset_to_next = array_offset;
@ -1715,45 +1776,33 @@ LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
uint32_t size = entry_data_list->entry_data.data_size;
offset = entry_data_list->entry_data.offset_to_next;
MMDB_entry_data_list_s *previous = entry_data_list;
while (size-- > 0) {
MMDB_entry_data_list_s *entry_data_list_to = previous->next =
new_entry_data_list();
if (NULL == entry_data_list_to) {
MMDB_entry_data_list_s *list_key = data_pool_alloc(pool);
if (!list_key) {
return MMDB_OUT_OF_MEMORY_ERROR;
}
int status =
get_entry_data_list(mmdb, offset, entry_data_list_to,
depth);
get_entry_data_list(mmdb, offset, list_key, pool, depth);
if (MMDB_SUCCESS != status) {
DEBUG_MSG("get_entry_data_list on map key failed.");
return status;
}
while (previous->next) {
previous = previous->next;
}
offset = list_key->entry_data.offset_to_next;
offset = entry_data_list_to->entry_data.offset_to_next;
entry_data_list_to = previous->next =
new_entry_data_list();
if (NULL == entry_data_list_to) {
MMDB_entry_data_list_s *list_value = data_pool_alloc(pool);
if (!list_value) {
return MMDB_OUT_OF_MEMORY_ERROR;
}
status = get_entry_data_list(mmdb, offset, entry_data_list_to,
status = get_entry_data_list(mmdb, offset, list_value, pool,
depth);
if (MMDB_SUCCESS != status) {
DEBUG_MSG("get_entry_data_list on map element failed.");
return status;
}
while (previous->next) {
previous = previous->next;
}
offset = entry_data_list_to->entry_data.offset_to_next;
offset = list_value->entry_data.offset_to_next;
}
entry_data_list->entry_data.offset_to_next = offset;
}
@ -1832,22 +1881,12 @@ LOCAL int32_t get_sintX(const uint8_t *p, int length)
return (int32_t)get_uintX(p, length);
}
LOCAL MMDB_entry_data_list_s *new_entry_data_list(void)
{
/* We need calloc here in order to ensure that the ->next pointer in the
* struct doesn't point to some random address. */
return calloc(1, sizeof(MMDB_entry_data_list_s));
}
void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list)
{
if (entry_data_list == NULL) {
return;
}
if (entry_data_list->next) {
MMDB_free_entry_data_list(entry_data_list->next);
}
free(entry_data_list);
data_pool_destroy(entry_data_list->pool);
}
void MMDB_close(MMDB_s *const mmdb)
@ -1885,7 +1924,7 @@ LOCAL void free_mmdb_struct(MMDB_s *const mmdb)
LOCAL void free_languages_metadata(MMDB_s *mmdb)
{
if (!mmdb->metadata.languages.count) {
if (!mmdb->metadata.languages.names) {
return;
}

View File

@ -5,8 +5,16 @@ extern "C" {
#ifndef MAXMINDDB_H
#define MAXMINDDB_H
/* Request POSIX.1-2008. However, we want to remain compatible with
* POSIX.1-2001 (since we have been historically and see no reason to drop
* compatibility). By requesting POSIX.1-2008, we can conditionally use
* features provided by that standard if the implementation provides it. We can
* check for what the implementation provides by checking the _POSIX_VERSION
* macro after including unistd.h. If a feature is in POSIX.1-2008 but not
* POSIX.1-2001, check that macro before using the feature (or check for the
* feature directly if possible). */
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#define _POSIX_C_SOURCE 200809L
#endif
#include "maxminddb_config.h"
@ -20,7 +28,7 @@ extern "C" {
#include <winsock2.h>
#include <ws2tcpip.h>
/* libmaxminddb package version from configure */
#define PACKAGE_VERSION "1.2.1"
#define PACKAGE_VERSION "1.3.2"
typedef ADDRESS_FAMILY sa_family_t;
@ -87,7 +95,7 @@ typedef unsigned __int128 mmdb_uint128_t;
/* This is a pointer into the data section for a given IP address lookup */
typedef struct MMDB_entry_s {
struct MMDB_s *mmdb;
const struct MMDB_s *mmdb;
uint32_t offset;
} MMDB_entry_s;
@ -135,6 +143,7 @@ typedef struct MMDB_entry_data_s {
typedef struct MMDB_entry_data_list_s {
MMDB_entry_data_s entry_data;
struct MMDB_entry_data_list_s *next;
void *pool;
} MMDB_entry_data_list_s;
typedef struct MMDB_description_s {
@ -189,41 +198,40 @@ typedef struct MMDB_search_node_s {
MMDB_entry_s right_record_entry;
} MMDB_search_node_s;
/* *INDENT-OFF* */
/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
extern int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb);
extern MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
extern int MMDB_open(const char *const filename, uint32_t flags,
MMDB_s *const mmdb);
extern MMDB_lookup_result_s MMDB_lookup_string(const MMDB_s *const mmdb,
const char *const ipstr,
int *const gai_error,
int *const mmdb_error);
extern MMDB_lookup_result_s MMDB_lookup_sockaddr(
MMDB_s *const mmdb,
extern MMDB_lookup_result_s MMDB_lookup_sockaddr(
const MMDB_s *const mmdb,
const struct sockaddr *const sockaddr,
int *const mmdb_error);
extern int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
extern int MMDB_read_node(const MMDB_s *const mmdb,
uint32_t node_number,
MMDB_search_node_s *const node);
extern int MMDB_get_value(MMDB_entry_s *const start,
extern int MMDB_get_value(MMDB_entry_s *const start,
MMDB_entry_data_s *const entry_data,
...);
extern int MMDB_vget_value(MMDB_entry_s *const start,
extern int MMDB_vget_value(MMDB_entry_s *const start,
MMDB_entry_data_s *const entry_data,
va_list va_path);
extern int MMDB_aget_value(MMDB_entry_s *const start,
extern int MMDB_aget_value(MMDB_entry_s *const start,
MMDB_entry_data_s *const entry_data,
const char *const *const path);
extern int MMDB_get_metadata_as_entry_data_list(
MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list);
extern int MMDB_get_entry_data_list(
extern int MMDB_get_metadata_as_entry_data_list(
const MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list);
extern int MMDB_get_entry_data_list(
MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list);
extern void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list);
extern void MMDB_close(MMDB_s *const mmdb);
extern const char *MMDB_lib_version(void);
extern int MMDB_dump_entry_data_list(FILE *const stream,
extern void MMDB_free_entry_data_list(
MMDB_entry_data_list_s *const entry_data_list);
extern void MMDB_close(MMDB_s *const mmdb);
extern const char *MMDB_lib_version(void);
extern int MMDB_dump_entry_data_list(FILE *const stream,
MMDB_entry_data_list_s *const entry_data_list,
int indent);
extern const char *MMDB_strerror(int error_code);
/* --prototypes end - don't remove this comment-- */
/* *INDENT-ON* */
extern const char *MMDB_strerror(int error_code);
#endif /* MAXMINDDB_H */