Update libmaxminddb to v1.1.0

This commit is contained in:
Arkshine 2015-07-22 00:15:32 +02:00
parent 2162059352
commit 8efa1ba067
2 changed files with 127 additions and 85 deletions

View File

@ -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);
cleanup:
if (NULL != addresses) {
freeaddrinfo(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;

View File

@ -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)