Mostly quality of life improvements.
On the other hand, it looks like the notfatal hash table API was being
used incorrectly. HASH_ADD_KEYPTR can OOM, but `errno` wasn't being
catched.
Fixing this is nontrivial, however, because strange `reqs_error`
functions are in the way, and that's a spaggetti I decided to avoid.
Instead, I converted HASH_ADD_KEYPTR usage to the fatal hash table API.
That's the future according to #40, anyway.
I don't think this has anything to do with #83, though.
* this is the caller's responsibility.
*
* TODO I think most of the code is not checking this.
+ *
+ * Functions that can OOM:
+ *
+ * HASH_ADD_TO_TABLE
+ * HASH_ADD_KEYPTR_BYHASHVALUE_INORDER
+ * HASH_REPLACE_BYHASHVALUE_INORDER
+ * HASH_REPLACE_INORDER
+ * HASH_ADD_KEYPTR_INORDER
+ * HASH_ADD_INORDER
+ * HASH_ADD_BYHASHVALUE_INORDER
+ * HASH_ADD_KEYPTR_BYHASHVALUE
+ * HASH_REPLACE_BYHASHVALUE
+ * HASH_REPLACE (*)
+ * HASH_ADD_KEYPTR (**)
+ * HASH_ADD
+ * HASH_ADD_BYHASHVALUE
+ * HASH_SELECT
+ *
+ * (*) Used by Fort
+ * (**) Used by Fort, but in its fatal uthash form.
*/
#define HASH_NONFATAL_OOM 1
#define uthash_nonfatal_oom(obj) \
struct tal_param {
struct thread_pool *pool;
struct db_table *db;
- struct threads_list *threads;
+ struct threads_list threads;
};
static int
* have been extracted from a TAL.
*/
static int
-handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
+handle_tal_uri(struct tal *tal, struct rpki_uri *uri,
+ struct validation_thread *thread)
{
/*
* Because of the way the foreach iterates, this function must return
* A "hard error" is any other error.
*/
- struct validation_thread *thread_arg = arg;
struct validation_handler validation_handler;
struct validation *state;
struct cert_stack *certstack;
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 = thread_arg->arg;
+ validation_handler.arg = thread->arg;
error = validation_prepare(&state, tal, &validation_handler);
if (error)
return ENSURE_NEGATIVE(error);
- if (thread_arg->sync_files) {
+ if (thread->sync_files) {
if (uri_is_rsync(uri)) {
if (!config_get_rsync_enabled()) {
validation_destroy(state);
}
/* At least one URI was sync'd */
- thread_arg->retry_local = false;
- if (thread_arg->sync_files && working_repo_peek() != NULL)
+ thread->retry_local = false;
+ if (thread->sync_files && working_repo_peek() != NULL)
reqs_errors_rem_uri(working_repo_peek());
working_repo_pop();
if (error)
goto destroy_tal;
- error = foreach_uri(tal, __handle_tal_uri_sync, thread_arg);
+ error = foreach_uri(tal, __handle_tal_uri_sync, thread);
if (error > 0) {
error = 0;
goto destroy_tal;
thread->sync_files = false;
pr_val_warn("Looking for the TA certificate at the local files.");
- error = foreach_uri(tal, __handle_tal_uri_local, thread_arg);
+ error = foreach_uri(tal, __handle_tal_uri_local, thread);
if (error > 0)
error = 0;
else if (error == 0)
goto free_tal_file;
}
- SLIST_INSERT_HEAD(t_param->threads, thread, next);
+ SLIST_INSERT_HEAD(&t_param->threads, thread, next);
return 0;
free_tal_file:
int
perform_standalone_validation(struct thread_pool *pool, struct db_table *table)
{
- struct tal_param *param;
- struct threads_list threads;
+ struct tal_param param;
struct validation_thread *thread;
- int error, t_error;
-
- param = malloc(sizeof(struct tal_param));
- if (param == NULL)
- return pr_enomem();
+ int error;
/* Set existent tal RRDP info to non visited */
db_rrdp_reset_visited_tals();
- SLIST_INIT(&threads);
-
- param->pool = pool;
- param->db = table;
- param->threads = &threads;
+ param.pool = pool;
+ param.db = table;
+ SLIST_INIT(¶m.threads);
error = process_file_or_dir(config_get_tal(), TAL_FILE_EXTENSION, true,
- __do_file_validation, param);
+ __do_file_validation, ¶m);
if (error) {
/* End all thread data */
- while (!SLIST_EMPTY(&threads)) {
- thread = threads.slh_first;
- SLIST_REMOVE_HEAD(&threads, next);
+ while (!SLIST_EMPTY(¶m.threads)) {
+ thread = SLIST_FIRST(¶m.threads);
+ SLIST_REMOVE_HEAD(¶m.threads, next);
thread_destroy(thread);
}
- free(param);
return error;
}
/* Wait for all */
thread_pool_wait(pool);
- t_error = 0;
- while (!SLIST_EMPTY(&threads)) {
- thread = threads.slh_first;
- SLIST_REMOVE_HEAD(&threads, next);
+ while (!SLIST_EMPTY(¶m.threads)) {
+ thread = SLIST_FIRST(¶m.threads);
+ SLIST_REMOVE_HEAD(¶m.threads, next);
if (thread->exit_status) {
- t_error = thread->exit_status;
+ error = thread->exit_status;
pr_op_warn("Validation from TAL '%s' yielded error, discarding any other validation results.",
thread->tal_file);
}
thread_destroy(thread);
}
- /* The parameter isn't needed anymore */
- free(param);
-
/* Log the error'd URIs summary */
reqs_errors_log_summary();
/* One thread has errors, validation can't keep the resulting table */
- if (t_error)
- return t_error;
+ if (error)
+ return error;
/* Remove non-visited rrdps URIS by tal */
db_rrdp_rem_nonvisited_tals();
- return error;
+ return 0;
}
}
static void
-print_roas(struct db_table *db)
+print_roas(struct db_table const *db)
{
FILE *out;
JSON_OUT json_out;
}
static void
-print_router_keys(struct db_table *db)
+print_router_keys(struct db_table const *db)
{
FILE *out;
JSON_OUT json_out;
}
void
-output_print_data(struct db_table *db)
+output_print_data(struct db_table const *db)
{
print_roas(db);
print_router_keys(db);
#include "rtr/db/db_table.h"
-void output_print_data(struct db_table *);
+void output_print_data(struct db_table const *);
#endif /* SRC_OUTPUT_PRINTER_H_ */
#include <syslog.h>
#include <time.h>
-#include "data_structure/uthash_nonfatal.h"
+#include "data_structure/uthash.h"
#include "common.h"
#include "config.h"
#include "log.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include "data_structure/uthash_nonfatal.h"
+#include "data_structure/uthash.h"
#include "common.h"
#include "log.h"
#include "thread_var.h"
{
struct uris_table *old_uri;
+ /*
+ * TODO (fine) this should use HASH_REPLACE instead of HASH_ADD_KEYPTR
+ */
+
old_uri = find_rrdp_uri(uris, new_uri->uri);
if (old_uri != NULL) {
HASH_DELETE(hh, uris->table, old_uri);
}
int
-db_table_foreach_roa(struct db_table *table, vrp_foreach_cb cb, void *arg)
+db_table_foreach_roa(struct db_table const *table, vrp_foreach_cb cb, void *arg)
{
struct hashable_roa *node, *tmp;
int error;
}
int
-db_table_foreach_router_key(struct db_table *table, router_key_foreach_cb cb,
- void *arg)
+db_table_foreach_router_key(struct db_table const *table,
+ router_key_foreach_cb cb, void *arg)
{
struct hashable_key *node, *tmp;
int error;
unsigned int db_table_roa_count(struct db_table *);
unsigned int db_table_router_key_count(struct db_table *);
-int db_table_foreach_roa(struct db_table *, vrp_foreach_cb, void *);
+int db_table_foreach_roa(struct db_table const *, vrp_foreach_cb, void *);
void db_table_remove_roa(struct db_table *, struct vrp const *);
-int db_table_foreach_router_key(struct db_table *, router_key_foreach_cb,
+int db_table_foreach_router_key(struct db_table const *, router_key_foreach_cb,
void *);
void db_table_remove_router_key(struct db_table *, struct router_key const *);
db_table_destroy(state.base);
}
-#define WLOCK_HANDLER(lock, cb) \
+#define WLOCK_HANDLER(cb) \
int error; \
- rwlock_write_lock(lock); \
+ rwlock_write_lock(&table_lock); \
error = cb; \
- rwlock_unlock(lock); \
+ rwlock_unlock(&table_lock); \
return error;
int
handle_roa_v4(uint32_t as, struct ipv4_prefix const *prefix,
uint8_t max_length, void *arg)
{
- WLOCK_HANDLER(&table_lock,
- rtrhandler_handle_roa_v4(arg, as, prefix, max_length))
+ WLOCK_HANDLER(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)
{
- WLOCK_HANDLER(&table_lock,
- rtrhandler_handle_roa_v6(arg, as, prefix, max_length))
+ WLOCK_HANDLER(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)
{
- WLOCK_HANDLER(&table_lock,
- rtrhandler_handle_router_key(arg, ski, as, spk))
+ WLOCK_HANDLER(rtrhandler_handle_router_key(arg, ski, as, spk))
}
static int
#include "log.h"
#include "thread_var.h"
-static int
-get_current_threads_handler(struct validation_handler const **result)
+static struct validation_handler const *
+get_current_threads_handler(void)
{
struct validation *state;
struct validation_handler const *handler;
state = state_retrieve();
if (state == NULL)
- return -EINVAL;
+ return NULL;
handler = validation_get_validation_handler(state);
if (handler == NULL)
pr_crit("This thread lacks a validation handler.");
- *result = handler;
- return 0;
+ return handler;
}
int
uint8_t max_length)
{
struct validation_handler const *handler;
- int error;
- error = get_current_threads_handler(&handler);
- if (error)
- return error;
+ handler = get_current_threads_handler();
+ if (handler == NULL)
+ return -EINVAL;
return (handler->handle_roa_v4 != NULL)
? handler->handle_roa_v4(as, prefix, max_length, handler->arg)
uint8_t max_length)
{
struct validation_handler const *handler;
- int error;
- error = get_current_threads_handler(&handler);
- if (error)
- return error;
+ handler = get_current_threads_handler();
+ if (handler == NULL)
+ return -EINVAL;
return (handler->handle_roa_v6 != NULL)
? handler->handle_roa_v6(as, prefix, max_length, handler->arg)
unsigned char const *spk)
{
struct validation_handler const *handler;
- int error;
- error = get_current_threads_handler(&handler);
- if (error)
- return error;
+ handler = get_current_threads_handler();
+ if (handler == NULL)
+ return -EINVAL;
return (handler->handle_router_key != NULL)
? handler->handle_router_key(ski, as, spk, handler->arg)
#include "log.h"
#include "delete_dir_daemon.h"
#include "data_structure/array_list.h"
-#include "data_structure/uthash_nonfatal.h"
+#include "data_structure/uthash.h"
struct visited_elem {
/* key */