From: pcarana Date: Tue, 3 Sep 2019 17:42:35 +0000 (-0500) Subject: Create one thread per TAL file X-Git-Tag: v1.1.0~1^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b4ed8ee86e61540a7b10c962e0e313b9f0a68e18;p=thirdparty%2FFORT-validator.git Create one thread per TAL file +Each TAL will validate its own repositories without waiting for the others to terminate. +Remove a TODO on configure.ac +Update unit tests. +Fix warning at base64 sanitizer, replace the function 'strchr' with a local one since the read buffer isn't necessarily a string. --- diff --git a/configure.ac b/configure.ac index 6831fcac..b1e448e6 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,6 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -# TODO change the bug report address AC_INIT([fort], [1.0.0], [fort-validator@nic.mx]) AC_CONFIG_SRCDIR([src/main.c]) AM_INIT_AUTOMAKE([subdir-objects]) diff --git a/src/object/tal.c b/src/object/tal.c index d395f855..c198cf5c 100644 --- a/src/object/tal.c +++ b/src/object/tal.c @@ -3,10 +3,12 @@ #include "tal.h" #include +#include #include #include #include #include +#include #include #include @@ -18,9 +20,11 @@ #include "random.h" #include "state.h" #include "thread_var.h" +#include "validation_handler.h" #include "crypto/base64.h" #include "object/certificate.h" #include "rsync/rsync.h" +#include "rtr/db/vrps.h" #define TAL_FILE_EXTENSION ".tal" @@ -37,6 +41,20 @@ struct tal { size_t spki_len; }; +struct fv_param { + char *tal_file; + void *arg; +}; + +struct thread { + pthread_t pid; + char *file; + SLIST_ENTRY(thread) next; +}; + +/* List of threads, one per TAL file */ +SLIST_HEAD(threads_list, thread) threads; + static int uris_init(struct uris *uris) { @@ -132,6 +150,17 @@ get_spki_alloc_size(struct line_file *lfile) return EVP_DECODE_LENGTH(get_spki_orig_size(lfile)); } +static char * +locate_char(char *str, size_t len, char find) +{ + size_t i; + + for(i = 0; i < len; i++) + if (str[i] == find) + return str + i; + return NULL; +} + /* * Get the base64 chars from @lfile and allocate to @out with lines no greater * than 65 chars (including line feed). @@ -144,8 +173,7 @@ base64_sanitize(struct line_file *lfile, char **out) { #define BUF_SIZE 65 FILE *fd; - char buf[BUF_SIZE]; - char *result, *eol; + char *buf, *result, *eol; size_t original_size, new_size; size_t fread_result, offset; int error; @@ -160,6 +188,12 @@ base64_sanitize(struct line_file *lfile, char **out) if (result == NULL) return pr_enomem(); + buf = malloc(BUF_SIZE); + if (buf == NULL) { + free(result); + return pr_enomem(); + } + fd = lfile_fd(lfile); offset = 0; while ((fread_result = fread(buf, 1, @@ -177,7 +211,7 @@ base64_sanitize(struct line_file *lfile, char **out) } original_size -= fread_result; - eol = strchr(buf, '\n'); + eol = locate_char(buf, fread_result, '\n'); /* Larger than buffer length, add LF and copy last char */ if (eol == NULL) { memcpy(&result[offset], buf, fread_result - 1); @@ -208,11 +242,13 @@ base64_sanitize(struct line_file *lfile, char **out) } result = eol; } + free(buf); result[offset] = '\0'; *out = result; return 0; free_result: + free(buf); free(result); return error; #undef BUF_SIZE @@ -395,22 +431,29 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg) * A "hard error" is any other error. */ + struct validation_handler validation_handler; struct validation *state; struct cert_stack *certstack; struct deferred_cert deferred; int error; + validation_handler.handle_roa_v4 = handle_roa_v4; + validation_handler.handle_roa_v6 = handle_roa_v6; + validation_handler.handle_router_key = handle_router_key; + validation_handler.arg = arg; + + error = validation_prepare(&state, tal, &validation_handler); + if (error) + return ENSURE_NEGATIVE(error); + error = download_files(uri, true, false); if (error) { pr_warn("TAL '%s' could not be RSYNC'd.", uri_get_printable(uri)); + validation_destroy(state); return ENSURE_NEGATIVE(error); } - error = validation_prepare(&state, tal, arg); - if (error) - return ENSURE_NEGATIVE(error); - pr_debug_add("TAL URI '%s' {", uri_get_printable(uri)); if (!uri_is_certificate(uri)) { @@ -471,47 +514,123 @@ end: validation_destroy(state); return error; } -static int -do_file_validation(char const *tal_file, void *arg) +static void * +do_file_validation(void *thread_arg) { + struct fv_param param; struct tal *tal; int error; - fnstack_push(tal_file); + memcpy(¶m, thread_arg, sizeof(param)); + free(thread_arg); - error = tal_load(tal_file, &tal); + fnstack_init(); + fnstack_push(param.tal_file); + + error = tal_load(param.tal_file, &tal); if (error) goto end; if (config_get_shuffle_tal_uris()) tal_shuffle_uris(tal); - error = foreach_uri(tal, handle_tal_uri, arg); + error = foreach_uri(tal, handle_tal_uri, param.arg); if (error > 0) error = 0; else if (error == 0) error = pr_err("None of the URIs of the TAL '%s' yielded a successful traversal.", - tal_file); + param.tal_file); tal_destroy(tal); end: - fnstack_pop(); + fnstack_cleanup(); + free(param.tal_file); + return NULL; +} + +static void +thread_destroy(struct thread *thread) +{ + free(thread->file); + free(thread); +} + +/* Creates a thread for the @tal_file */ +static int +__do_file_validation(char const *tal_file, void *arg) +{ + struct thread *thread; + struct fv_param *param; + static pthread_t pid; + int error; + + param = malloc(sizeof(struct fv_param)); + if (param == NULL) + return pr_enomem(); + + param->tal_file = strdup(tal_file); + param->arg = arg; + + errno = pthread_create(&pid, NULL, do_file_validation, param); + if (errno) { + error = -pr_errno(errno, + "Could not spawn the file validation thread"); + goto free_param; + } + + thread = malloc(sizeof(struct thread)); + if (thread == NULL) { + close_thread(pid, tal_file); + error = -EINVAL; + goto free_param; + } + + thread->pid = pid; + thread->file = strdup(tal_file); + SLIST_INSERT_HEAD(&threads, thread, next); + + return 0; +free_param: + free(param->tal_file); + free(param); return error; } int -perform_standalone_validation(struct validation_handler *handler) +perform_standalone_validation(struct db_table *table) { + struct thread *thread; int error; - error = rsync_init(); + SLIST_INIT(&threads); + error = process_file_or_dir(config_get_tal(), TAL_FILE_EXTENSION, + __do_file_validation, table); if (error) return error; - fnstack_init(); - error = process_file_or_dir(config_get_tal(), TAL_FILE_EXTENSION, - do_file_validation, handler); - fnstack_cleanup(); - rsync_destroy(); + /* Wait for all */ + while (!SLIST_EMPTY(&threads)) { + thread = threads.slh_first; + error = pthread_join(thread->pid, NULL); + if (error) + pr_crit("pthread_join() threw %d on the '%s' thread.", + error, thread->file); + SLIST_REMOVE_HEAD(&threads, next); + thread_destroy(thread); + } return error; } + +void +terminate_standalone_validation(void) +{ + struct thread *thread; + + /* End all threads */ + while (!SLIST_EMPTY(&threads)) { + thread = threads.slh_first; + close_thread(thread->pid, thread->file); + SLIST_REMOVE_HEAD(&threads, next); + thread_destroy(thread); + } +} diff --git a/src/object/tal.h b/src/object/tal.h index d5564d36..12e6669c 100644 --- a/src/object/tal.h +++ b/src/object/tal.h @@ -5,7 +5,7 @@ #include #include "uri.h" -#include "validation_handler.h" +#include "rtr/db/db_table.h" struct tal; @@ -19,6 +19,7 @@ void tal_shuffle_uris(struct tal *); char const *tal_get_file_name(struct tal *); void tal_get_spki(struct tal *, unsigned char const **, size_t *); -int perform_standalone_validation(struct validation_handler *); +int perform_standalone_validation(struct db_table *); +void terminate_standalone_validation(void); #endif /* TAL_OBJECT_H_ */ diff --git a/src/rsync/rsync.c b/src/rsync/rsync.c index 5e7e2449..80bafea8 100644 --- a/src/rsync/rsync.c +++ b/src/rsync/rsync.c @@ -12,6 +12,7 @@ #include "config.h" #include "log.h" #include "str.h" +#include "thread_var.h" struct uri { struct rpki_uri *uri; @@ -19,28 +20,37 @@ struct uri { }; /** URIs that we have already downloaded. */ -SLIST_HEAD(uri_list, uri) visited_uris; +SLIST_HEAD(uri_list, uri); /* static char const *const RSYNC_PREFIX = "rsync://"; */ int -rsync_init(void) +rsync_create(struct uri_list **result) { - SLIST_INIT(&visited_uris); + struct uri_list *visited_uris; + + visited_uris = malloc(sizeof(struct uri_list)); + if (visited_uris == NULL) + return pr_enomem(); + + SLIST_INIT(visited_uris); + + *result = visited_uris; return 0; } void -rsync_destroy(void) +rsync_destroy(struct uri_list *list) { struct uri *uri; - while (!SLIST_EMPTY(&visited_uris)) { - uri = SLIST_FIRST(&visited_uris); - SLIST_REMOVE_HEAD(&visited_uris, next); + while (!SLIST_EMPTY(list)) { + uri = SLIST_FIRST(list); + SLIST_REMOVE_HEAD(list, next); uri_refput(uri->uri); free(uri); } + free(list); } /* @@ -77,12 +87,12 @@ is_descendant(struct rpki_uri *ancestor, struct rpki_uri *descendant) * run. */ static bool -is_already_downloaded(struct rpki_uri *uri) +is_already_downloaded(struct rpki_uri *uri, struct uri_list *visited_uris) { struct uri *cursor; /* TODO (next iteration) this is begging for a radix trie. */ - SLIST_FOREACH(cursor, &visited_uris, next) + SLIST_FOREACH(cursor, visited_uris, next) if (is_descendant(cursor->uri, uri)) return true; @@ -90,7 +100,7 @@ is_already_downloaded(struct rpki_uri *uri) } static int -mark_as_downloaded(struct rpki_uri *uri) +mark_as_downloaded(struct rpki_uri *uri, struct uri_list *visited_uris) { struct uri *node; @@ -101,7 +111,7 @@ mark_as_downloaded(struct rpki_uri *uri) node->uri = uri; uri_refget(uri); - SLIST_INSERT_HEAD(&visited_uris, node, next); + SLIST_INSERT_HEAD(visited_uris, node, next); return 0; } @@ -375,13 +385,21 @@ download_files(struct rpki_uri *requested_uri, bool is_ta, bool force) * @rsync_uri is the URL we're actually going to RSYNC. * (They can differ, depending on config_get_sync_strategy().) */ + struct validation *state; + struct uri_list *visited_uris; struct rpki_uri *rsync_uri; int error; if (config_get_sync_strategy() == SYNC_OFF) return 0; - if (!force && is_already_downloaded(requested_uri)) { + state = state_retrieve(); + if (state == NULL) + return -EINVAL; + + visited_uris = validation_visited_uris(state); + + if (!force && is_already_downloaded(requested_uri, visited_uris)) { pr_debug("No need to redownload '%s'.", uri_get_printable(requested_uri)); return 0; @@ -399,8 +417,9 @@ download_files(struct rpki_uri *requested_uri, bool is_ta, bool force) /* Don't store when "force" and if its already downloaded */ error = do_rsync(rsync_uri, is_ta); - if (!error && !(force && is_already_downloaded(rsync_uri))) - error = mark_as_downloaded(rsync_uri); + if (!error && + !(force && is_already_downloaded(rsync_uri, visited_uris))) + error = mark_as_downloaded(rsync_uri, visited_uris); uri_refput(rsync_uri); return error; diff --git a/src/rsync/rsync.h b/src/rsync/rsync.h index 72bca0b0..0cb63183 100644 --- a/src/rsync/rsync.h +++ b/src/rsync/rsync.h @@ -4,9 +4,11 @@ #include #include "uri.h" +struct uri_list; + int download_files(struct rpki_uri *, bool, bool); -int rsync_init(void); -void rsync_destroy(void); +int rsync_create(struct uri_list **); +void rsync_destroy(struct uri_list *); #endif /* SRC_RSYNC_RSYNC_H_ */ diff --git a/src/rtr/db/vrps.c b/src/rtr/db/vrps.c index b6a1bb01..6efa3a55 100644 --- a/src/rtr/db/vrps.c +++ b/src/rtr/db/vrps.c @@ -61,7 +61,10 @@ struct state { } state; /** Read/write lock, which protects @state and its inhabitants. */ -static pthread_rwlock_t lock; +static pthread_rwlock_t state_lock; + +/** Lock to protect ROA table during construction. */ +static pthread_rwlock_t table_lock; void deltagroup_cleanup(struct delta_group *group) @@ -92,10 +95,17 @@ vrps_init(void) ? (state.v0_session_id - 1) : (0xFFFFu); - error = pthread_rwlock_init(&lock, NULL); + error = pthread_rwlock_init(&state_lock, NULL); + if (error) { + deltas_db_cleanup(&state.deltas, deltagroup_cleanup); + return pr_errno(error, "state pthread_rwlock_init() errored"); + } + + error = pthread_rwlock_init(&table_lock, NULL); if (error) { + pthread_rwlock_destroy(&state_lock); deltas_db_cleanup(&state.deltas, deltagroup_cleanup); - return pr_errno(error, "pthread_rwlock_init() errored"); + return pr_errno(error, "table pthread_rwlock_init() errored"); } return 0; @@ -107,48 +117,55 @@ vrps_destroy(void) if (state.base != NULL) db_table_destroy(state.base); deltas_db_cleanup(&state.deltas, deltagroup_cleanup); - pthread_rwlock_destroy(&lock); /* Nothing to do with error code */ + /* Nothing to do with error codes from now on */ + pthread_rwlock_destroy(&state_lock); + pthread_rwlock_destroy(&table_lock); } +#define WLOCK_HANDLER(lock, cb) \ + int error; \ + rwlock_write_lock(lock); \ + error = cb; \ + rwlock_unlock(lock); \ + return error; + int -__handle_roa_v4(uint32_t as, struct ipv4_prefix const *prefix, +handle_roa_v4(uint32_t as, struct ipv4_prefix const *prefix, uint8_t max_length, void *arg) { - return rtrhandler_handle_roa_v4(arg, as, prefix, max_length); + WLOCK_HANDLER(&table_lock, + rtrhandler_handle_roa_v4(arg, as, prefix, max_length)) } int -__handle_roa_v6(uint32_t as, struct ipv6_prefix const * prefix, +handle_roa_v6(uint32_t as, struct ipv6_prefix const * prefix, uint8_t max_length, void *arg) { - return rtrhandler_handle_roa_v6(arg, as, prefix, max_length); + WLOCK_HANDLER(&table_lock, + rtrhandler_handle_roa_v6(arg, as, prefix, max_length)) } int -__handle_router_key(unsigned char const *ski, uint32_t as, +handle_router_key(unsigned char const *ski, uint32_t as, unsigned char const *spk, void *arg) { - return rtrhandler_handle_router_key(arg, ski, as, spk); + WLOCK_HANDLER(&table_lock, + rtrhandler_handle_router_key(arg, ski, as, spk)) } static int __perform_standalone_validation(struct db_table **result) { struct db_table *db; - struct validation_handler validation_handler; int error; db = db_table_create(); if (db == NULL) return pr_enomem(); - validation_handler.handle_roa_v4 = __handle_roa_v4; - validation_handler.handle_roa_v6 = __handle_roa_v6; - validation_handler.handle_router_key = __handle_router_key; - validation_handler.arg = db; - - error = perform_standalone_validation(&validation_handler); + error = perform_standalone_validation(db); if (error) { + terminate_standalone_validation(); db_table_destroy(db); return error; } @@ -255,7 +272,7 @@ vrps_update(bool *changed) if (error) return error; - rwlock_write_lock(&lock); + rwlock_write_lock(&state_lock); /* * TODO (next iteration) Remember the last valid SLURM @@ -271,12 +288,12 @@ vrps_update(bool *changed) if (state.base != NULL) { error = compute_deltas(state.base, new_base, &deltas); if (error) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); goto revert_base; } if (deltas_is_empty(deltas)) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); goto revert_deltas; /* error == 0 is good */ } @@ -286,7 +303,7 @@ vrps_update(bool *changed) deltas_node.deltas = deltas; error = deltas_db_add(&state.deltas, &deltas_node); if (error) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); goto revert_deltas; } } @@ -300,13 +317,13 @@ vrps_update(bool *changed) /* Remove unnecessary deltas */ error = vrps_purge(&deltas); if (error) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); goto revert_base; } } else { error = create_empty_delta(&deltas); if (error) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); goto revert_base; } } @@ -315,7 +332,7 @@ vrps_update(bool *changed) state.base = new_base; state.next_serial++; - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); if (old_base != NULL) db_table_destroy(old_base); @@ -345,7 +362,7 @@ vrps_foreach_base(vrp_foreach_cb cb_roa, router_key_foreach_cb cb_rk, void *arg) { int error; - error = rwlock_read_lock(&lock); + error = rwlock_read_lock(&state_lock); if (error) return error; @@ -358,7 +375,7 @@ vrps_foreach_base(vrp_foreach_cb cb_roa, router_key_foreach_cb cb_rk, void *arg) error = -EAGAIN; unlock: - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); return error; } @@ -504,12 +521,12 @@ vrps_get_deltas_from(serial_t from, serial_t *to, struct deltas_db *result) from_found = false; - error = rwlock_read_lock(&lock); + error = rwlock_read_lock(&state_lock); if (error) return error; if (state.base == NULL) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); return -EAGAIN; } @@ -524,7 +541,7 @@ vrps_get_deltas_from(serial_t from, serial_t *to, struct deltas_db *result) error = deltas_db_add(result, group); if (error) { - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); return error; } @@ -532,7 +549,7 @@ vrps_get_deltas_from(serial_t from, serial_t *to, struct deltas_db *result) *to = group->serial; } - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); return from_found ? 0 : -ESRCH; } @@ -541,7 +558,7 @@ get_last_serial_number(serial_t *result) { int error; - error = rwlock_read_lock(&lock); + error = rwlock_read_lock(&state_lock); if (error) return error; @@ -550,7 +567,7 @@ get_last_serial_number(serial_t *result) else error = -EAGAIN; - rwlock_unlock(&lock); + rwlock_unlock(&state_lock); return error; } diff --git a/src/rtr/db/vrps.h b/src/rtr/db/vrps.h index 6d6bc771..78770849 100644 --- a/src/rtr/db/vrps.h +++ b/src/rtr/db/vrps.h @@ -36,6 +36,11 @@ int get_last_serial_number(serial_t *); int vrps_foreach_filtered_delta(struct deltas_db *, delta_vrp_foreach_cb, delta_router_key_foreach_cb, void *); +int handle_roa_v4(uint32_t, struct ipv4_prefix const *, uint8_t, void *); +int handle_roa_v6(uint32_t, struct ipv6_prefix const *, uint8_t, void *); +int handle_router_key(unsigned char const *, uint32_t, unsigned char const *, + void *); + uint16_t get_current_session_id(uint8_t); #endif /* SRC_VRPS_H_ */ diff --git a/src/state.c b/src/state.c index f3551392..343f8a24 100644 --- a/src/state.c +++ b/src/state.c @@ -22,6 +22,8 @@ struct validation { struct cert_stack *certstack; + struct uri_list *visited_uris; + /* Did the TAL's public key match the root certificate's public key? */ enum pubkey_state pubkey_state; @@ -115,12 +117,18 @@ validation_prepare(struct validation **out, struct tal *tal, if (error) goto abort3; + error = rsync_create(&result->visited_uris); + if (error) + goto abort4; + result->pubkey_state = PKS_UNTESTED; result->validation_handler = *validation_handler; result->x509_data.params = params; /* Ownership transfered */ *out = result; return 0; +abort4: + certstack_destroy(result->certstack); abort3: X509_VERIFY_PARAM_free(params); abort2: @@ -136,6 +144,7 @@ validation_destroy(struct validation *state) X509_VERIFY_PARAM_free(state->x509_data.params); X509_STORE_free(state->x509_data.store); certstack_destroy(state->certstack); + rsync_destroy(state->visited_uris); free(state); } @@ -157,6 +166,12 @@ validation_certstack(struct validation *state) return state->certstack; } +struct uri_list * +validation_visited_uris(struct validation *state) +{ + return state->visited_uris; +} + void validation_pubkey_valid(struct validation *state) { diff --git a/src/state.h b/src/state.h index 448ccf8a..495ae873 100644 --- a/src/state.h +++ b/src/state.h @@ -5,6 +5,7 @@ #include "cert_stack.h" #include "validation_handler.h" #include "object/tal.h" +#include "rsync/rsync.h" struct validation; @@ -14,7 +15,8 @@ void validation_destroy(struct validation *); struct tal *validation_tal(struct validation *); X509_STORE *validation_store(struct validation *); -struct cert_stack *validation_certstack(struct validation *state); +struct cert_stack *validation_certstack(struct validation *); +struct uri_list *validation_visited_uris(struct validation *); enum pubkey_state { PKS_VALID, diff --git a/test/rsync_test.c b/test/rsync_test.c index 18ba7c41..3fcb1f36 100644 --- a/test/rsync_test.c +++ b/test/rsync_test.c @@ -8,6 +8,13 @@ #include "uri.c" #include "rsync/rsync.c" + +struct validation * +state_retrieve(void) +{ + return NULL; +} + START_TEST(rsync_load_normal) { @@ -52,48 +59,50 @@ START_TEST(rsync_test_prefix_equals) END_TEST static void -__mark_as_downloaded(char *uri_str) +__mark_as_downloaded(char *uri_str, struct uri_list *visited_uris) { struct rpki_uri *uri; ck_assert_int_eq(0, uri_create_str(&uri, uri_str, strlen(uri_str))); - ck_assert_int_eq(mark_as_downloaded(uri), 0); + ck_assert_int_eq(mark_as_downloaded(uri, visited_uris), 0); uri_refput(uri); } static void -assert_downloaded(char *uri_str, bool expected) +assert_downloaded(char *uri_str, struct uri_list *visited_uris, bool expected) { struct rpki_uri *uri; ck_assert_int_eq(0, uri_create_str(&uri, uri_str, strlen(uri_str))); - ck_assert_int_eq(is_already_downloaded(uri), expected); + ck_assert_int_eq(is_already_downloaded(uri, visited_uris), expected); uri_refput(uri); } START_TEST(rsync_test_list) { - struct uri *uri; - - ck_assert_int_eq(rsync_init(), 0); - - __mark_as_downloaded("rsync://example.foo/repository/"); - __mark_as_downloaded("rsync://example.foo/member_repository/"); - __mark_as_downloaded("rsync://example.foz/repository/"); - __mark_as_downloaded("rsync://example.boo/repo/"); - __mark_as_downloaded("rsync://example.potato/rpki/"); - - assert_downloaded("rsync://example.foo/repository/", true); - assert_downloaded("rsync://example.foo/repository/abc/cdfg", true); - assert_downloaded("rsync://example.foo/member_repository/bca", true); - assert_downloaded("rsync://example.boo/repository/", false); - assert_downloaded("rsync://example.potato/repository/", false); - assert_downloaded("rsync://example.potato/rpki/abc/", true); - - /* rsync destroy */ - while (!SLIST_EMPTY(&visited_uris)) { - uri = SLIST_FIRST(&visited_uris); - SLIST_REMOVE_HEAD(&visited_uris, next); - free(uri); - } + struct uri_list *visited_uris; + + ck_assert_int_eq(rsync_create(&visited_uris), 0); + + __mark_as_downloaded("rsync://example.foo/repository/", visited_uris); + __mark_as_downloaded("rsync://example.foo/member_repository/", + visited_uris); + __mark_as_downloaded("rsync://example.foz/repository/", visited_uris); + __mark_as_downloaded("rsync://example.boo/repo/", visited_uris); + __mark_as_downloaded("rsync://example.potato/rpki/", visited_uris); + + assert_downloaded("rsync://example.foo/repository/", visited_uris, + true); + assert_downloaded("rsync://example.foo/repository/abc/cdfg", + visited_uris, true); + assert_downloaded("rsync://example.foo/member_repository/bca", + visited_uris, true); + assert_downloaded("rsync://example.boo/repository/", visited_uris, + false); + assert_downloaded("rsync://example.potato/repository/", visited_uris, + false); + assert_downloaded("rsync://example.potato/rpki/abc/", visited_uris, + true); + + rsync_destroy(visited_uris); } END_TEST diff --git a/test/rtr/db/rtr_db_impersonator.c b/test/rtr/db/rtr_db_impersonator.c index 5f3e14b2..9a314bf1 100644 --- a/test/rtr/db/rtr_db_impersonator.c +++ b/test/rtr/db/rtr_db_impersonator.c @@ -26,26 +26,54 @@ add_v6(struct validation_handler *handler, uint32_t as) } int -perform_standalone_validation(struct validation_handler *handler) +__handle_roa_v4(uint32_t as, struct ipv4_prefix const *prefix, + uint8_t max_length, void *arg) { + return rtrhandler_handle_roa_v4(arg, as, prefix, max_length); +} + +int +__handle_roa_v6(uint32_t as, struct ipv6_prefix const * prefix, + uint8_t max_length, void *arg) +{ + return rtrhandler_handle_roa_v6(arg, as, prefix, max_length); +} + +int +__handle_router_key(unsigned char const *ski, uint32_t as, + unsigned char const *spk, void *arg) +{ + return rtrhandler_handle_router_key(arg, ski, as, spk); +} + +int +perform_standalone_validation(struct db_table *table) +{ + struct validation_handler handler; + + handler.handle_roa_v4 = __handle_roa_v4; + handler.handle_roa_v6 = __handle_roa_v6; + handler.handle_router_key = __handle_router_key; + handler.arg = table; + switch (iteration) { case 0: - add_v4(handler, 0); - add_v6(handler, 0); + add_v4(&handler, 0); + add_v6(&handler, 0); break; case 1: - add_v4(handler, 0); - add_v6(handler, 0); - add_v4(handler, 1); - add_v6(handler, 1); + add_v4(&handler, 0); + add_v6(&handler, 0); + add_v4(&handler, 1); + add_v6(&handler, 1); break; case 2: - add_v4(handler, 1); - add_v6(handler, 1); + add_v4(&handler, 1); + add_v6(&handler, 1); break; case 3: - add_v4(handler, 0); - add_v6(handler, 0); + add_v4(&handler, 0); + add_v6(&handler, 0); break; default: ck_abort_msg("perform_standalone_validation() was called too many times (%d).", @@ -55,3 +83,9 @@ perform_standalone_validation(struct validation_handler *handler) iteration++; return 0; } + +void +terminate_standalone_validation(void) +{ + /* Nothing, no threads to join */ +} diff --git a/test/rtr/pdu_test.c b/test/rtr/pdu_test.c index 3c8883e1..e1392776 100644 --- a/test/rtr/pdu_test.c +++ b/test/rtr/pdu_test.c @@ -77,6 +77,27 @@ send_error_report_pdu(int fd, uint8_t version, uint16_t code, return 0; } +int +rtrhandler_handle_roa_v4(struct db_table *table, uint32_t asn, + struct ipv4_prefix const *prefix4, uint8_t max_length) +{ + return 0; +} + +int +rtrhandler_handle_roa_v6(struct db_table *table, uint32_t asn, + struct ipv6_prefix const *prefix6, uint8_t max_length) +{ + return 0; +} + +int +rtrhandler_handle_router_key(struct db_table *table, + unsigned char const *ski, uint32_t as, unsigned char const *spk) +{ + return 0; +} + /* End of impersonator */ static void diff --git a/test/tal_test.c b/test/tal_test.c index 39a2de3f..aedfabc6 100644 --- a/test/tal_test.c +++ b/test/tal_test.c @@ -50,6 +50,12 @@ process_file_or_dir(char const *location, char const *file_ext, return 0; } +void +close_thread(pthread_t thread, char const *what) +{ + /* Nothing to close */ +} + void fnstack_init(void) { @@ -74,6 +80,12 @@ fnstack_push(char const *file) /* Empty */ } +struct validation * +state_retrieve(void) +{ + return NULL; +} + START_TEST(tal_load_normal) { struct tal *tal;