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
|
||||
#include "maxminddb.h"
|
||||
#include "maxminddb-compat-util.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
@ -19,7 +20,6 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define MMDB_DATA_SECTION_SEPARATOR (16)
|
||||
|
||||
#ifdef MMDB_DEBUG
|
||||
|
@ -118,6 +118,7 @@ typedef struct record_info_s {
|
|||
|
||||
/* *INDENT-OFF* */
|
||||
/* --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,
|
||||
ssize_t file_size, uint32_t *metadata_size);
|
||||
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 status = MMDB_SUCCESS;
|
||||
|
||||
mmdb->file_content = NULL;
|
||||
mmdb->data_section = 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);
|
||||
if (NULL == mmdb->filename) {
|
||||
free_mmdb_struct(mmdb);
|
||||
return MMDB_OUT_OF_MEMORY_ERROR;
|
||||
status = 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) {
|
||||
flags |= MMDB_MODE_MMAP;
|
||||
}
|
||||
mmdb->flags = flags;
|
||||
mmdb->file_size = size;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE mmh = CreateFileMappingA(fd, NULL, PAGE_READONLY, 0, size, NULL);
|
||||
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;
|
||||
if (MMDB_SUCCESS != (status = map_file(mmdb)) ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#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);
|
||||
#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 *
|
||||
mmdb->full_record_byte_size;
|
||||
|
||||
mmdb->file_content = file_content;
|
||||
mmdb->data_section = file_content + search_tree_size;
|
||||
mmdb->data_section = mmdb->file_content + search_tree_size;
|
||||
mmdb->data_section_size = mmdb->file_size - search_tree_size;
|
||||
mmdb->metadata_section = metadata;
|
||||
mmdb->ipv4_start_node.node_value = 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,
|
||||
|
@ -309,7 +344,7 @@ LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
|
|||
file_size;
|
||||
|
||||
uint8_t *search_area = (uint8_t *)(file_content + (file_size - max_size));
|
||||
uint8_t *tmp = search_area;
|
||||
uint8_t *tmp;
|
||||
do {
|
||||
tmp = mmdb_memmem(search_area, max_size,
|
||||
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;
|
||||
mmdb->metadata.description.count = 0;
|
||||
if (0 == map_size) {
|
||||
mmdb->metadata.description.descriptions = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mmdb->metadata.description.descriptions =
|
||||
malloc(map_size * sizeof(MMDB_description_s *));
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if (*gai_error) {
|
||||
if (NULL != addresses) {
|
||||
freeaddrinfo(addresses);
|
||||
}
|
||||
return result;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (mmdb->metadata.ip_version == 4
|
||||
&& addresses->ai_addr->sa_family == AF_INET6) {
|
||||
|
||||
*mmdb_error = MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR;
|
||||
freeaddrinfo(addresses);
|
||||
return result;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, mmdb_error);
|
||||
|
||||
freeaddrinfo(addresses);
|
||||
cleanup:
|
||||
if (NULL != addresses) {
|
||||
freeaddrinfo(addresses);
|
||||
}
|
||||
|
||||
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.right_record_getter = &get_uint32;
|
||||
record_info.right_record_offset = 4;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/* 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_POINTER (1)
|
||||
|
|
Loading…
Reference in New Issue
Block a user