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:
parent
33ed902a72
commit
8769051980
@ -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>
|
||||
|
14
config/common/maxminddb_config.h
Normal file
14
config/common/maxminddb_config.h
Normal 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 */
|
@ -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 */
|
@ -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
180
external/MaxmindDB/data-pool.c
vendored
Normal 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
52
external/MaxmindDB/data-pool.h
vendored
Normal 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
|
233
external/MaxmindDB/maxminddb.c
vendored
233
external/MaxmindDB/maxminddb.c
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user