]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Create one thread per TAL file
authorpcarana <pc.moreno2099@gmail.com>
Tue, 3 Sep 2019 17:42:35 +0000 (12:42 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Tue, 3 Sep 2019 17:42:35 +0000 (12:42 -0500)
+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.

13 files changed:
configure.ac
src/object/tal.c
src/object/tal.h
src/rsync/rsync.c
src/rsync/rsync.h
src/rtr/db/vrps.c
src/rtr/db/vrps.h
src/state.c
src/state.h
test/rsync_test.c
test/rtr/db/rtr_db_impersonator.c
test/rtr/pdu_test.c
test/tal_test.c

index 6831fcac5177ab0eaed108d1022af41008de2043..b1e448e6910026162f45666684ab3ef1b8ad34f7 100644 (file)
@@ -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])
index d395f8559eba1f5173bd9c4a55dc502fa7715220..c198cf5c48f76c502ce55590e8463f09c95bfe80 100644 (file)
@@ -3,10 +3,12 @@
 #include "tal.h"
 
 #include <errno.h>
+#include <pthread.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/queue.h>
 #include <sys/stat.h>
 #include <openssl/evp.h>
 
 #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(&param, 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);
+       }
+}
index d5564d3699a0b934806c4c7afdb00273cce01a63..12e6669ca9b1ff2827294511df044e94c90949c3 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <stddef.h>
 #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_ */
index 5e7e2449c8eedd5650b5eaadc8d4cfe92022f568..80bafea8fc6047481b44563246f65db2f9247b6f 100644 (file)
@@ -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;
index 72bca0b0db4ed49c4398340274ec71288df05555..0cb63183b601b7eaac2c4252b450733a6460d3d2 100644 (file)
@@ -4,9 +4,11 @@
 #include <stdbool.h>
 #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_ */
index b6a1bb01f6b545f967d09871f128d44f35c704f7..6efa3a5544207c01a940f4d3a3465b56cdc68048 100644 (file)
@@ -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;
 }
index 6d6bc7718f1de5a09431a1f3b6b55cf55634d0d5..7877084971dd814d6725918c332006a62ef01ab5 100644 (file)
@@ -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_ */
index f35513925cc0919b6c92e14951a846f81fc7e4af..343f8a24091c43c95ed3d18b5164e6576eab1d6e 100644 (file)
@@ -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)
 {
index 448ccf8ac1145ea15869adb82155a8ce5c053975..495ae87349c31795c864236abb1b830a15d2e2aa 100644 (file)
@@ -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,
index 18ba7c417af148268cea989856ee0c38a94cba77..3fcb1f36639b5d6df8c58573ef6393f954d0ed36 100644 (file)
@@ -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
 
index 5f3e14b218313bc679bd22065305abcce1804437..9a314bf11b1d8f0a89c1d07b0bcb33cbd25a9563 100644 (file)
@@ -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 */
+}
index 3c8883e10170ca4223901b8cb77890adb21e3d9c..e1392776be1c91a054043f4ad1600e1fce9ceb02 100644 (file)
@@ -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
index 39a2de3f324d6ee4c5e00ad89bcf22c9233beb73..aedfabc646a7221a0f15a719027f67c516fb4e1f 100644 (file)
@@ -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;