From e1ce21962e783c19977cb79c581b083c033e2e09 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 20 Mar 2020 21:29:08 +0200 Subject: [PATCH] Update libmaxminddb library to version 1.4.2. --- config/common/maxminddb_config.h | 6 +- config/gcc32/maxminddb_config.h | 6 +- config/gcc64/maxminddb_config.h | 6 +- external/MaxmindDB/maxminddb.c | 106 ++++++++----------------------- include/maxminddb.h | 17 ++++- 5 files changed, 50 insertions(+), 91 deletions(-) diff --git a/config/common/maxminddb_config.h b/config/common/maxminddb_config.h index 6d69ad47..70d5dfde 100644 --- a/config/common/maxminddb_config.h +++ b/config/common/maxminddb_config.h @@ -31,7 +31,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.3.2" +#define PACKAGE_STRING "libmaxminddb 1.4.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -40,12 +40,12 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.3.2" +#define PACKAGE_VERSION "1.4.2" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.3.2" +#define VERSION "1.4.2" #endif /* MAXMINDDB_CONFIG_H */ diff --git a/config/gcc32/maxminddb_config.h b/config/gcc32/maxminddb_config.h index 62d2cb38..f8505b72 100644 --- a/config/gcc32/maxminddb_config.h +++ b/config/gcc32/maxminddb_config.h @@ -112,7 +112,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.1" +#define PACKAGE_STRING "libmaxminddb 1.4.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -121,13 +121,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.1" +#define PACKAGE_VERSION "1.4.2" /* 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 VERSION "1.4.2" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/config/gcc64/maxminddb_config.h b/config/gcc64/maxminddb_config.h index fd76481b..b5498aba 100644 --- a/config/gcc64/maxminddb_config.h +++ b/config/gcc64/maxminddb_config.h @@ -112,7 +112,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.1" +#define PACKAGE_STRING "libmaxminddb 1.4.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -121,13 +121,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.1" +#define PACKAGE_VERSION "1.4.2" /* 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 VERSION "1.4.2" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/external/MaxmindDB/maxminddb.c b/external/MaxmindDB/maxminddb.c index 93ab4f7c..78a3c66d 100644 --- a/external/MaxmindDB/maxminddb.c +++ b/external/MaxmindDB/maxminddb.c @@ -157,9 +157,6 @@ LOCAL int find_address_in_search_tree(const MMDB_s *const mmdb, MMDB_lookup_result_s *result); 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(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); @@ -929,76 +926,48 @@ LOCAL int find_address_in_search_tree(const MMDB_s *const mmdb, return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR; } - DEBUG_NL; - DEBUG_MSG("Looking for address in search tree"); - uint32_t value = 0; - uint16_t max_depth0 = mmdb->depth - 1; - uint16_t start_bit = max_depth0; - + uint16_t current_bit = 0; if (mmdb->metadata.ip_version == 6 && address_family == AF_INET) { - /* 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); - - uint8_t type = maybe_populate_result(mmdb, - mmdb->ipv4_start_node.node_value, - mmdb->ipv4_start_node.netmask, - result); - if (MMDB_RECORD_TYPE_INVALID == type) { - return MMDB_CORRUPT_SEARCH_TREE_ERROR; - } - - /* We have an IPv6 database with no IPv4 data */ - if (MMDB_RECORD_TYPE_SEARCH_NODE != type) { - return MMDB_SUCCESS; - } - value = mmdb->ipv4_start_node.node_value; - start_bit -= mmdb->ipv4_start_node.netmask; + current_bit = mmdb->ipv4_start_node.netmask; } + uint32_t node_count = mmdb->metadata.node_count; const uint8_t *search_tree = mmdb->file_content; const uint8_t *record_pointer; - for (int current_bit = start_bit; current_bit >= 0; current_bit--) { - uint8_t bit_is_true = - address[(max_depth0 - current_bit) >> 3] - & (1U << (~(max_depth0 - current_bit) & 7)) ? 1 : 0; - - DEBUG_MSGF("Looking at bit %i - bit's value is %i", current_bit, - bit_is_true); - DEBUG_MSGF(" current node = %u", value); + for (; current_bit < mmdb->depth && value < node_count; current_bit++) { + uint8_t bit = 1U & + (address[current_bit >> 3] >> (7 - (current_bit % 8))); record_pointer = &search_tree[value * record_info.record_length]; if (record_pointer + record_info.record_length > mmdb->data_section) { return MMDB_CORRUPT_SEARCH_TREE_ERROR; } - if (bit_is_true) { + if (bit) { record_pointer += record_info.right_record_offset; value = record_info.right_record_getter(record_pointer); } else { value = record_info.left_record_getter(record_pointer); } - - uint8_t type = maybe_populate_result(mmdb, value, (uint16_t)current_bit, - result); - if (MMDB_RECORD_TYPE_INVALID == type) { - return MMDB_CORRUPT_SEARCH_TREE_ERROR; - } - - if (MMDB_RECORD_TYPE_SEARCH_NODE != type) { - return MMDB_SUCCESS; - } - - DEBUG_MSGF(" proceeding to search tree node %i", value); } - DEBUG_MSG( - "Reached the end of the address bits without leaving the search tree"); + result->netmask = current_bit; - // We should not be able to reach this return. If we do, something very bad happened. - return MMDB_CORRUPT_SEARCH_TREE_ERROR; + if (value >= node_count + mmdb->data_section_size) { + // The pointer points off the end of the database. + return MMDB_CORRUPT_SEARCH_TREE_ERROR; + } + + if (value == node_count) { + // record is empty + result->found_entry = false; + return MMDB_SUCCESS; + } + result->found_entry = true; + result->entry.offset = data_section_offset_for_record(mmdb, value); + + return MMDB_SUCCESS; } LOCAL record_info_s record_info_for_database(const MMDB_s *const mmdb) @@ -1042,17 +1011,14 @@ LOCAL int find_ipv4_start_node(MMDB_s *const mmdb) uint32_t node_value = 0; const uint8_t *record_pointer; uint16_t netmask; - for (netmask = 0; netmask < 96; netmask++) { + uint32_t node_count = mmdb->metadata.node_count; + + for (netmask = 0; netmask < 96 && node_value < node_count; netmask++) { record_pointer = &search_tree[node_value * record_info.record_length]; if (record_pointer + record_info.record_length > mmdb->data_section) { return MMDB_CORRUPT_SEARCH_TREE_ERROR; } node_value = record_info.left_record_getter(record_pointer); - /* This can happen if there's no IPv4 data _or_ if there is a subnet - * with data that contains the entire IPv4 range (like ::/64) */ - if (node_value >= mmdb->metadata.node_count) { - break; - } } mmdb->ipv4_start_node.node_value = node_value; @@ -1061,28 +1027,6 @@ LOCAL int find_ipv4_start_node(MMDB_s *const mmdb) return MMDB_SUCCESS; } -LOCAL uint8_t maybe_populate_result(const MMDB_s *const mmdb, uint32_t record, - uint16_t netmask, - MMDB_lookup_result_s *result) -{ - uint8_t type = record_type(mmdb, record); - - if (MMDB_RECORD_TYPE_SEARCH_NODE == type || - MMDB_RECORD_TYPE_INVALID == type) { - return type; - } - - result->netmask = mmdb->depth - netmask; - - result->entry.offset = data_section_offset_for_record(mmdb, record); - - // type is either MMDB_RECORD_TYPE_DATA or MMDB_RECORD_TYPE_EMPTY - // at this point - result->found_entry = MMDB_RECORD_TYPE_DATA == type; - - return type; -} - LOCAL uint8_t record_type(const MMDB_s *const mmdb, uint64_t record) { uint32_t node_count = mmdb->metadata.node_count; diff --git a/include/maxminddb.h b/include/maxminddb.h index 6e6c615c..f4b9bd24 100644 --- a/include/maxminddb.h +++ b/include/maxminddb.h @@ -28,7 +28,7 @@ extern "C" { #include #include /* libmaxminddb package version from configure */ -#define PACKAGE_VERSION "1.3.2" +#define PACKAGE_VERSION "1.4.2" typedef ADDRESS_FAMILY sa_family_t; @@ -151,6 +151,10 @@ typedef struct MMDB_description_s { const char *description; } MMDB_description_s; +/* WARNING: do not add new fields to this struct without bumping the SONAME. + * The struct is allocated by the users of this library and increasing the + * size will cause existing users to allocate too little space when the shared + * library is upgraded */ typedef struct MMDB_metadata_s { uint32_t node_count; uint16_t record_size; @@ -167,13 +171,23 @@ typedef struct MMDB_metadata_s { size_t count; MMDB_description_s **descriptions; } description; + /* See above warning before adding fields */ } MMDB_metadata_s; +/* WARNING: do not add new fields to this struct without bumping the SONAME. + * The struct is allocated by the users of this library and increasing the + * size will cause existing users to allocate too little space when the shared + * library is upgraded */ typedef struct MMDB_ipv4_start_node_s { uint16_t netmask; uint32_t node_value; + /* See above warning before adding fields */ } MMDB_ipv4_start_node_s; +/* WARNING: do not add new fields to this struct without bumping the SONAME. + * The struct is allocated by the users of this library and increasing the + * size will cause existing users to allocate too little space when the shared + * library is upgraded */ typedef struct MMDB_s { uint32_t flags; const char *filename; @@ -187,6 +201,7 @@ typedef struct MMDB_s { uint16_t depth; MMDB_ipv4_start_node_s ipv4_start_node; MMDB_metadata_s metadata; + /* See above warning before adding fields */ } MMDB_s; typedef struct MMDB_search_node_s {