2021-01-31 17:48:31 +01:00
|
|
|
#include "maxminddb_test_helper.h"
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
typedef struct thread_arg {
|
|
|
|
int thread_id;
|
|
|
|
MMDB_s *mmdb;
|
|
|
|
const char *ip_to_lookup;
|
|
|
|
} thread_arg_s;
|
|
|
|
|
|
|
|
typedef struct test_result {
|
|
|
|
const char *ip_looked_up;
|
|
|
|
int lookup_string_gai_error;
|
|
|
|
int lookup_string_mmdb_error;
|
|
|
|
int found_entry;
|
|
|
|
int get_value_status;
|
|
|
|
int data_type_ok;
|
|
|
|
char *data_value;
|
|
|
|
} test_result_s;
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void test_one_ip(MMDB_s *mmdb, const char *ip, test_result_s *test_result) {
|
2021-01-31 17:48:31 +01:00
|
|
|
|
|
|
|
test_result->ip_looked_up = ip;
|
|
|
|
|
|
|
|
int gai_error = 0;
|
|
|
|
int mmdb_error = 0;
|
|
|
|
MMDB_lookup_result_s result =
|
|
|
|
MMDB_lookup_string(mmdb, ip, &gai_error, &mmdb_error);
|
|
|
|
|
|
|
|
test_result->lookup_string_gai_error = gai_error;
|
|
|
|
if (gai_error) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_result->lookup_string_mmdb_error = mmdb_error;
|
|
|
|
if (mmdb_error) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_result->found_entry = result.found_entry;
|
|
|
|
if (!result.found_entry) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MMDB_entry_data_s data;
|
|
|
|
int status = MMDB_get_value(&result.entry, &data, "ip", NULL);
|
|
|
|
|
|
|
|
test_result->get_value_status = status;
|
|
|
|
if (status) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_result->data_type_ok = data.type == MMDB_DATA_TYPE_UTF8_STRING;
|
|
|
|
if (!test_result->data_type_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_result->data_value = mmdb_strndup(data.utf8_string, data.data_size);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void *run_one_thread(void *arg) {
|
2021-01-31 17:48:31 +01:00
|
|
|
thread_arg_s *thread_arg = (thread_arg_s *)arg;
|
|
|
|
|
|
|
|
MMDB_s *mmdb = thread_arg->mmdb;
|
|
|
|
const char *ip = thread_arg->ip_to_lookup;
|
|
|
|
|
|
|
|
test_result_s *result = malloc(sizeof(test_result_s));
|
2021-08-22 19:15:19 +02:00
|
|
|
if (!result) {
|
|
|
|
BAIL_OUT("could not allocate memory");
|
|
|
|
}
|
2021-01-31 17:48:31 +01:00
|
|
|
test_one_ip(mmdb, ip, result);
|
|
|
|
|
|
|
|
pthread_exit((void *)result);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void process_result(test_result_s *result,
|
|
|
|
const char *expect,
|
|
|
|
const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
int is_ok;
|
2021-08-22 19:15:19 +02:00
|
|
|
is_ok = ok(!result->lookup_string_gai_error,
|
|
|
|
"no getaddrinfo error for %s - %s",
|
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (!is_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
is_ok = ok(!result->lookup_string_mmdb_error,
|
|
|
|
"no mmdb error for %s - %s",
|
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (!is_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
is_ok = ok(result->found_entry,
|
|
|
|
"got a result for %s in the database - %s",
|
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (!is_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
is_ok = ok(!result->get_value_status,
|
|
|
|
"no error from MMDB_get_value for %s - %s",
|
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (!is_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
is_ok = ok(result->data_type_ok,
|
|
|
|
"MMDB_get_value found a utf8_string at 'ip' key for %s - %s",
|
2021-08-22 19:15:19 +02:00
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (!is_ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
is(result->data_value,
|
|
|
|
expect,
|
2021-01-31 17:48:31 +01:00
|
|
|
"found expected result for 'ip' key for %s - %s",
|
2021-08-22 19:15:19 +02:00
|
|
|
result->ip_looked_up,
|
|
|
|
mode_desc);
|
2021-01-31 17:48:31 +01:00
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void run_ipX_tests(MMDB_s *mmdb,
|
|
|
|
const char *pairs[][2],
|
|
|
|
int pairs_rows,
|
|
|
|
int mode,
|
|
|
|
const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
pthread_t threads[pairs_rows];
|
|
|
|
struct thread_arg thread_args[pairs_rows];
|
|
|
|
|
|
|
|
for (int i = 0; i < pairs_rows; i += 1) {
|
|
|
|
thread_args[i].thread_id = i;
|
|
|
|
thread_args[i].mmdb = mmdb;
|
|
|
|
thread_args[i].ip_to_lookup = pairs[i][0];
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
int error =
|
|
|
|
pthread_create(&threads[i], NULL, run_one_thread, &thread_args[i]);
|
2021-01-31 17:48:31 +01:00
|
|
|
if (error) {
|
|
|
|
BAIL_OUT("pthread_create failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < pairs_rows; i += 1) {
|
|
|
|
void *thread_return;
|
|
|
|
int error = pthread_join(threads[i], &thread_return);
|
|
|
|
if (error) {
|
|
|
|
BAIL_OUT("pthread_join failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
test_result_s *test_result = (test_result_s *)thread_return;
|
|
|
|
if (NULL != test_result) {
|
|
|
|
process_result(test_result, pairs[i][1], mode_desc);
|
|
|
|
if (test_result->data_type_ok) {
|
|
|
|
free(test_result->data_value);
|
|
|
|
}
|
|
|
|
free(test_result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
void run_tests(int mode, const char *mode_desc) {
|
2021-01-31 17:48:31 +01:00
|
|
|
const char *filename = "MaxMind-DB-test-mixed-32.mmdb";
|
|
|
|
const char *path = test_database_path(filename);
|
|
|
|
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
|
|
|
free((void *)path);
|
|
|
|
|
|
|
|
const char *pairs[18][2] = {
|
2021-08-22 19:15:19 +02:00
|
|
|
{"1.1.1.1", "::1.1.1.1"},
|
|
|
|
{"1.1.1.2", "::1.1.1.2"},
|
|
|
|
{"1.1.1.3", "::1.1.1.2"},
|
|
|
|
{"1.1.1.7", "::1.1.1.4"},
|
|
|
|
{"1.1.1.9", "::1.1.1.8"},
|
|
|
|
{"1.1.1.15", "::1.1.1.8"},
|
|
|
|
{"1.1.1.17", "::1.1.1.16"},
|
|
|
|
{"1.1.1.31", "::1.1.1.16"},
|
|
|
|
{"1.1.1.32", "::1.1.1.32"},
|
|
|
|
{"::1:ffff:ffff", "::1:ffff:ffff"},
|
|
|
|
{"::2:0:0", "::2:0:0"},
|
|
|
|
{"::2:0:1a", "::2:0:0"},
|
|
|
|
{"::2:0:40", "::2:0:40"},
|
|
|
|
{"::2:0:4f", "::2:0:40"},
|
|
|
|
{"::2:0:50", "::2:0:50"},
|
|
|
|
{"::2:0:52", "::2:0:50"},
|
|
|
|
{"::2:0:58", "::2:0:58"},
|
|
|
|
{"::2:0:59", "::2:0:58"},
|
2021-01-31 17:48:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
run_ipX_tests(mmdb, pairs, 18, mode, mode_desc);
|
|
|
|
|
|
|
|
MMDB_close(mmdb);
|
|
|
|
free(mmdb);
|
|
|
|
}
|
|
|
|
|
2021-08-22 19:15:19 +02:00
|
|
|
int main(void) {
|
2021-01-31 17:48:31 +01:00
|
|
|
plan(NO_PLAN);
|
|
|
|
for_all_modes(&run_tests);
|
|
|
|
done_testing();
|
|
|
|
pthread_exit(NULL);
|
|
|
|
}
|