mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-06-16 15:17:13 +02:00
Update MaxmindDB to current git.
This commit is contained in:
406
vendor/MaxmindDB/bin/mmdblookup.c
vendored
406
vendor/MaxmindDB/bin/mmdblookup.c
vendored
@ -23,46 +23,42 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define LOCAL static
|
||||
|
||||
LOCAL void usage(char *program, int exit_code, const char *error);
|
||||
LOCAL const char **get_options(
|
||||
int argc,
|
||||
char **argv,
|
||||
char **mmdb_file,
|
||||
char **ip_address,
|
||||
int *verbose,
|
||||
int *iterations,
|
||||
int *lookup_path_length,
|
||||
int *const thread_count,
|
||||
char **const ip_file);
|
||||
LOCAL MMDB_s open_or_die(const char *fname);
|
||||
LOCAL void dump_meta(MMDB_s *mmdb);
|
||||
LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
char const *const ip_file,
|
||||
bool const dump);
|
||||
LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
|
||||
const char **lookup_path,
|
||||
int lookup_path_length,
|
||||
bool verbose);
|
||||
LOCAL int benchmark(MMDB_s *mmdb, int iterations);
|
||||
LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr);
|
||||
LOCAL void random_ipv4(char *ip);
|
||||
static void usage(char *program, int exit_code, const char *error);
|
||||
static const char **get_options(int argc,
|
||||
char **argv,
|
||||
char **mmdb_file,
|
||||
char **ip_address,
|
||||
int *verbose,
|
||||
int *iterations,
|
||||
int *lookup_path_length,
|
||||
int *const thread_count,
|
||||
char **const ip_file);
|
||||
static MMDB_s open_or_die(const char *fname);
|
||||
static void dump_meta(MMDB_s *mmdb);
|
||||
static bool lookup_from_file(MMDB_s *const mmdb,
|
||||
char const *const ip_file,
|
||||
bool const dump);
|
||||
static int lookup_and_print(MMDB_s *mmdb,
|
||||
const char *ip_address,
|
||||
const char **lookup_path,
|
||||
int lookup_path_length,
|
||||
bool verbose);
|
||||
static int benchmark(MMDB_s *mmdb, int iterations);
|
||||
static MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr);
|
||||
static void random_ipv4(char *ip);
|
||||
|
||||
#ifndef _WIN32
|
||||
// These aren't with the automatically generated prototypes as we'd lose the
|
||||
// enclosing macros.
|
||||
static bool start_threaded_benchmark(
|
||||
MMDB_s *const mmdb,
|
||||
int const thread_count,
|
||||
int const iterations);
|
||||
static bool start_threaded_benchmark(MMDB_s *const mmdb,
|
||||
int const thread_count,
|
||||
int const iterations);
|
||||
static long double get_time(void);
|
||||
static void *thread(void *arg);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
int wmain(int argc, wchar_t **wargv)
|
||||
{
|
||||
int wmain(int argc, wchar_t **wargv) {
|
||||
// Convert our argument list from UTF-16 to UTF-8.
|
||||
char **argv = (char **)calloc(argc, sizeof(char *));
|
||||
if (!argv) {
|
||||
@ -72,11 +68,11 @@ int wmain(int argc, wchar_t **wargv)
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int utf8_width;
|
||||
char *utf8_string;
|
||||
utf8_width = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0,
|
||||
NULL, NULL);
|
||||
utf8_width =
|
||||
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL);
|
||||
if (utf8_width < 1) {
|
||||
fprintf(stderr, "WideCharToMultiByte() failed: %d\n",
|
||||
GetLastError());
|
||||
fprintf(
|
||||
stderr, "WideCharToMultiByte() failed: %d\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
utf8_string = calloc(utf8_width, sizeof(char));
|
||||
@ -84,17 +80,17 @@ int wmain(int argc, wchar_t **wargv)
|
||||
fprintf(stderr, "calloc(): %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, utf8_string,
|
||||
utf8_width, NULL, NULL) < 1) {
|
||||
fprintf(stderr, "WideCharToMultiByte() failed: %d\n",
|
||||
GetLastError());
|
||||
if (WideCharToMultiByte(
|
||||
CP_UTF8, 0, wargv[i], -1, utf8_string, utf8_width, NULL, NULL) <
|
||||
1) {
|
||||
fprintf(
|
||||
stderr, "WideCharToMultiByte() failed: %d\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
argv[i] = utf8_string;
|
||||
}
|
||||
#else // _WIN32
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#else // _WIN32
|
||||
int main(int argc, char **argv) {
|
||||
#endif // _WIN32
|
||||
char *mmdb_file = NULL;
|
||||
char *ip_address = NULL;
|
||||
@ -104,9 +100,15 @@ int main(int argc, char **argv)
|
||||
int thread_count = 0;
|
||||
char *ip_file = NULL;
|
||||
|
||||
const char **lookup_path =
|
||||
get_options(argc, argv, &mmdb_file, &ip_address, &verbose, &iterations,
|
||||
&lookup_path_length, &thread_count, &ip_file);
|
||||
const char **lookup_path = get_options(argc,
|
||||
argv,
|
||||
&mmdb_file,
|
||||
&ip_address,
|
||||
&verbose,
|
||||
&iterations,
|
||||
&lookup_path_length,
|
||||
&thread_count,
|
||||
&ip_file);
|
||||
|
||||
MMDB_s mmdb = open_or_die(mmdb_file);
|
||||
|
||||
@ -131,13 +133,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (0 == iterations) {
|
||||
exit(lookup_and_print(&mmdb, ip_address, lookup_path,
|
||||
lookup_path_length, verbose));
|
||||
exit(lookup_and_print(
|
||||
&mmdb, ip_address, lookup_path, lookup_path_length, verbose));
|
||||
}
|
||||
|
||||
free((void *)lookup_path);
|
||||
|
||||
srand( (int)time(NULL) );
|
||||
srand((int)time(NULL));
|
||||
|
||||
#ifndef _WIN32
|
||||
if (thread_count > 0) {
|
||||
@ -153,97 +155,96 @@ int main(int argc, char **argv)
|
||||
exit(benchmark(&mmdb, iterations));
|
||||
}
|
||||
|
||||
LOCAL void usage(char *program, int exit_code, const char *error)
|
||||
{
|
||||
static void usage(char *program, int exit_code, const char *error) {
|
||||
if (NULL != error) {
|
||||
fprintf(stderr, "\n *ERROR: %s\n", error);
|
||||
}
|
||||
|
||||
char *usage = "\n"
|
||||
" %s --file /path/to/file.mmdb --ip 1.2.3.4 [path to lookup]\n"
|
||||
"\n"
|
||||
" This application accepts the following options:\n"
|
||||
"\n"
|
||||
" --file (-f) The path to the MMDB file. Required.\n"
|
||||
"\n"
|
||||
" --ip (-i) The IP address to look up. Required.\n"
|
||||
"\n"
|
||||
" --verbose (-v) Turns on verbose output. Specifically, this causes this\n"
|
||||
" application to output the database metadata.\n"
|
||||
"\n"
|
||||
" --version Print the program's version number and exit.\n"
|
||||
"\n"
|
||||
" --help (-h -?) Show usage information.\n"
|
||||
"\n"
|
||||
" If an IP's data entry resolves to a map or array, you can provide\n"
|
||||
" a lookup path to only show part of that data.\n"
|
||||
"\n"
|
||||
" For example, given a JSON structure like this:\n"
|
||||
"\n"
|
||||
" {\n"
|
||||
" \"names\": {\n"
|
||||
" \"en\": \"Germany\",\n"
|
||||
" \"de\": \"Deutschland\"\n"
|
||||
" },\n"
|
||||
" \"cities\": [ \"Berlin\", \"Frankfurt\" ]\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" You could look up just the English name by calling mmdblookup with a lookup path of:\n"
|
||||
"\n"
|
||||
" mmdblookup --file ... --ip ... names en\n"
|
||||
"\n"
|
||||
" Or you could look up the second city in the list with:\n"
|
||||
"\n"
|
||||
" mmdblookup --file ... --ip ... cities 1\n"
|
||||
"\n"
|
||||
" Array numbering begins with zero (0).\n"
|
||||
"\n"
|
||||
" If you do not provide a path to lookup, all of the information for a given IP\n"
|
||||
" will be shown.\n"
|
||||
"\n";
|
||||
char *usage =
|
||||
"\n"
|
||||
" %s --file /path/to/file.mmdb --ip 1.2.3.4 [path to lookup]\n"
|
||||
"\n"
|
||||
" This application accepts the following options:\n"
|
||||
"\n"
|
||||
" --file (-f) The path to the MMDB file. Required.\n"
|
||||
"\n"
|
||||
" --ip (-i) The IP address to look up. Required.\n"
|
||||
"\n"
|
||||
" --verbose (-v) Turns on verbose output. Specifically, this "
|
||||
"causes this\n"
|
||||
" application to output the database metadata.\n"
|
||||
"\n"
|
||||
" --version Print the program's version number and exit.\n"
|
||||
"\n"
|
||||
" --help (-h -?) Show usage information.\n"
|
||||
"\n"
|
||||
" If an IP's data entry resolves to a map or array, you can provide\n"
|
||||
" a lookup path to only show part of that data.\n"
|
||||
"\n"
|
||||
" For example, given a JSON structure like this:\n"
|
||||
"\n"
|
||||
" {\n"
|
||||
" \"names\": {\n"
|
||||
" \"en\": \"Germany\",\n"
|
||||
" \"de\": \"Deutschland\"\n"
|
||||
" },\n"
|
||||
" \"cities\": [ \"Berlin\", \"Frankfurt\" ]\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" You could look up just the English name by calling mmdblookup with "
|
||||
"a lookup path of:\n"
|
||||
"\n"
|
||||
" mmdblookup --file ... --ip ... names en\n"
|
||||
"\n"
|
||||
" Or you could look up the second city in the list with:\n"
|
||||
"\n"
|
||||
" mmdblookup --file ... --ip ... cities 1\n"
|
||||
"\n"
|
||||
" Array numbering begins with zero (0).\n"
|
||||
"\n"
|
||||
" If you do not provide a path to lookup, all of the information for "
|
||||
"a given IP\n"
|
||||
" will be shown.\n"
|
||||
"\n";
|
||||
|
||||
fprintf(stdout, usage, program);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
LOCAL const char **get_options(
|
||||
int argc,
|
||||
char **argv,
|
||||
char **mmdb_file,
|
||||
char **ip_address,
|
||||
int *verbose,
|
||||
int *iterations,
|
||||
int *lookup_path_length,
|
||||
int *const thread_count,
|
||||
char **const ip_file)
|
||||
{
|
||||
static const char **get_options(int argc,
|
||||
char **argv,
|
||||
char **mmdb_file,
|
||||
char **ip_address,
|
||||
int *verbose,
|
||||
int *iterations,
|
||||
int *lookup_path_length,
|
||||
int *const thread_count,
|
||||
char **const ip_file) {
|
||||
static int help = 0;
|
||||
static int version = 0;
|
||||
|
||||
while (1) {
|
||||
static struct option options[] = {
|
||||
{ "file", required_argument, 0, 'f' },
|
||||
{ "ip", required_argument, 0, 'i' },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ "version", no_argument, 0, 'n' },
|
||||
{ "benchmark", required_argument, 0, 'b' },
|
||||
{"file", required_argument, 0, 'f'},
|
||||
{"ip", required_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"version", no_argument, 0, 'n'},
|
||||
{"benchmark", required_argument, 0, 'b'},
|
||||
#ifndef _WIN32
|
||||
{ "threads", required_argument, 0, 't' },
|
||||
{"threads", required_argument, 0, 't'},
|
||||
#endif
|
||||
{ "ip-file", required_argument, 0, 'I' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "?", no_argument, 0, 1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
{"ip-file", required_argument, 0, 'I'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"?", no_argument, 0, 1},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
int opt_index;
|
||||
#ifdef _WIN32
|
||||
char const * const optstring = "f:i:b:I:vnh?";
|
||||
char const *const optstring = "f:i:b:I:vnh?";
|
||||
#else
|
||||
char const * const optstring = "f:i:b:t:I:vnh?";
|
||||
char const *const optstring = "f:i:b:t:I:vnh?";
|
||||
#endif
|
||||
int opt_char = getopt_long(argc, argv, optstring, options,
|
||||
&opt_index);
|
||||
int opt_char = getopt_long(argc, argv, optstring, options, &opt_index);
|
||||
|
||||
if (-1 == opt_char) {
|
||||
break;
|
||||
@ -295,6 +296,10 @@ LOCAL const char **get_options(
|
||||
|
||||
const char **lookup_path =
|
||||
calloc((argc - optind) + 1, sizeof(const char *));
|
||||
if (!lookup_path) {
|
||||
fprintf(stderr, "calloc(): %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < argc - optind; i++) {
|
||||
lookup_path[i] = argv[i + optind];
|
||||
@ -305,14 +310,13 @@ LOCAL const char **get_options(
|
||||
return lookup_path;
|
||||
}
|
||||
|
||||
LOCAL MMDB_s open_or_die(const char *fname)
|
||||
{
|
||||
static MMDB_s open_or_die(const char *fname) {
|
||||
MMDB_s mmdb;
|
||||
int status = MMDB_open(fname, MMDB_MODE_MMAP, &mmdb);
|
||||
|
||||
if (MMDB_SUCCESS != status) {
|
||||
fprintf(stderr, "\n Can't open %s - %s\n", fname,
|
||||
MMDB_strerror(status));
|
||||
fprintf(
|
||||
stderr, "\n Can't open %s - %s\n", fname, MMDB_strerror(status));
|
||||
|
||||
if (MMDB_IO_ERROR == status) {
|
||||
fprintf(stderr, " IO error: %s\n", strerror(errno));
|
||||
@ -326,8 +330,7 @@ LOCAL MMDB_s open_or_die(const char *fname)
|
||||
return mmdb;
|
||||
}
|
||||
|
||||
LOCAL void dump_meta(MMDB_s *mmdb)
|
||||
{
|
||||
static void dump_meta(MMDB_s *mmdb) {
|
||||
const char *meta_dump = "\n"
|
||||
" Database metadata\n"
|
||||
" Node count: %i\n"
|
||||
@ -342,7 +345,8 @@ LOCAL void dump_meta(MMDB_s *mmdb)
|
||||
const time_t epoch = (const time_t)mmdb->metadata.build_epoch;
|
||||
strftime(date, 40, "%F %T UTC", gmtime(&epoch));
|
||||
|
||||
fprintf(stdout, meta_dump,
|
||||
fprintf(stdout,
|
||||
meta_dump,
|
||||
mmdb->metadata.node_count,
|
||||
mmdb->metadata.record_size,
|
||||
mmdb->metadata.ip_version,
|
||||
@ -362,7 +366,8 @@ LOCAL void dump_meta(MMDB_s *mmdb)
|
||||
|
||||
fprintf(stdout, " Description:\n");
|
||||
for (size_t i = 0; i < mmdb->metadata.description.count; i++) {
|
||||
fprintf(stdout, " %s: %s\n",
|
||||
fprintf(stdout,
|
||||
" %s: %s\n",
|
||||
mmdb->metadata.description.descriptions[i]->language,
|
||||
mmdb->metadata.description.descriptions[i]->description);
|
||||
}
|
||||
@ -381,10 +386,9 @@ LOCAL void dump_meta(MMDB_s *mmdb)
|
||||
//
|
||||
// In addition to being useful for comparisons, this function provides a way to
|
||||
// have a more deterministic set of lookups for benchmarking.
|
||||
LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
char const *const ip_file,
|
||||
bool const dump)
|
||||
{
|
||||
static bool lookup_from_file(MMDB_s *const mmdb,
|
||||
char const *const ip_file,
|
||||
bool const dump) {
|
||||
FILE *const fh = fopen(ip_file, "r");
|
||||
if (!fh) {
|
||||
fprintf(stderr, "fopen(): %s: %s\n", ip_file, strerror(errno));
|
||||
@ -392,7 +396,7 @@ LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
}
|
||||
|
||||
clock_t const clock_start = clock();
|
||||
char buf[1024] = { 0 };
|
||||
char buf[1024] = {0};
|
||||
// I'd normally use uint64_t, but support for it is optional in C99.
|
||||
unsigned long long i = 0;
|
||||
while (1) {
|
||||
@ -429,10 +433,11 @@ LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
}
|
||||
|
||||
MMDB_entry_data_list_s *entry_data_list = NULL;
|
||||
int const status = MMDB_get_entry_data_list(&result.entry,
|
||||
&entry_data_list);
|
||||
int const status =
|
||||
MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
||||
if (status != MMDB_SUCCESS) {
|
||||
fprintf(stderr, "MMDB_get_entry_data_list(): %s\n",
|
||||
fprintf(stderr,
|
||||
"MMDB_get_entry_data_list(): %s\n",
|
||||
MMDB_strerror(status));
|
||||
fclose(fh);
|
||||
MMDB_free_entry_data_list(entry_data_list);
|
||||
@ -447,10 +452,11 @@ LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
|
||||
if (dump) {
|
||||
fprintf(stdout, "%s:\n", buf);
|
||||
int const status = MMDB_dump_entry_data_list(stderr,
|
||||
entry_data_list, 0);
|
||||
int const status =
|
||||
MMDB_dump_entry_data_list(stderr, entry_data_list, 0);
|
||||
if (status != MMDB_SUCCESS) {
|
||||
fprintf(stderr, "MMDB_dump_entry_data_list(): %s\n",
|
||||
fprintf(stderr,
|
||||
"MMDB_dump_entry_data_list(): %s\n",
|
||||
MMDB_strerror(status));
|
||||
fclose(fh);
|
||||
MMDB_free_entry_data_list(entry_data_list);
|
||||
@ -467,16 +473,18 @@ LOCAL bool lookup_from_file(MMDB_s *const mmdb,
|
||||
fprintf(
|
||||
stdout,
|
||||
"Looked up %llu addresses in %.2f seconds. %.2f lookups per second.\n",
|
||||
i, seconds, i / seconds);
|
||||
i,
|
||||
seconds,
|
||||
i / seconds);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
|
||||
const char **lookup_path,
|
||||
int lookup_path_length,
|
||||
bool verbose)
|
||||
{
|
||||
static int lookup_and_print(MMDB_s *mmdb,
|
||||
const char *ip_address,
|
||||
const char **lookup_path,
|
||||
int lookup_path_length,
|
||||
bool verbose) {
|
||||
|
||||
MMDB_lookup_result_s result = lookup_or_die(mmdb, ip_address);
|
||||
MMDB_entry_data_list_s *entry_data_list = NULL;
|
||||
@ -484,38 +492,32 @@ LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
|
||||
int exit_code = 0;
|
||||
|
||||
if (verbose) {
|
||||
fprintf(
|
||||
stdout,
|
||||
"\n Record prefix length: %d\n",
|
||||
result.netmask
|
||||
);
|
||||
fprintf(stdout, "\n Record prefix length: %d\n", result.netmask);
|
||||
}
|
||||
|
||||
if (result.found_entry) {
|
||||
int status;
|
||||
if (lookup_path_length) {
|
||||
MMDB_entry_data_s entry_data;
|
||||
status = MMDB_aget_value(&result.entry, &entry_data,
|
||||
lookup_path);
|
||||
status = MMDB_aget_value(&result.entry, &entry_data, lookup_path);
|
||||
if (MMDB_SUCCESS == status) {
|
||||
if (entry_data.offset) {
|
||||
MMDB_entry_s entry =
|
||||
{ .mmdb = mmdb, .offset = entry_data.offset };
|
||||
status = MMDB_get_entry_data_list(&entry,
|
||||
&entry_data_list);
|
||||
MMDB_entry_s entry = {.mmdb = mmdb,
|
||||
.offset = entry_data.offset};
|
||||
status = MMDB_get_entry_data_list(&entry, &entry_data_list);
|
||||
} else {
|
||||
fprintf(
|
||||
stdout,
|
||||
"\n No data was found at the lookup path you provided\n\n");
|
||||
fprintf(stdout,
|
||||
"\n No data was found at the lookup path you "
|
||||
"provided\n\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = MMDB_get_entry_data_list(&result.entry,
|
||||
&entry_data_list);
|
||||
status = MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
||||
}
|
||||
|
||||
if (MMDB_SUCCESS != status) {
|
||||
fprintf(stderr, "Got an error looking up the entry data - %s\n",
|
||||
fprintf(stderr,
|
||||
"Got an error looking up the entry data - %s\n",
|
||||
MMDB_strerror(status));
|
||||
exit_code = 5;
|
||||
goto end;
|
||||
@ -533,7 +535,7 @@ LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
|
||||
exit_code = 6;
|
||||
}
|
||||
|
||||
end:
|
||||
end:
|
||||
MMDB_free_entry_data_list(entry_data_list);
|
||||
MMDB_close(mmdb);
|
||||
free((void *)lookup_path);
|
||||
@ -541,8 +543,7 @@ LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
LOCAL int benchmark(MMDB_s *mmdb, int iterations)
|
||||
{
|
||||
static int benchmark(MMDB_s *mmdb, int iterations) {
|
||||
char ip_address[16];
|
||||
int exit_code = 0;
|
||||
|
||||
@ -556,11 +557,12 @@ LOCAL int benchmark(MMDB_s *mmdb, int iterations)
|
||||
|
||||
if (result.found_entry) {
|
||||
|
||||
int status = MMDB_get_entry_data_list(&result.entry,
|
||||
&entry_data_list);
|
||||
int status =
|
||||
MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
||||
|
||||
if (MMDB_SUCCESS != status) {
|
||||
fprintf(stderr, "Got an error looking up the entry data - %s\n",
|
||||
fprintf(stderr,
|
||||
"Got an error looking up the entry data - %s\n",
|
||||
MMDB_strerror(status));
|
||||
exit_code = 5;
|
||||
MMDB_free_entry_data_list(entry_data_list);
|
||||
@ -573,19 +575,20 @@ LOCAL int benchmark(MMDB_s *mmdb, int iterations)
|
||||
|
||||
time = clock() - time;
|
||||
double seconds = ((double)time / CLOCKS_PER_SEC);
|
||||
fprintf(
|
||||
stdout,
|
||||
"\n Looked up %i addresses in %.2f seconds. %.2f lookups per second.\n\n",
|
||||
iterations, seconds, iterations / seconds);
|
||||
fprintf(stdout,
|
||||
"\n Looked up %i addresses in %.2f seconds. %.2f lookups per "
|
||||
"second.\n\n",
|
||||
iterations,
|
||||
seconds,
|
||||
iterations / seconds);
|
||||
|
||||
end:
|
||||
end:
|
||||
MMDB_close(mmdb);
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr)
|
||||
{
|
||||
static MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr) {
|
||||
int gai_error, mmdb_error;
|
||||
MMDB_lookup_result_s result =
|
||||
MMDB_lookup_string(mmdb, ipstr, &gai_error, &mmdb_error);
|
||||
@ -599,12 +602,13 @@ LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr)
|
||||
#else
|
||||
gai_strerror(gai_error)
|
||||
#endif
|
||||
);
|
||||
);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if (MMDB_SUCCESS != mmdb_error) {
|
||||
fprintf(stderr, "\n Got an error from the maxminddb library: %s\n\n",
|
||||
fprintf(stderr,
|
||||
"\n Got an error from the maxminddb library: %s\n\n",
|
||||
MMDB_strerror(mmdb_error));
|
||||
exit(4);
|
||||
}
|
||||
@ -612,15 +616,19 @@ LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr)
|
||||
return result;
|
||||
}
|
||||
|
||||
LOCAL void random_ipv4(char *ip)
|
||||
{
|
||||
static void random_ipv4(char *ip) {
|
||||
// rand() is perfectly fine for this use case
|
||||
// coverity[dont_call]
|
||||
int ip_int = rand();
|
||||
uint8_t *bytes = (uint8_t *)&ip_int;
|
||||
|
||||
snprintf(ip, 16, "%u.%u.%u.%u",
|
||||
*bytes, *(bytes + 1), *(bytes + 2), *(bytes + 3));
|
||||
snprintf(ip,
|
||||
16,
|
||||
"%u.%u.%u.%u",
|
||||
*bytes,
|
||||
*(bytes + 1),
|
||||
*(bytes + 2),
|
||||
*(bytes + 3));
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
@ -631,13 +639,11 @@ struct thread_info {
|
||||
int iterations;
|
||||
};
|
||||
|
||||
static bool start_threaded_benchmark(
|
||||
MMDB_s *const mmdb,
|
||||
int const thread_count,
|
||||
int const iterations)
|
||||
{
|
||||
struct thread_info *const tinfo = calloc(thread_count,
|
||||
sizeof(struct thread_info));
|
||||
static bool start_threaded_benchmark(MMDB_s *const mmdb,
|
||||
int const thread_count,
|
||||
int const iterations) {
|
||||
struct thread_info *const tinfo =
|
||||
calloc(thread_count, sizeof(struct thread_info));
|
||||
if (!tinfo) {
|
||||
fprintf(stderr, "calloc(): %s\n", strerror(errno));
|
||||
return false;
|
||||
@ -685,20 +691,22 @@ static bool start_threaded_benchmark(
|
||||
rate = total_ips / elapsed;
|
||||
}
|
||||
|
||||
fprintf(
|
||||
stdout,
|
||||
"Looked up %llu addresses using %d threads in %.2Lf seconds. %.2Lf lookups per second.\n",
|
||||
total_ips, thread_count, elapsed, rate);
|
||||
fprintf(stdout,
|
||||
"Looked up %llu addresses using %d threads in %.2Lf seconds. %.2Lf "
|
||||
"lookups per second.\n",
|
||||
total_ips,
|
||||
thread_count,
|
||||
elapsed,
|
||||
rate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static long double get_time(void)
|
||||
{
|
||||
static long double get_time(void) {
|
||||
// clock_gettime() is not present on OSX until 10.12.
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec tp = {
|
||||
.tv_sec = 0,
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = 0,
|
||||
};
|
||||
clockid_t clk_id = CLOCK_REALTIME;
|
||||
@ -720,15 +728,14 @@ static long double get_time(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *thread(void *arg)
|
||||
{
|
||||
static void *thread(void *arg) {
|
||||
const struct thread_info *const tinfo = arg;
|
||||
if (!tinfo) {
|
||||
fprintf(stderr, "thread(): %s\n", strerror(EINVAL));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char ip_address[16] = { 0 };
|
||||
char ip_address[16] = {0};
|
||||
|
||||
for (int i = 0; i < tinfo->iterations; i++) {
|
||||
memset(ip_address, 0, 16);
|
||||
@ -740,10 +747,11 @@ static void *thread(void *arg)
|
||||
}
|
||||
|
||||
MMDB_entry_data_list_s *entry_data_list = NULL;
|
||||
int const status = MMDB_get_entry_data_list(&result.entry,
|
||||
&entry_data_list);
|
||||
int const status =
|
||||
MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
||||
if (status != MMDB_SUCCESS) {
|
||||
fprintf(stderr, "MMDB_get_entry_data_list(): %s\n",
|
||||
fprintf(stderr,
|
||||
"MMDB_get_entry_data_list(): %s\n",
|
||||
MMDB_strerror(status));
|
||||
MMDB_free_entry_data_list(entry_data_list);
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user