Merge pull request #269 from Arkshine/update-libmaxminddb

Update libmaxminddb to v1.1.0
This commit is contained in:
Vincent Herbet 2015-07-22 12:57:46 +02:00
commit 57037740fd
2 changed files with 127 additions and 85 deletions

View File

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

View File

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