+The new arguments are: http.enabled, http.priority, http.retry.count, http.retry.interval.
+rrdp.* args still exist. When any of them is set (via conf file or as arg) a warning message is displayed and the value of the argument is set to its corresponding http.* arg.
+Move the 'retries logic' to the http requests, since only RRDP flows had it.
+At a TAL: when shuffle-uris arg is set, do the shuffle first and then consider the priority set at rsync and http args, so that the priority argument can be honored.
fort_SOURCES += config/log_conf.h config/log_conf.c
fort_SOURCES += config/mode.c config/mode.h
fort_SOURCES += config/incidences.h config/incidences.c
+fort_SOURCES += config/rrdp_conf.h config/rrdp_conf.c
fort_SOURCES += config/rsync_strategy.h config/rsync_strategy.c
fort_SOURCES += config/str.c config/str.h
fort_SOURCES += config/string_array.h config/string_array.c
#include "log.h"
#include "config/boolean.h"
#include "config/incidences.h"
+#include "config/rrdp_conf.h"
#include "config/str.h"
#include "config/sync_strategy.h"
#include "config/uint.h"
} rrdp;
struct {
+ /* Enables the protocol */
+ bool enabled;
+ /*
+ * Priority, whenever there's an option to sync something via
+ * http or rsync, use this priority. When working with CAs, this
+ * will override the order set at the CAs in their accessMethod
+ * extension.
+ */
+ unsigned int priority;
+ /* Retry conf, utilized on errors */
+ struct {
+ /* Maximum number of retries on error */
+ unsigned int count;
+ /* Interval (in seconds) between each retry */
+ unsigned int interval;
+ } retry;
/* User-Agent header set at requests */
char *user_agent;
/* Timeout in seconds for the connect phase */
{
.id = 10000,
.name = "rrdp.enabled",
- .type = >_bool,
+ .type = >_rrdp_enabled,
.offset = offsetof(struct rpki_config, rrdp.enabled),
- .doc = "Enables RRDP execution",
+ .doc = "Enables RRDP execution. Will be deprecated, use 'http.enabled' instead.",
}, {
.id = 10001,
.name = "rrdp.priority",
- .type = >_uint32,
+ .type = >_rrdp_priority,
.offset = offsetof(struct rpki_config, rrdp.priority),
- .doc = "Priority of execution to fetch repositories files, a higher value means higher priority",
+ .doc = "Priority of execution to fetch repositories files, a higher value means higher priority. Will be deprecated, use 'http.priority' instead.",
.min = 0,
.max = 100,
}, {
.id = 10002,
.name = "rrdp.retry.count",
- .type = >_uint,
+ .type = >_rrdp_retry_count,
.offset = offsetof(struct rpki_config, rrdp.retry.count),
- .doc = "Maximum amount of retries whenever there's an error fetching RRDP files",
+ .doc = "Maximum amount of retries whenever there's an error fetching RRDP files. Will be deprecated, use 'http.retry.count' instead.",
.min = 0,
.max = UINT_MAX,
}, {
.id = 10003,
.name = "rrdp.retry.interval",
- .type = >_uint,
+ .type = >_rrdp_retry_interval,
.offset = offsetof(struct rpki_config, rrdp.retry.interval),
- .doc = "Period (in seconds) to wait between retries after an error ocurred fetching RRDP files",
+ .doc = "Period (in seconds) to wait between retries after an error ocurred fetching RRDP files. Will be deprecated, use 'http.retry.interval' instead.",
.min = 0,
.max = UINT_MAX,
},
/* HTTP requests parameters */
{
.id = 9000,
+ .name = "http.enabled",
+ .type = >_rrdp_enabled,
+ .offset = offsetof(struct rpki_config, http.enabled),
+ .doc = "Enables outgoing HTTP requests",
+ },
+ {
+ .id = 9001,
+ .name = "http.priority",
+ .type = >_rrdp_priority,
+ .offset = offsetof(struct rpki_config, http.priority),
+ .doc = "Priority of execution to fetch repositories files, a higher value means higher priority",
+ .min = 0,
+ .max = 100,
+ },
+ {
+ .id = 9002,
+ .name = "http.retry.count",
+ .type = >_rrdp_retry_count,
+ .offset = offsetof(struct rpki_config, http.retry.count),
+ .doc = "Maximum amount of retries whenever there's an error requesting HTTP URIs",
+ .min = 0,
+ .max = UINT_MAX,
+ },
+ {
+ .id = 9003,
+ .name = "http.retry.interval",
+ .type = >_rrdp_retry_interval,
+ .offset = offsetof(struct rpki_config, http.retry.interval),
+ .doc = "Period (in seconds) to wait between retries after an error ocurred doing HTTP requests",
+ .min = 0,
+ .max = UINT_MAX,
+ },
+ {
+ .id = 9004,
.name = "http.user-agent",
.type = >_string,
.offset = offsetof(struct rpki_config, http.user_agent),
.doc = "User-Agent to use at HTTP requests, eg. Fort Validator Local/1.0",
},
{
- .id = 9001,
+ .id = 9005,
.name = "http.connect-timeout",
.type = >_uint,
.offset = offsetof(struct rpki_config, http.connect_timeout),
.max = UINT_MAX,
},
{
- .id = 9002,
+ .id = 9006,
.name = "http.transfer-timeout",
.type = >_uint,
.offset = offsetof(struct rpki_config, http.transfer_timeout),
.max = UINT_MAX,
},
{
- .id = 9003,
+ .id = 9007,
.name = "http.idle-timeout",
.type = >_uint,
.offset = offsetof(struct rpki_config, http.idle_timeout),
.max = UINT_MAX,
},
{
- .id = 9004,
+ .id = 9008,
.name = "http.ca-path",
.type = >_string,
.offset = offsetof(struct rpki_config, http.ca_path),
if (error)
goto revert_recursive_array;
- rpki_config.rrdp.enabled = true;
- rpki_config.rrdp.priority = 50;
- rpki_config.rrdp.retry.count = 2;
- rpki_config.rrdp.retry.interval = 5;
-
+ /* By default, has a higher priority than rsync */
+ rpki_config.http.enabled = true;
+ rpki_config.http.priority = 60;
+ rpki_config.http.retry.count = 2;
+ rpki_config.http.retry.interval = 5;
rpki_config.http.user_agent = strdup(PACKAGE_NAME "/" PACKAGE_VERSION);
if (rpki_config.http.user_agent == NULL) {
error = pr_enomem();
rpki_config.http.idle_timeout = 15;
rpki_config.http.ca_path = NULL; /* Use system default */
+ /*
+ * FIXME (later) Same values as http.*, delete when rrdp.* is fully
+ * deprecated
+ */
+ rpki_config.rrdp.enabled = rpki_config.http.enabled;
+ rpki_config.rrdp.priority = rpki_config.http.priority;
+ rpki_config.rrdp.retry.count = rpki_config.http.retry.count;
+ rpki_config.rrdp.retry.interval = rpki_config.http.retry.interval;
+
rpki_config.log.color = false;
rpki_config.log.filename_format = FNF_GLOBAL;
rpki_config.log.level = LOG_WARNING;
}
bool
-config_get_rrdp_enabled(void)
+config_get_http_enabled(void)
{
- return rpki_config.rrdp.enabled;
+ return rpki_config.http.enabled;
}
unsigned int
-config_get_rrdp_priority(void)
+config_get_http_priority(void)
{
- return rpki_config.rrdp.priority;
+ return rpki_config.http.priority;
}
unsigned int
-config_get_rrdp_retry_count(void)
+config_get_http_retry_count(void)
{
- return rpki_config.rrdp.retry.count;
+ return rpki_config.http.retry.count;
}
unsigned int
-config_get_rrdp_retry_interval(void)
+config_get_http_retry_interval(void)
{
- return rpki_config.rrdp.retry.interval;
+ return rpki_config.http.retry.interval;
}
char const *
rpki_config.rsync.enabled = value;
}
+void
+config_set_http_enabled(bool value)
+{
+ rpki_config.http.enabled = value;
+}
+
+void
+free_rpki_config(void)
+{
+ struct option_field const *option;
+
+ FOREACH_OPTION(options, option, 0xFFFF)
+ if (is_rpki_config_field(option) && option->type->free != NULL)
+ option->type->free(get_rpki_config_field(option));
+}
+
+/*
+ * "To be deprecated" section
+ */
void
config_set_rrdp_enabled(bool value)
{
}
void
-free_rpki_config(void)
+config_set_rrdp_priority(unsigned int value)
{
- struct option_field const *option;
+ rpki_config.rrdp.priority = value;
+}
- FOREACH_OPTION(options, option, 0xFFFF)
- if (is_rpki_config_field(option) && option->type->free != NULL)
- option->type->free(get_rpki_config_field(option));
+void
+config_set_http_priority(unsigned int value)
+{
+ rpki_config.http.priority = value;
+}
+
+void
+config_set_rrdp_retry_count(unsigned int value)
+{
+ rpki_config.rrdp.retry.count = value;
+}
+
+void
+config_set_http_retry_count(unsigned int value)
+{
+ rpki_config.http.retry.count = value;
+}
+
+void
+config_set_rrdp_retry_interval(unsigned int value)
+{
+ rpki_config.rrdp.retry.interval = value;
+}
+
+void
+config_set_http_retry_interval(unsigned int value)
+{
+ rpki_config.http.retry.interval = value;
}
unsigned int config_get_rsync_retry_interval(void);
char *config_get_rsync_program(void);
struct string_array const *config_get_rsync_args(bool);
-bool config_get_rrdp_enabled(void);
-unsigned int config_get_rrdp_priority(void);
-unsigned int config_get_rrdp_retry_count(void);
-unsigned int config_get_rrdp_retry_interval(void);
+bool config_get_http_enabled(void);
+unsigned int config_get_http_priority(void);
+unsigned int config_get_http_retry_count(void);
+unsigned int config_get_http_retry_interval(void);
char const *config_get_output_roa(void);
char const *config_get_output_bgpsec(void);
unsigned int config_get_asn1_decode_max_stack(void);
* sync-strategy when set to 'off'.
*/
void config_set_rsync_enabled(bool);
+void config_set_http_enabled(bool);
+/* FIXME (later) This will be deprecated */
void config_set_rrdp_enabled(bool);
/* FIXME (later) Remove when sync-strategy is fully deprecated */
void config_set_sync_strategy(enum rsync_strategy);
void config_set_rsync_strategy(enum rsync_strategy);
+/* FIXME (later) Remove once rrdp.* is fully deprecated */
+void config_set_rrdp_priority(unsigned int);
+void config_set_http_priority(unsigned int);
+void config_set_rrdp_retry_count(unsigned int);
+void config_set_http_retry_count(unsigned int);
+void config_set_rrdp_retry_interval(unsigned int);
+void config_set_http_retry_interval(unsigned int);
+
/* Needed public by the JSON module */
void *get_rpki_config_field(struct option_field const *);
struct option_field const *get_option_metadatas(void);
--- /dev/null
+#include "config/rrdp_conf.h"
+
+#include <getopt.h>
+#include <stdbool.h>
+#include <string.h>
+#include "config.h"
+#include "log.h"
+#include "config/boolean.h"
+#include "config/uint.h"
+#include "config/uint32.h"
+
+/*
+ * Note that this is just a wrapper to set rrdp.* arguments and its equivalent
+ * http.* args.
+ *
+ * FIXME (later) This wrapper will live until all rrdp.* args are fully
+ * deprecated.
+ */
+
+#define DEREFERENCE_BOOL(void_value) (*((bool *) void_value))
+#define DEREFERENCE_UINT32(void_value) (*((uint32_t *) void_value))
+#define DEREFERENCE_UINT(void_value) (*((unsigned int *) void_value))
+
+static int
+set_rrdp_enabled(char const *name, bool value)
+{
+ /* Warn about future deprecation */
+ if (strcmp(name, "rrdp.enabled") == 0)
+ pr_op_warn("'rrdp.enabled' will be deprecated, use 'http.enabled' instead.");
+
+ config_set_rrdp_enabled(value);
+ config_set_http_enabled(value);
+ return 0;
+}
+
+static int
+set_priority(char const *name, uint32_t value)
+{
+ /* Warn about future deprecation */
+ if (strcmp(name, "rrdp.priority") == 0)
+ pr_op_warn("'rrdp.priority' will be deprecated, use 'http.priority' instead.");
+
+ config_set_rrdp_priority(value);
+ config_set_http_priority(value);
+ return 0;
+}
+
+static int
+set_retry_count(char const *name, unsigned int value)
+{
+ /* Warn about future deprecation */
+ if (strcmp(name, "rrdp.retry.count") == 0)
+ pr_op_warn("'rrdp.retry.count' will be deprecated, use 'http.retry.count' instead.");
+
+ config_set_rrdp_retry_count(value);
+ config_set_http_retry_count(value);
+ return 0;
+}
+
+static int
+set_retry_interval(char const *name, unsigned int value)
+{
+ /* Warn about future deprecation */
+ if (strcmp(name, "rrdp.retry.interval") == 0)
+ pr_op_warn("'rrdp.retry.interval' will be deprecated, use 'http.retry.interval' instead.");
+
+ config_set_rrdp_retry_interval(value);
+ config_set_http_retry_interval(value);
+ return 0;
+}
+
+int
+parse_argv_enabled(struct option_field const *field, char const *str,
+ void *result)
+{
+ int error;
+
+ error = parse_argv_bool(field, str, result);
+ if (error)
+ return error;
+
+ return set_rrdp_enabled(field->name, DEREFERENCE_BOOL(result));
+}
+
+int
+parse_json_enabled(struct option_field const *opt, struct json_t *json,
+ void *result)
+{
+ int error;
+
+ error = parse_json_bool(opt, json, result);
+ if (error)
+ return error;
+
+ return set_rrdp_enabled(opt->name, DEREFERENCE_BOOL(result));
+}
+
+int
+parse_argv_priority(struct option_field const *field, char const *str,
+ void *result)
+{
+ int error;
+
+ error = parse_argv_uint32(field, str, result);
+ if (error)
+ return error;
+
+ return set_priority(field->name, DEREFERENCE_UINT32(result));
+}
+
+int
+parse_json_priority(struct option_field const *opt, json_t *json, void *result)
+{
+ int error;
+
+ error = parse_json_uint32(opt, json, result);
+ if (error)
+ return error;
+
+ return set_priority(opt->name, DEREFERENCE_UINT32(result));
+}
+
+int
+parse_argv_retry_count(struct option_field const *field, char const *str,
+ void *result)
+{
+ int error;
+
+ error = parse_argv_uint(field, str, result);
+ if (error)
+ return error;
+
+ return set_retry_count(field->name, DEREFERENCE_UINT(result));
+}
+
+int
+parse_json_retry_count(struct option_field const *opt, json_t *json,
+ void *result)
+{
+ int error;
+
+ error = parse_json_uint(opt, json, result);
+ if (error)
+ return error;
+
+ return set_retry_count(opt->name, DEREFERENCE_UINT(result));
+}
+
+int
+parse_argv_retry_interval(struct option_field const *field, char const *str,
+ void *result)
+{
+ int error;
+
+ error = parse_argv_uint(field, str, result);
+ if (error)
+ return error;
+
+ return set_retry_interval(field->name, DEREFERENCE_UINT(result));
+}
+
+int
+parse_json_retry_interval(struct option_field const *opt, json_t *json,
+ void *result)
+{
+ int error;
+
+ error = parse_json_uint(opt, json, result);
+ if (error)
+ return error;
+
+ return set_retry_interval(opt->name, DEREFERENCE_UINT(result));
+}
+
+const struct global_type gt_rrdp_enabled = {
+ .has_arg = optional_argument,
+ .size = sizeof(bool),
+ .print = print_bool,
+ .parse.argv = parse_argv_enabled,
+ .parse.json = parse_json_enabled,
+ .arg_doc = "true|false",
+};
+
+const struct global_type gt_rrdp_priority = {
+ .has_arg = required_argument,
+ .size = sizeof(uint32_t),
+ .print = print_uint32,
+ .parse.argv = parse_argv_priority,
+ .parse.json = parse_json_priority,
+ .arg_doc = "<32-bit unsigned integer>",
+};
+
+const struct global_type gt_rrdp_retry_count = {
+ .has_arg = required_argument,
+ .size = sizeof(unsigned int),
+ .print = print_uint,
+ .parse.argv = parse_argv_retry_count,
+ .parse.json = parse_json_retry_count,
+ .arg_doc = "<unsigned integer>",
+};
+
+const struct global_type gt_rrdp_retry_interval = {
+ .has_arg = required_argument,
+ .size = sizeof(unsigned int),
+ .print = print_uint,
+ .parse.argv = parse_argv_retry_interval,
+ .parse.json = parse_json_retry_interval,
+ .arg_doc = "<unsigned integer>",
+};
--- /dev/null
+#ifndef SRC_CONFIG_RRDP_CONF_H_
+#define SRC_CONFIG_RRDP_CONF_H_
+
+#include "config/types.h"
+
+extern const struct global_type gt_rrdp_enabled;
+extern const struct global_type gt_rrdp_priority;
+extern const struct global_type gt_rrdp_retry_count;
+extern const struct global_type gt_rrdp_retry_interval;
+
+#endif /* SRC_CONFIG_RRDP_CONF_H_ */
#include <string.h>
#include "log.h"
-static void
+void
print_uint(struct option_field const *field, void *value)
{
pr_op_info("%s: %u", field->name, *((unsigned int *) value));
extern const struct global_type gt_uint;
+void print_uint(struct option_field const *, void *);
int parse_argv_uint(struct option_field const *, char const *, void *);
int parse_json_uint(struct option_field const *, struct json_t *, void *);
#include "log.h"
#include "config/uint.h"
-static void
+void
print_uint32(struct option_field const *field, void *value)
{
pr_op_info("%s: %u", field->name, *((uint32_t *) value));
}
-static int
+int
parse_argv_uint32(struct option_field const *field, char const *str,
void *result)
{
return 0;
}
-static int
+int
parse_json_uint32(struct option_field const *opt, json_t *json, void *result)
{
unsigned int tmp;
extern const struct global_type gt_uint32;
+void print_uint32(struct option_field const *, void *);
+int parse_argv_uint32(struct option_field const *, char const *, void *);
+int parse_json_uint32(struct option_field const *, json_t *, void *);
+
#endif /* SRC_CONFIG_UINT32_H_ */
config_set_rsync_enabled(!DEREFERENCE(result));
config_set_rrdp_enabled(!DEREFERENCE(result));
+ config_set_http_enabled(!DEREFERENCE(result));
return 0;
}
config_set_rsync_enabled(!DEREFERENCE(result));
config_set_rrdp_enabled(!DEREFERENCE(result));
+ config_set_http_enabled(!DEREFERENCE(result));
return 0;
}
#include "http.h"
+#include <unistd.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include "common.h"
struct http_handler handler;
struct stat stat;
FILE *out;
+ unsigned int retries;
int error;
+ retries = 0;
*cond_met = 1;
- if (config_get_work_offline()) {
+ if (!config_get_http_enabled()) {
*response_code = 0; /* Not 200 code, but also not an error */
return 0;
}
if (error)
goto delete_dir;
- error = http_easy_init(&handler);
- if (error)
- goto close_file;
-
- /* Set "If-Modified-Since" header only if a value is specified */
- if (ims_value > 0) {
- curl_easy_setopt(handler.curl, CURLOPT_TIMEVALUE, ims_value);
- curl_easy_setopt(handler.curl, CURLOPT_TIMECONDITION,
- CURL_TIMECOND_IFMODSINCE);
- }
+ do {
+ error = http_easy_init(&handler);
+ if (error)
+ goto close_file;
+
+ /* Set "If-Modified-Since" header only if a value is specified */
+ if (ims_value > 0) {
+ curl_easy_setopt(handler.curl, CURLOPT_TIMEVALUE, ims_value);
+ curl_easy_setopt(handler.curl, CURLOPT_TIMECONDITION,
+ CURL_TIMECOND_IFMODSINCE);
+ }
+ error = http_fetch(&handler, uri_get_global(uri), response_code,
+ cond_met, log_operation, cb, out);
+ if (error != EREQFAILED)
+ break;
+
+ if (retries == config_get_http_retry_count()) {
+ pr_val_warn("Max HTTP retries (%u) reached requesting for '%s', won't retry again.",
+ retries, uri_get_global(uri));
+ break;
+ }
+ pr_val_warn("Retrying HTTP request '%s' in %u seconds, %u attempts remaining.",
+ uri_get_global(uri),
+ config_get_http_retry_interval(),
+ config_get_http_retry_count() - retries);
+ retries++;
+ http_easy_cleanup(&handler);
+ sleep(config_get_http_retry_interval());
+ } while (true);
- error = http_fetch(&handler, uri_get_global(uri), response_code,
- cond_met, log_operation, cb, out);
http_easy_cleanup(&handler);
file_close(out);
* care of that.
*/
(*retry_repo_sync) = true;
- if (sia_uris->rpkiNotify.uri == NULL || !config_get_rrdp_enabled()) {
+ if (sia_uris->rpkiNotify.uri == NULL || !config_get_http_enabled()) {
error = rsync_cb(sia_uris);
goto verify_mft;
}
}
/* Use CA's or configured priority? */
- if (config_get_rsync_priority() == config_get_rrdp_priority())
+ if (config_get_rsync_priority() == config_get_http_priority())
primary_rrdp = sia_uris->caRepository.position
> sia_uris->rpkiNotify.position;
else
primary_rrdp = config_get_rsync_priority()
- < config_get_rrdp_priority();
+ < config_get_http_priority();
cb_primary = primary_rrdp ? rrdp_cb : rsync_cb;
cb_secondary = primary_rrdp ? rsync_cb : rrdp_cb;
#include "rrdp/db/db_rrdp.h"
#define TAL_FILE_EXTENSION ".tal"
+typedef int (*foreach_uri_cb)(struct tal *, struct rpki_uri *, void *);
struct uris {
struct rpki_uri **array; /* This is an array of rpki URIs. */
unsigned int count;
unsigned int size;
+ unsigned int rsync_count;
+ unsigned int https_count;
};
struct tal {
uris_init(struct uris *uris)
{
uris->count = 0;
+ uris->rsync_count = 0;
+ uris->https_count = 0;
uris->size = 4; /* Most TALs only define one. */
uris->array = malloc(uris->size * sizeof(struct rpki_uri *));
- return (uris->array != NULL) ? 0 : -ENOMEM;
+ return (uris->array != NULL) ? 0 : pr_enomem();
}
static void
if (error)
return error;
+ if (uri_is_rsync(new))
+ uris->rsync_count++;
+ else
+ uris->https_count++;
+
if (uris->count + 1 >= uris->size) {
uris->size *= 2;
tmp = realloc(uris->array,
return 0;
}
-void
+static void
tal_shuffle_uris(struct tal *tal)
{
struct rpki_uri **array = tal->uris.array;
}
}
+static int
+tal_order_uris(struct tal *tal)
+{
+ struct rpki_uri **ordered;
+ struct rpki_uri **tmp;
+ bool http_first;
+ unsigned int i;
+ unsigned int last_rsync;
+ unsigned int last_https;
+
+ /* First do the shuffle */
+ if (config_get_shuffle_tal_uris())
+ tal_shuffle_uris(tal);
+
+ if (config_get_rsync_priority() == config_get_http_priority())
+ return 0;
+
+ /* Now order according to the priority */
+ http_first = (config_get_http_priority() > config_get_rsync_priority());
+
+ ordered = malloc(tal->uris.size * sizeof(struct rpki_uri *));
+ if (ordered == NULL)
+ return pr_enomem();
+
+ last_rsync = (http_first ? tal->uris.https_count : 0);
+ last_https = (http_first ? 0 : tal->uris.rsync_count);
+
+ for (i = 0; i < tal->uris.count; i++) {
+ if (uri_is_rsync(tal->uris.array[i]))
+ ordered[last_rsync++] = tal->uris.array[i];
+ else
+ ordered[last_https++] = tal->uris.array[i];
+ }
+
+ /* Everything is ok, point to the ordered array */
+ tmp = tal->uris.array;
+ tal->uris.array = ordered;
+ free(tmp);
+
+ return 0;
+}
+
char const *
tal_get_file_name(struct tal *tal)
{
error = download_files(uri, true, false);
break;
}
- /* FIXME (later) Should be 'config_get_http_enabled()' */
- if (config_get_work_offline())
+ if (!config_get_http_enabled())
return 0; /* Soft error */
error = handle_https_uri(uri);
} while (0);
if (error)
goto end;
- if (config_get_shuffle_tal_uris())
- tal_shuffle_uris(tal);
+ error = tal_order_uris(tal);
+ if (error)
+ goto destroy_tal;
+
error = foreach_uri(tal, __handle_tal_uri_sync, thread_arg);
if (error > 0) {
error = 0;
int tal_load(char const *, struct tal **);
void tal_destroy(struct tal *);
-typedef int (*foreach_uri_cb)(struct tal *, struct rpki_uri *, void *);
-int foreach_uri(struct tal *, foreach_uri_cb, void *);
-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 *);
bool log_operation;
int error, upd_error;
- if (!config_get_rrdp_enabled())
+ if (!config_get_http_enabled())
return 0;
/* Avoid multiple requests on the same run */
static int
download_file(struct rpki_uri *uri, long last_update, bool log_operation)
{
- unsigned int retries;
int error;
- retries = 0;
- do {
- if (last_update > 0)
- error = http_download_file_with_ims(uri, write_local,
- last_update, log_operation);
- else
- error = http_download_file(uri, write_local,
- log_operation);
+ if (last_update > 0)
+ error = http_download_file_with_ims(uri, write_local,
+ last_update, log_operation);
+ else
+ error = http_download_file(uri, write_local,
+ log_operation);
- /* Remember: positive values are expected */
- if (error >= 0)
- return error;
+ /*
+ * Since distinct files can be downloaded (notification, snapshot,
+ * delta) just return the error and let the caller to add only the
+ * update notification URI to the request errors DB.
+ */
+ if (error == -EREQFAILED)
+ return EREQFAILED;
- if (retries == config_get_rrdp_retry_count()) {
- pr_val_warn("Max RRDP retries (%u) reached fetching '%s', won't retry again.",
- retries, uri_get_global(uri));
- /*
- * Since distinct files can be downloaded (notification,
- * snapshot, delta) just return the error and let the
- * caller to add only the update notification URI to
- * the request errors DB.
- */
- return EREQFAILED;
- }
- pr_val_warn("Retrying RRDP file download '%s' in %u seconds, %u attempts remaining.",
- uri_get_global(uri),
- config_get_rrdp_retry_interval(),
- config_get_rrdp_retry_count() - retries);
- retries++;
- sleep(config_get_rrdp_retry_interval());
- } while (true);
+ /* Remember: positive values are expected */
+ return error;
}
/* Left trim @from, setting the result at @result pointer */
static char addr_buffer1[INET6_ADDRSTRLEN];
static char addr_buffer2[INET6_ADDRSTRLEN];
+static unsigned int http_priority = 60;
+static unsigned int rsync_priority = 50;
+
char const *
v4addr2str(struct in_addr const *addr)
{
unsigned int
config_get_rsync_priority(void)
{
- return 50;
+ return rsync_priority;
}
bool
-config_get_rrdp_enabled(void)
+config_get_http_enabled(void)
{
return false;
}
unsigned int
-config_get_rrdp_priority(void)
+config_get_http_priority(void)
{
- return 50;
+ return http_priority;
}
bool
{
return NULL;
}
+
+void
+config_set_rsync_priority(unsigned int value)
+{
+ rsync_priority = value;
+}
+
+void
+config_set_http_priority(unsigned int value)
+{
+ http_priority = value;
+}
}
END_TEST
+START_TEST(tal_order_http_first)
+{
+ struct tal *tal;
+
+ ck_assert_int_eq(tal_load("tal/lacnic.tal", &tal), 0);
+
+ config_set_http_priority(60);
+ config_set_rsync_priority(50);
+ ck_assert_int_eq(tal_order_uris(tal), 0);
+
+ ck_assert_str_eq(tal->uris.array[0]->global, "https://potato");
+ ck_assert_str_eq(tal->uris.array[1]->global,
+ "rsync://repository.lacnic.net/rpki/lacnic/rta-lacnic-rpki.cer");
+ ck_assert_str_eq(tal->uris.array[2]->global, "rsync://potato");
+
+ tal_destroy(tal);
+}
+END_TEST
+
+START_TEST(tal_order_http_last)
+{
+ struct tal *tal;
+
+ ck_assert_int_eq(tal_load("tal/lacnic.tal", &tal), 0);
+
+ config_set_http_priority(50);
+ config_set_rsync_priority(60);
+ ck_assert_int_eq(tal_order_uris(tal), 0);
+
+ ck_assert_str_eq(tal->uris.array[0]->global,
+ "rsync://repository.lacnic.net/rpki/lacnic/rta-lacnic-rpki.cer");
+ ck_assert_str_eq(tal->uris.array[1]->global, "rsync://potato");
+ ck_assert_str_eq(tal->uris.array[2]->global, "https://potato");
+
+ tal_destroy(tal);
+}
+END_TEST
+
Suite *tal_load_suite(void)
{
Suite *suite;
- TCase *core;
+ TCase *core, *order;
core = tcase_create("Core");
tcase_add_test(core, tal_load_normal);
- suite = suite_create("lfile_read()");
+ order = tcase_create("Order");
+ tcase_add_test(order, tal_order_http_first);
+ tcase_add_test(order, tal_order_http_last);
+
+ suite = suite_create("tal_load()");
suite_add_tcase(suite, core);
+ suite_add_tcase(suite, order);
return suite;
}