Update libmaxminddb to v1.1.0
This commit is contained in:
parent
2162059352
commit
8efa1ba067
210
third_party/libmaxminddb/maxminddb.c
vendored
210
third_party/libmaxminddb/maxminddb.c
vendored
|
@ -3,6 +3,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "maxminddb.h"
|
#include "maxminddb.h"
|
||||||
#include "maxminddb-compat-util.h"
|
#include "maxminddb-compat-util.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MMDB_DATA_SECTION_SEPARATOR (16)
|
#define MMDB_DATA_SECTION_SEPARATOR (16)
|
||||||
|
|
||||||
#ifdef MMDB_DEBUG
|
#ifdef MMDB_DEBUG
|
||||||
|
@ -118,6 +118,7 @@ typedef struct record_info_s {
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
|
/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
|
||||||
|
LOCAL int map_file(MMDB_s *const mmdb);
|
||||||
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
||||||
ssize_t file_size, uint32_t *metadata_size);
|
ssize_t file_size, uint32_t *metadata_size);
|
||||||
LOCAL int read_metadata(MMDB_s *mmdb);
|
LOCAL int read_metadata(MMDB_s *mmdb);
|
||||||
|
@ -194,6 +195,8 @@ LOCAL char *bytes_to_hex(uint8_t *bytes, uint32_t size);
|
||||||
|
|
||||||
int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
|
int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
|
||||||
{
|
{
|
||||||
|
int status = MMDB_SUCCESS;
|
||||||
|
|
||||||
mmdb->file_content = NULL;
|
mmdb->file_content = NULL;
|
||||||
mmdb->data_section = NULL;
|
mmdb->data_section = NULL;
|
||||||
mmdb->metadata.database_type = NULL;
|
mmdb->metadata.database_type = NULL;
|
||||||
|
@ -202,85 +205,17 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
|
||||||
|
|
||||||
mmdb->filename = mmdb_strdup(filename);
|
mmdb->filename = mmdb_strdup(filename);
|
||||||
if (NULL == mmdb->filename) {
|
if (NULL == mmdb->filename) {
|
||||||
free_mmdb_struct(mmdb);
|
status = MMDB_OUT_OF_MEMORY_ERROR;
|
||||||
return MMDB_OUT_OF_MEMORY_ERROR;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t size;
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE fd = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (fd == INVALID_HANDLE_VALUE) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_FILE_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
size = GetFileSize(fd, NULL);
|
|
||||||
if (size == INVALID_FILE_SIZE) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
CloseHandle(fd);
|
|
||||||
return MMDB_FILE_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int fd = open(filename, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_FILE_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat s;
|
|
||||||
if (fstat(fd, &s) ) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
close(fd);
|
|
||||||
return MMDB_FILE_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
size = s.st_size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((flags & MMDB_MODE_MASK) == 0) {
|
if ((flags & MMDB_MODE_MASK) == 0) {
|
||||||
flags |= MMDB_MODE_MMAP;
|
flags |= MMDB_MODE_MMAP;
|
||||||
}
|
}
|
||||||
mmdb->flags = flags;
|
mmdb->flags = flags;
|
||||||
mmdb->file_size = size;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
if (MMDB_SUCCESS != (status = map_file(mmdb)) ) {
|
||||||
HANDLE mmh = CreateFileMappingA(fd, NULL, PAGE_READONLY, 0, size, NULL);
|
goto cleanup;
|
||||||
uint8_t *file_content =
|
|
||||||
(uint8_t *)MapViewOfFile(mmh, FILE_MAP_READ, 0, 0, 0);
|
|
||||||
CloseHandle(fd);
|
|
||||||
if (file_content == NULL) {
|
|
||||||
CloseHandle(mmh);
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_IO_ERROR;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uint8_t *file_content =
|
|
||||||
(uint8_t *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
close(fd);
|
|
||||||
if (MAP_FAILED == file_content) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_IO_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t metadata_size = 0;
|
|
||||||
const uint8_t *metadata = find_metadata(file_content, size, &metadata_size);
|
|
||||||
if (NULL == metadata) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_INVALID_METADATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmdb->metadata_section = metadata;
|
|
||||||
mmdb->metadata_section_size = metadata_size;
|
|
||||||
|
|
||||||
int status = read_metadata(mmdb);
|
|
||||||
if (MMDB_SUCCESS != status) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mmdb->metadata.binary_format_major_version != 2) {
|
|
||||||
free_mmdb_struct(mmdb);
|
|
||||||
return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -288,17 +223,117 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb)
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsa);
|
WSAStartup(MAKEWORD(2, 2), &wsa);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint32_t metadata_size = 0;
|
||||||
|
const uint8_t *metadata = find_metadata(mmdb->file_content, mmdb->file_size,
|
||||||
|
&metadata_size);
|
||||||
|
if (NULL == metadata) {
|
||||||
|
status = MMDB_INVALID_METADATA_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
mmdb->metadata_section = metadata;
|
||||||
|
mmdb->metadata_section_size = metadata_size;
|
||||||
|
|
||||||
|
status = read_metadata(mmdb);
|
||||||
|
if (MMDB_SUCCESS != status) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmdb->metadata.binary_format_major_version != 2) {
|
||||||
|
status = MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t search_tree_size = mmdb->metadata.node_count *
|
uint32_t search_tree_size = mmdb->metadata.node_count *
|
||||||
mmdb->full_record_byte_size;
|
mmdb->full_record_byte_size;
|
||||||
|
|
||||||
mmdb->file_content = file_content;
|
mmdb->data_section = mmdb->file_content + search_tree_size;
|
||||||
mmdb->data_section = file_content + search_tree_size;
|
|
||||||
mmdb->data_section_size = mmdb->file_size - search_tree_size;
|
mmdb->data_section_size = mmdb->file_size - search_tree_size;
|
||||||
mmdb->metadata_section = metadata;
|
mmdb->metadata_section = metadata;
|
||||||
mmdb->ipv4_start_node.node_value = 0;
|
mmdb->ipv4_start_node.node_value = 0;
|
||||||
mmdb->ipv4_start_node.netmask = 0;
|
mmdb->ipv4_start_node.netmask = 0;
|
||||||
|
|
||||||
return MMDB_SUCCESS;
|
cleanup:
|
||||||
|
if (MMDB_SUCCESS != status) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
free_mmdb_struct(mmdb);
|
||||||
|
errno = saved_errno;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCAL int map_file(MMDB_s *const mmdb)
|
||||||
|
{
|
||||||
|
ssize_t size;
|
||||||
|
int status = MMDB_SUCCESS;
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE fd = INVALID_HANDLE_VALUE;
|
||||||
|
HANDLE mmh = NULL;
|
||||||
|
|
||||||
|
fd = CreateFileA(mmdb->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (fd == INVALID_HANDLE_VALUE) {
|
||||||
|
status = MMDB_FILE_OPEN_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
size = GetFileSize(fd, NULL);
|
||||||
|
if (size == INVALID_FILE_SIZE) {
|
||||||
|
status = MMDB_FILE_OPEN_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
mmh = CreateFileMappingA(fd, NULL, PAGE_READONLY, 0, size, NULL);
|
||||||
|
if (NULL == mmh) { /* Microsoft documentation for CreateFileMapping indicates this returns NULL not INVALID_HANDLE_VALUE on error */
|
||||||
|
status = MMDB_IO_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
uint8_t *file_content =
|
||||||
|
(uint8_t *)MapViewOfFile(mmh, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if (file_content == NULL) {
|
||||||
|
status = MMDB_IO_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int fd = open(mmdb->filename, O_RDONLY);
|
||||||
|
struct stat s;
|
||||||
|
if (fd < 0 || fstat(fd, &s)) {
|
||||||
|
status = MMDB_FILE_OPEN_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = s.st_size;
|
||||||
|
|
||||||
|
uint8_t *file_content =
|
||||||
|
(uint8_t *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (MAP_FAILED == file_content) {
|
||||||
|
if (ENOMEM == errno) {
|
||||||
|
status = MMDB_OUT_OF_MEMORY_ERROR;
|
||||||
|
} else {
|
||||||
|
status = MMDB_IO_ERROR;
|
||||||
|
}
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mmdb->file_size = size;
|
||||||
|
mmdb->file_content = file_content;
|
||||||
|
|
||||||
|
cleanup:;
|
||||||
|
int saved_errno = errno;
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (INVALID_HANDLE_VALUE != fd) {
|
||||||
|
CloseHandle(fd);
|
||||||
|
}
|
||||||
|
if (NULL != mmh) {
|
||||||
|
CloseHandle(mmh);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
errno = saved_errno;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
||||||
|
@ -309,7 +344,7 @@ LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
||||||
file_size;
|
file_size;
|
||||||
|
|
||||||
uint8_t *search_area = (uint8_t *)(file_content + (file_size - max_size));
|
uint8_t *search_area = (uint8_t *)(file_content + (file_size - max_size));
|
||||||
uint8_t *tmp = search_area;
|
uint8_t *tmp;
|
||||||
do {
|
do {
|
||||||
tmp = mmdb_memmem(search_area, max_size,
|
tmp = mmdb_memmem(search_area, max_size,
|
||||||
METADATA_MARKER, strlen(METADATA_MARKER));
|
METADATA_MARKER, strlen(METADATA_MARKER));
|
||||||
|
@ -535,6 +570,11 @@ LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
|
||||||
|
|
||||||
uint32_t map_size = member->entry_data.data_size;
|
uint32_t map_size = member->entry_data.data_size;
|
||||||
mmdb->metadata.description.count = 0;
|
mmdb->metadata.description.count = 0;
|
||||||
|
if (0 == map_size) {
|
||||||
|
mmdb->metadata.description.descriptions = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
mmdb->metadata.description.descriptions =
|
mmdb->metadata.description.descriptions =
|
||||||
malloc(map_size * sizeof(MMDB_description_s *));
|
malloc(map_size * sizeof(MMDB_description_s *));
|
||||||
if (NULL == mmdb->metadata.description.descriptions) {
|
if (NULL == mmdb->metadata.description.descriptions) {
|
||||||
|
@ -581,6 +621,7 @@ LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
MMDB_free_entry_data_list(first_member);
|
MMDB_free_entry_data_list(first_member);
|
||||||
|
|
||||||
return MMDB_SUCCESS;
|
return MMDB_SUCCESS;
|
||||||
|
@ -604,23 +645,22 @@ MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
|
||||||
*gai_error = resolve_any_address(ipstr, &addresses);
|
*gai_error = resolve_any_address(ipstr, &addresses);
|
||||||
|
|
||||||
if (*gai_error) {
|
if (*gai_error) {
|
||||||
if (NULL != addresses) {
|
goto cleanup;
|
||||||
freeaddrinfo(addresses);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mmdb->metadata.ip_version == 4
|
if (mmdb->metadata.ip_version == 4
|
||||||
&& addresses->ai_addr->sa_family == AF_INET6) {
|
&& addresses->ai_addr->sa_family == AF_INET6) {
|
||||||
|
|
||||||
*mmdb_error = MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR;
|
*mmdb_error = MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR;
|
||||||
freeaddrinfo(addresses);
|
goto cleanup;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, mmdb_error);
|
result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, mmdb_error);
|
||||||
|
|
||||||
freeaddrinfo(addresses);
|
cleanup:
|
||||||
|
if (NULL != addresses) {
|
||||||
|
freeaddrinfo(addresses);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -783,6 +823,8 @@ LOCAL record_info_s record_info_for_database(MMDB_s *mmdb)
|
||||||
record_info.left_record_getter = &get_uint32;
|
record_info.left_record_getter = &get_uint32;
|
||||||
record_info.right_record_getter = &get_uint32;
|
record_info.right_record_getter = &get_uint32;
|
||||||
record_info.right_record_offset = 4;
|
record_info.right_record_offset = 4;
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return record_info;
|
return record_info;
|
||||||
|
|
2
third_party/libmaxminddb/maxminddb.h
vendored
2
third_party/libmaxminddb/maxminddb.h
vendored
|
@ -36,7 +36,7 @@ typedef ADDRESS_FAMILY sa_family_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* libmaxminddb package version from configure */
|
/* libmaxminddb package version from configure */
|
||||||
#define PACKAGE_VERSION "1.0.4"
|
#define PACKAGE_VERSION "1.1.0"
|
||||||
|
|
||||||
#define MMDB_DATA_TYPE_EXTENDED (0)
|
#define MMDB_DATA_TYPE_EXTENDED (0)
|
||||||
#define MMDB_DATA_TYPE_POINTER (1)
|
#define MMDB_DATA_TYPE_POINTER (1)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user