+The new configuration properties are: 'rsync.enabled', 'rsync.priority', 'rsync.strategy', 'rrdp.enabled', 'rrdp.priority', and 'work-offline'.
+'sync-strategy' will be deprecated but still it can be set. Whenever is set, its value will be set to 'rsync.priority'.
+Fix possible bug at 'visited_uris', a nul char was being set at a wrong location.
+Consider configured priorities and enabled flags whenever an access method is utilized while processing certificates.
+Boolean configuration parameters value can now be set also at command line, using the syntax '--key=value'.
+Remove 'http.disabled' and 'rrdp-disabled', they aren't needed anymore.
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/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
fort_SOURCES += config/sync_strategy.h config/sync_strategy.c
fort_SOURCES += config/types.h
fort_SOURCES += config/uint.c config/uint.h
fort_SOURCES += config/uint32.c config/uint32.h
+fort_SOURCES += config/work_offline.c config/work_offline.h
fort_SOURCES += crypto/base64.h crypto/base64.c
fort_SOURCES += crypto/hash.h crypto/hash.c
#include "config/boolean.h"
#include "config/incidences.h"
#include "config/str.h"
+#include "config/sync_strategy.h"
#include "config/uint.h"
#include "config/uint32.h"
+#include "config/work_offline.h"
/**
* To add a member to this structure,
char *tal;
/** Path of our local clone of the repository */
char *local_repository;
- /** Synchronization (currently only RSYNC) download strategy. */
- enum sync_strategy sync_strategy;
- /* Disable RRDP file processing */
- bool rrdp_disabled;
+ /** FIXME (later) Deprecated, remove it. RSYNC download strategy. */
+ enum rsync_strategy sync_strategy;
/**
* Handle TAL URIs in random order?
* (https://tools.ietf.org/html/rfc8630#section-3, last
char *slurm;
/* Run as RTR server or standalone validation */
enum mode mode;
+ /*
+ * Disable outgoing requests (currently rsync and http supported), if
+ * 'true' uses only local files located at local-repository.
+ */
+ bool work_offline;
struct {
/** The bound listening address of the RTR server. */
} server;
struct {
+ /* Enables the protocol */
+ bool enabled;
+ /*
+ * Priority, this will override the order set at the CAs in
+ * their accessMethod extension.
+ */
+ unsigned int priority;
+ /* Synchronization download strategy. */
+ enum rsync_strategy strategy;
char *program;
struct {
struct string_array flat;
} args;
} rsync;
+ struct {
+ /* Enables the protocol */
+ bool enabled;
+ /*
+ * Priority, this will override the order set at the CAs in
+ * their accessMethod extension.
+ */
+ unsigned int priority;
+ } rrdp;
+
struct {
/* User-Agent header set at requests */
char *user_agent;
unsigned int transfer_timeout;
/* Directory where CA certs to verify peers are found */
char *ca_path;
- /*
- * Disable HTTP requests, if 'true' uses local files located at
- * local-repository.
- */
- bool disabled;
} http;
struct {
.name = "sync-strategy",
.type = >_sync_strategy,
.offset = offsetof(struct rpki_config, sync_strategy),
- .doc = "RSYNC download strategy",
- }, {
- .id = 2000,
- .name = "rrdp-disabled",
- .type = >_bool,
- .offset = offsetof(struct rpki_config, rrdp_disabled),
- .doc = "Disable RRDP file(s) processing",
+ .doc = "RSYNC download strategy. Will be deprecated, use 'rsync.strategy' instead.",
}, {
.id = 2001,
.name = "shuffle-uris",
.type = >_mode,
.offset = offsetof(struct rpki_config, mode),
.doc = "Run mode: 'server' (run as RTR server), 'standalone' (run validation once and exit)",
+ }, {
+ .id = 1005,
+ .name = "work-offline",
+ .type = >_work_offline,
+ .offset = offsetof(struct rpki_config, work_offline),
+ .doc = "Disable all outgoing requests (rsync, http (implies RRDP)) and work only with local repository files.",
},
/* Server fields */
/* RSYNC fields */
{
.id = 3000,
+ .name = "rsync.enabled",
+ .type = >_bool,
+ .offset = offsetof(struct rpki_config, rsync.enabled),
+ .doc = "Enables RSYNC execution",
+ }, {
+ .id = 3001,
+ .name = "rsync.priority",
+ .type = >_uint32,
+ .offset = offsetof(struct rpki_config, rsync.priority),
+ .doc = "Priority of execution to fetch repositories files, a higher value means higher priority",
+ .min = 0,
+ .max = 100,
+ },{
+ .id = 3002,
+ .name = "rsync.strategy",
+ .type = >_rsync_strategy,
+ .offset = offsetof(struct rpki_config, rsync.strategy),
+ .doc = "RSYNC download strategy",
+ },{
+ .id = 3003,
.name = "rsync.program",
.type = >_string,
.offset = offsetof(struct rpki_config, rsync.program),
.arg_doc = "<path to program>",
.availability = AVAILABILITY_JSON,
}, {
- .id = 3001,
+ .id = 3004,
.name = "rsync.arguments-recursive",
.type = >_string_array,
.offset = offsetof(struct rpki_config, rsync.args.recursive),
.doc = "RSYNC program arguments that will trigger a recursive RSYNC",
.availability = AVAILABILITY_JSON,
}, {
- .id = 3002,
+ .id = 3005,
.name = "rsync.arguments-flat",
.type = >_string_array,
.offset = offsetof(struct rpki_config, rsync.args.flat),
.availability = AVAILABILITY_JSON,
},
+ /* RRDP fields */
+ {
+ .id = 10000,
+ .name = "rrdp.enabled",
+ .type = >_bool,
+ .offset = offsetof(struct rpki_config, rrdp.enabled),
+ .doc = "Enables RRDP execution",
+ }, {
+ .id = 10001,
+ .name = "rrdp.priority",
+ .type = >_uint32,
+ .offset = offsetof(struct rpki_config, rrdp.priority),
+ .doc = "Priority of execution to fetch repositories files, a higher value means higher priority",
+ .min = 0,
+ .max = 100,
+ },
+
/* HTTP requests parameters */
{
.id = 9000,
.doc = "Directory where CA certificates are found, used to verify the peer",
.arg_doc = "<directory>",
},
- {
- .id = 9004,
- .name = "http.disabled",
- .type = >_bool,
- .offset = offsetof(struct rpki_config, http.disabled),
- .doc = "Enable or disable HTTP requests",
- },
/* Logging fields */
{
goto revert_port;
}
- rpki_config.rrdp_disabled = false;
- rpki_config.sync_strategy = SYNC_ROOT;
+ rpki_config.sync_strategy = RSYNC_ROOT;
rpki_config.shuffle_tal_uris = false;
rpki_config.maximum_certificate_depth = 32;
rpki_config.mode = SERVER;
+ rpki_config.work_offline = false;
+ rpki_config.rsync.enabled = true;
+ rpki_config.rsync.priority = 50;
+ rpki_config.rsync.strategy = RSYNC_ROOT;
rpki_config.rsync.program = strdup("rsync");
if (rpki_config.rsync.program == NULL) {
error = pr_enomem();
if (error)
goto revert_recursive_array;
+ rpki_config.rrdp.enabled = true;
+ rpki_config.rrdp.priority = 50;
+
rpki_config.http.user_agent = strdup(PACKAGE_NAME "/" PACKAGE_VERSION);
if (rpki_config.http.user_agent == NULL) {
error = pr_enomem();
- goto revert_recursive_array;
+ goto revert_flat_array;
}
rpki_config.http.connect_timeout = 30;
rpki_config.http.transfer_timeout = 30;
rpki_config.http.ca_path = NULL; /* Use system default */
- rpki_config.http.disabled = false;
rpki_config.log.color = false;
rpki_config.log.filename_format = FNF_GLOBAL;
rpki_config.asn1_decode_max_stack = 4096; /* 4kB */
return 0;
-
+revert_flat_array:
+ string_array_cleanup(&rpki_config.rsync.args.flat);
revert_recursive_array:
string_array_cleanup(&rpki_config.rsync.args.recursive);
revert_rsync_program:
if (rpki_config.output.bgpsec != NULL &&
!valid_output_file(rpki_config.output.bgpsec))
- return pr_err("Invalid output.bgpsec file.");
+ return pr_err("Invalid output.bgpsec file.");
return (rpki_config.tal != NULL)
? 0
return rpki_config.server.backlog;
}
+bool
+config_get_work_offline(void)
+{
+ return rpki_config.work_offline;
+}
+
unsigned int
config_get_validation_interval(void)
{
return rpki_config.local_repository;
}
-enum sync_strategy
-config_get_sync_strategy(void)
-{
- return rpki_config.sync_strategy;
-}
-
-bool
-config_get_rrdp_disabled(void)
-{
- return rpki_config.rrdp_disabled;
-}
-
bool
config_get_shuffle_tal_uris(void)
{
return rpki_config.log.output;
}
+bool
+config_get_rsync_enabled(void)
+{
+ return rpki_config.rsync.enabled;
+}
+
+unsigned int
+config_get_rsync_priority(void)
+{
+ return rpki_config.rsync.priority;
+}
+
+enum rsync_strategy
+config_get_rsync_strategy(void)
+{
+ return rpki_config.rsync.strategy;
+}
+
char *
config_get_rsync_program(void)
{
struct string_array const *
config_get_rsync_args(bool is_ta)
{
- switch (rpki_config.sync_strategy) {
- case SYNC_ROOT:
+ switch (rpki_config.rsync.strategy) {
+ case RSYNC_ROOT:
return &rpki_config.rsync.args.recursive;
- case SYNC_ROOT_EXCEPT_TA:
+ case RSYNC_ROOT_EXCEPT_TA:
return is_ta
? &rpki_config.rsync.args.flat
: &rpki_config.rsync.args.recursive;
- case SYNC_STRICT:
+ case RSYNC_STRICT:
return &rpki_config.rsync.args.flat;
- case SYNC_OFF:
+ default:
break;
}
- pr_crit("Invalid sync strategy: '%u'", rpki_config.sync_strategy);
+ pr_crit("Invalid rsync strategy: '%u'", rpki_config.rsync.strategy);
+}
+
+bool
+config_get_rrdp_enabled(void)
+{
+ return rpki_config.rrdp.enabled;
+}
+
+unsigned int
+config_get_rrdp_priority(void)
+{
+ return rpki_config.rrdp.priority;
}
char const *
return rpki_config.http.ca_path;
}
-bool
-config_get_http_disabled(void)
-{
- return rpki_config.http.disabled;
-}
-
char const *
config_get_output_roa(void)
{
return rpki_config.asn1_decode_max_stack;
}
+void
+config_set_rsync_enabled(bool value)
+{
+ rpki_config.rsync.enabled = value;
+}
+
+void
+config_set_rrdp_enabled(bool value)
+{
+ rpki_config.rrdp.enabled = value;
+}
+
void
free_rpki_config(void)
{
#include "config/filename_format.h"
#include "config/log_conf.h"
#include "config/mode.h"
-#include "config/sync_strategy.h"
+#include "config/rsync_strategy.h"
#include "config/string_array.h"
#include "config/types.h"
char const *config_get_tal(void);
char const *config_get_local_repository(void);
-enum sync_strategy config_get_sync_strategy(void);
-bool config_get_rrdp_disabled(void);
bool config_get_shuffle_tal_uris(void);
unsigned int config_get_max_cert_depth(void);
enum mode config_get_mode(void);
+bool config_get_work_offline(void);
bool config_get_color_output(void);
enum filename_format config_get_filename_format(void);
char const *config_get_http_user_agent(void);
unsigned int config_get_http_connect_timeout(void);
unsigned int config_get_http_transfer_timeout(void);
char const *config_get_http_ca_path(void);
-bool config_get_http_disabled(void);
uint8_t config_get_log_level(void);
enum log_output config_get_log_output(void);
+bool config_get_rsync_enabled(void);
+unsigned int config_get_rsync_priority(void);
+enum rsync_strategy config_get_rsync_strategy(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);
char const *config_get_output_roa(void);
char const *config_get_output_bgpsec(void);
unsigned int config_get_asn1_decode_max_stack(void);
+/*
+ * Public, so that work-offline can set them, or (to be deprecated)
+ * sync-strategy when set to 'off'.
+ */
+void config_set_rsync_enabled(bool);
+void config_set_rrdp_enabled(bool);
+
/* Needed public by the JSON module */
void *get_rpki_config_field(struct option_field const *);
struct option_field const *get_option_metadatas(void);
#define DEREFERENCE(void_value) (*((bool *) void_value))
-static void
+void
print_bool(struct option_field const *field, void *value)
{
pr_info("%s: %s", field->name, DEREFERENCE(value) ? "true" : "false");
}
-static int
+int
parse_argv_bool(struct option_field const *field, char const *str, void *result)
{
- if (str == NULL) {
+ if (str == NULL || strlen(str) == 0) {
DEREFERENCE(result) = true;
return 0;
}
return pr_err("Cannot parse '%s' as a bool (true|false).", str);
}
-static int
+int
parse_json_bool(struct option_field const *opt, struct json_t *json,
void *result)
{
}
const struct global_type gt_bool = {
- .has_arg = no_argument,
+ .has_arg = optional_argument,
.size = sizeof(bool),
.print = print_bool,
.parse.argv = parse_argv_bool,
extern const struct global_type gt_bool;
+void print_bool(struct option_field const *, void *);
+int parse_argv_bool(struct option_field const *, char const *, void *);
+int parse_json_bool(struct option_field const *, struct json_t *, void *);
+
#endif /* SRC_CONFIG_BOOLEAN_H_ */
--- /dev/null
+#include "config/rsync_strategy.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "log.h"
+#include "config/str.h"
+
+#define RSYNC_VALUE_STRICT "strict"
+#define RSYNC_VALUE_ROOT "root"
+#define RSYNC_VALUE_ROOT_EXCEPT_TA "root-except-ta"
+
+#define DEREFERENCE(void_value) (*((enum rsync_strategy *) void_value))
+
+#ifdef ENABLE_STRICT_STRATEGY
+#define PRINT_STRICT_ARG_DOC "|" RSYNC_VALUE_STRICT
+#define HANDLE_RSYNC_STRICT DEREFERENCE(result) = RSYNC_STRICT;
+#else
+#define PRINT_STRICT_ARG_DOC
+#define HANDLE_RSYNC_STRICT \
+ return pr_err("Unknown rsync synchronization strategy: '%s'. In order to use it, recompile using flag ENABLE_STRICT_STRATEGY.",\
+ str);
+#endif
+
+void
+print_rsync_strategy(struct option_field const *field, void *value)
+{
+ char const *str = "<unknown>";
+
+ switch (DEREFERENCE(value)) {
+ case RSYNC_STRICT:
+ str = RSYNC_VALUE_STRICT;
+ break;
+ case RSYNC_ROOT:
+ str = RSYNC_VALUE_ROOT;
+ break;
+ case RSYNC_ROOT_EXCEPT_TA:
+ str = RSYNC_VALUE_ROOT_EXCEPT_TA;
+ break;
+ default:
+ break;
+ }
+
+ pr_info("%s: %s", field->name, str);
+}
+
+int
+parse_argv_rsync_strategy(struct option_field const *field, char const *str,
+ void *result)
+{
+ if (strcmp(str, RSYNC_VALUE_STRICT) == 0)
+ HANDLE_RSYNC_STRICT
+ else if (strcmp(str, RSYNC_VALUE_ROOT) == 0)
+ DEREFERENCE(result) = RSYNC_ROOT;
+ else if (strcmp(str, RSYNC_VALUE_ROOT_EXCEPT_TA) == 0)
+ DEREFERENCE(result) = RSYNC_ROOT_EXCEPT_TA;
+ else
+ return pr_err("Unknown rsync synchronization strategy: '%s'",
+ str);
+
+ return 0;
+}
+
+int
+parse_json_rsync_strategy(struct option_field const *opt, struct json_t *json,
+ void *result)
+{
+ char const *string;
+ int error;
+
+ error = parse_json_string(json, opt->name, &string);
+ return error ? error : parse_argv_rsync_strategy(opt, string, result);
+}
+
+const struct global_type gt_rsync_strategy = {
+ .has_arg = required_argument,
+ .size = sizeof(enum rsync_strategy),
+ .print = print_rsync_strategy,
+ .parse.argv = parse_argv_rsync_strategy,
+ .parse.json = parse_json_rsync_strategy,
+ .arg_doc = RSYNC_VALUE_ROOT
+ "|" RSYNC_VALUE_ROOT_EXCEPT_TA
+ PRINT_STRICT_ARG_DOC,
+};
--- /dev/null
+#ifndef SRC_CONFIG_RSYNC_STRATEGY_H_
+#define SRC_CONFIG_RSYNC_STRATEGY_H_
+
+#include "config/types.h"
+
+enum rsync_strategy {
+ /*
+ * FIXME (later) Deprecated. Still alive so that 'sync-strategy' and
+ * 'rsync.strategy' can live together.
+ *
+ * 'sync-strategy' type must handle this value to set 'rsync.enabled'
+ * as 'false'.
+ */
+ RSYNC_OFF,
+ /**
+ * Strictly correct download strategy.
+ *
+ * The validator will sync each repository publication point separately
+ * as requested by each caRepository contained in the CA certificates'
+ * SIA extensions.
+ *
+ * No risk of downloading unneeded files, but otherwise slow, as every
+ * different repository publication point requires a separate sync call.
+ *
+ * In order to enable this strategy, compile using the flag:
+ * ENABLE_STRICT_STRATEGY
+ */
+ RSYNC_STRICT,
+ /**
+ * Always download the likely root of the entire repository.
+ *
+ * For example, if we get the following caRepositories:
+ *
+ * - `rsync://a.b.c/d/e/f/g/h/i`
+ * - `rsync://a.b.c/d/e/f/g/h/j`
+ * - `rsync://a.b.c/d/e/f/k`
+ *
+ * This strategy will synchronize `rsync://a.b.c/d` while parsing the
+ * first caRepository, and then skip synchronization during the second
+ * and third ones. (Because they are already downloaded.)
+ *
+ * This strategy risks downloading unneeded files, and even failing due
+ * to lack of read permissions on stray subdirectories. On the flip
+ * side, if the repository holds no unnecessary subdirectories, then
+ * this strategy is the fastest one, since it generally only requires
+ * one sync call per domain, which often translates into one sync call
+ * per validation cycle.
+ *
+ * Currently, all of the official repositories are actually specifically
+ * structured to benefit this strategy.
+ */
+ RSYNC_ROOT,
+ /**
+ * Same as SYNC_ROOT, except the root certificate is synchronized
+ * separately.
+ * (Either because it's in a separate directory, or because we don't
+ * want to download its entire repository until we've verified its
+ * legitimacy and integrity.)
+ */
+ RSYNC_ROOT_EXCEPT_TA,
+};
+
+extern const struct global_type gt_rsync_strategy;
+
+/*
+ * FIXME (later) Public to live along with 'sync-strategy', return them to
+ * private whenever 'sync-strategy' is deleted.
+ */
+void print_rsync_strategy(struct option_field const *, void *);
+int parse_argv_rsync_strategy(struct option_field const *, char const *,
+ void *);
+int parse_json_rsync_strategy(struct option_field const *, struct json_t *,
+ void *);
+
+#endif /* SRC_CONFIG_RSYNC_STRATEGY_H_ */
#include <stdlib.h>
#include <string.h>
+#include "config.h"
#include "log.h"
#include "config/str.h"
+#include "config/rsync_strategy.h"
-#define SYNC_VALUE_OFF "off"
-#define SYNC_VALUE_STRICT "strict"
-#define SYNC_VALUE_ROOT "root"
-#define SYNC_VALUE_ROOT_EXCEPT_TA "root-except-ta"
+/*
+ * Yeap, all of this is duplicated, better remove it with the whole source file
+ * whenever sync-strategy isn't supported anymore.
+ */
-#define DEREFERENCE(void_value) (*((enum sync_strategy *) void_value))
+#define RSYNC_VALUE_OFF "off"
+#define RSYNC_VALUE_STRICT "strict"
+#define RSYNC_VALUE_ROOT "root"
+#define RSYNC_VALUE_ROOT_EXCEPT_TA "root-except-ta"
+
+#define DEREFERENCE(void_value) (*((enum rsync_strategy *) void_value))
#ifdef ENABLE_STRICT_STRATEGY
-#define PRINT_STRICT_ARG_DOC "|" SYNC_VALUE_STRICT
-#define HANDLE_SYNC_STRICT DEREFERENCE(result) = SYNC_STRICT;
+#define PRINT_STRICT_ARG_DOC "|" RSYNC_VALUE_STRICT
+#define HANDLE_RSYNC_STRICT DEREFERENCE(result) = RSYNC_STRICT;
#else
#define PRINT_STRICT_ARG_DOC
-#define HANDLE_SYNC_STRICT \
+#define HANDLE_RSYNC_STRICT \
return pr_err("Unknown synchronization strategy: '%s'. In order to use it, recompile using flag ENABLE_STRICT_STRATEGY.",\
str);
#endif
static void
print_sync_strategy(struct option_field const *field, void *value)
{
- char const *str = "<unknown>";
-
- switch (DEREFERENCE(value)) {
- case SYNC_OFF:
- str = SYNC_VALUE_OFF;
- break;
- case SYNC_STRICT:
- str = SYNC_VALUE_STRICT;
- break;
- case SYNC_ROOT:
- str = SYNC_VALUE_ROOT;
- break;
- case SYNC_ROOT_EXCEPT_TA:
- str = SYNC_VALUE_ROOT_EXCEPT_TA;
- break;
+ if (DEREFERENCE(value) == RSYNC_OFF) {
+ pr_info("%s: %s", field->name, RSYNC_VALUE_OFF);
+ return;
}
- pr_info("%s: %s", field->name, str);
+ print_rsync_strategy(field, value);
}
static int
parse_argv_sync_strategy(struct option_field const *field, char const *str,
void *result)
{
- if (strcmp(str, SYNC_VALUE_OFF) == 0)
- DEREFERENCE(result) = SYNC_OFF;
- else if (strcmp(str, SYNC_VALUE_STRICT) == 0)
- HANDLE_SYNC_STRICT
- else if (strcmp(str, SYNC_VALUE_ROOT) == 0)
- DEREFERENCE(result) = SYNC_ROOT;
- else if (strcmp(str, SYNC_VALUE_ROOT_EXCEPT_TA) == 0)
- DEREFERENCE(result) = SYNC_ROOT_EXCEPT_TA;
- else
- return pr_err("Unknown synchronization strategy: '%s'", str);
+ pr_warn("'sync-strategy' will be deprecated.");
+ pr_warn("Use 'rsync.strategy' instead; or 'rsync.enabled=false' if you wish to use 'off' strategy.");
+
+ if (strcmp(str, RSYNC_VALUE_OFF) == 0) {
+ DEREFERENCE(result) = RSYNC_OFF;
+ config_set_rsync_enabled(false);
+ return 0;
+ }
- return 0;
+ return parse_argv_rsync_strategy(field, str, result);
}
static int
const struct global_type gt_sync_strategy = {
.has_arg = required_argument,
- .size = sizeof(enum sync_strategy),
+ .size = sizeof(enum rsync_strategy),
.print = print_sync_strategy,
.parse.argv = parse_argv_sync_strategy,
.parse.json = parse_json_sync_strategy,
- .arg_doc = SYNC_VALUE_OFF
- PRINT_STRICT_ARG_DOC
- "|" SYNC_VALUE_ROOT
- "|" SYNC_VALUE_ROOT_EXCEPT_TA,
+ .arg_doc = RSYNC_VALUE_OFF
+ "|" RSYNC_VALUE_ROOT
+ "|" RSYNC_VALUE_ROOT_EXCEPT_TA
+ PRINT_STRICT_ARG_DOC,
};
#include "config/types.h"
-/**
- * Note: The only repository synchronization protocol implemented so far is
- * RSYNC. Whenever you see "sync", think "rsync."
- */
-enum sync_strategy {
- /**
- * Synchronization is turned off.
- * The validator will work on an already downloaded repository.
- */
- SYNC_OFF,
- /**
- * Strictly correct download strategy.
- *
- * The validator will sync each repository publication point separately
- * as requested by each caRepository contained in the CA certificates'
- * SIA extensions.
- *
- * No risk of downloading unneeded files, but otherwise slow, as every
- * different repository publication point requires a separate sync call.
- *
- * In order to enable this strategy, compile using the flag:
- * ENABLE_STRICT_STRATEGY
- */
- SYNC_STRICT,
- /**
- * Always download the likely root of the entire repository.
- *
- * For example, if we get the following caRepositories:
- *
- * - `rsync://a.b.c/d/e/f/g/h/i`
- * - `rsync://a.b.c/d/e/f/g/h/j`
- * - `rsync://a.b.c/d/e/f/k`
- *
- * This strategy will synchronize `rsync://a.b.c/d` while parsing the
- * first caRepository, and then skip synchronization during the second
- * and third ones. (Because they are already downloaded.)
- *
- * This strategy risks downloading unneeded files, and even failing due
- * to lack of read permissions on stray subdirectories. On the flip
- * side, if the repository holds no unnecessary subdirectories, then
- * this strategy is the fastest one, since it generally only requires
- * one sync call per domain, which often translates into one sync call
- * per validation cycle.
- *
- * Currently, all of the official repositories are actually specifically
- * structured to benefit this strategy.
- */
- SYNC_ROOT,
- /**
- * Same as SYNC_ROOT, except the root certificate is synchronized
- * separately.
- * (Either because it's in a separate directory, or because we don't
- * want to download its entire repository until we've verified its
- * legitimacy and integrity.)
- */
- SYNC_ROOT_EXCEPT_TA,
-};
-
extern const struct global_type gt_sync_strategy;
#endif /* SRC_CONFIG_SYNC_STRATEGY_H_ */
--- /dev/null
+#include "config/work_offline.h"
+
+#include <getopt.h>
+#include <stdbool.h>
+
+#include "config.h"
+#include "config/boolean.h"
+
+#define DEREFERENCE(void_value) (*((bool *) void_value))
+
+static int
+parse_argv_offline(struct option_field const *field, char const *str, void *result)
+{
+ int error;
+
+ error = parse_argv_bool(field, str, result);
+ if (error)
+ return error;
+
+ config_set_rsync_enabled(!DEREFERENCE(result));
+ config_set_rrdp_enabled(!DEREFERENCE(result));
+
+ return 0;
+}
+
+static int
+parse_json_offline(struct option_field const *opt, struct json_t *json,
+ void *result)
+{
+ int error;
+
+ error = parse_json_bool(opt, json, result);
+ if (error)
+ return error;
+
+ config_set_rsync_enabled(!DEREFERENCE(result));
+ config_set_rrdp_enabled(!DEREFERENCE(result));
+
+ return 0;
+}
+
+const struct global_type gt_work_offline = {
+ .has_arg = optional_argument,
+ .size = sizeof(bool),
+ .print = print_bool,
+ .parse.argv = parse_argv_offline,
+ .parse.json = parse_json_offline,
+ .arg_doc = "true|false",
+};
--- /dev/null
+#ifndef SRC_CONFIG_WORK_OFFLINE_H_
+#define SRC_CONFIG_WORK_OFFLINE_H_
+
+extern const struct global_type gt_work_offline;
+
+#endif /* SRC_CONFIG_WORK_OFFLINE_H_ */
FILE *out;
int error;
- if (config_get_http_disabled()) {
+ if (config_get_work_offline()) {
response_code = 0; /* Not 200 code, but also not an error */
return 0;
}
/*
* RSYNC will always be present (at least for now, see
- * rfc6487#section-4.8.8.1)
+ * rfc6487#section-4.8.8.1). If rsync is disabled, the cb will take
+ * care of that.
*/
- if (sia_uris->rpkiNotify.uri == NULL || config_get_rrdp_disabled())
+ if (sia_uris->rpkiNotify.uri == NULL || !config_get_rrdp_enabled())
return rsync_cb(sia_uris);
- /* Get the preferred */
- if (sia_uris->caRepository.position > sia_uris->rpkiNotify.position) {
- cb_primary = rrdp_cb;
- cb_secondary = rsync_cb;
- primary_rrdp = true;
- } else {
- cb_primary = rsync_cb;
- cb_secondary = rrdp_cb;
- primary_rrdp = false;
- }
+ /* RSYNC disabled, and RRDP is present, use it */
+ if (!config_get_rsync_enabled())
+ return rrdp_cb(sia_uris);
+
+ /* Use CA's or configured priority? */
+ if (config_get_rsync_priority() == config_get_rrdp_priority())
+ primary_rrdp = sia_uris->caRepository.position
+ > sia_uris->rpkiNotify.position;
+ else
+ primary_rrdp = config_get_rsync_priority()
+ < config_get_rrdp_priority();
+
+ cb_primary = primary_rrdp ? rrdp_cb : rsync_cb;
+ cb_secondary = primary_rrdp ? rsync_cb : rrdp_cb;
/* Try with the preferred; in case of error, try with the next one */
error = cb_primary(sia_uris);
#include "rrdp/db/db_rrdp_uris.h"
#include "rrdp/rrdp_objects.h"
#include "rrdp/rrdp_parser.h"
+#include "config.h"
#include "log.h"
#include "thread_var.h"
#include "visited_uris.h"
int error;
bool requested;
+ if (!config_get_rrdp_enabled())
+ return 0;
+
/* Avoid multiple requests on the same run */
requested = false;
error = db_rrdp_uris_get_requested(uri_get_global(uri), &requested);
string_tokenizer_init(&descendant_tokenizer, uri_get_global(descendant),
uri_get_global_len(descendant), '/');
- if (config_get_sync_strategy() == SYNC_STRICT)
+ if (config_get_rsync_strategy() == RSYNC_STRICT)
return strcmp(uri_get_global(ancestor),
uri_get_global(descendant)) == 0;
get_rsync_uri(struct rpki_uri *requested_uri, bool is_ta,
struct rpki_uri **rsync_uri)
{
- switch (config_get_sync_strategy()) {
- case SYNC_ROOT:
+ switch (config_get_rsync_strategy()) {
+ case RSYNC_ROOT:
return handle_root_strategy(requested_uri, rsync_uri);
- case SYNC_ROOT_EXCEPT_TA:
+ case RSYNC_ROOT_EXCEPT_TA:
return is_ta
? handle_strict_strategy(requested_uri, rsync_uri)
: handle_root_strategy(requested_uri, rsync_uri);
- case SYNC_STRICT:
+ case RSYNC_STRICT:
return handle_strict_strategy(requested_uri, rsync_uri);
- case SYNC_OFF:
+ default:
break;
}
- pr_crit("Invalid sync strategy: %u", config_get_sync_strategy());
+ pr_crit("Invalid rsync strategy: %u", config_get_rsync_strategy());
}
static void
* Note:
* @requested_uri is the URI we were asked to RSYNC.
* @rsync_uri is the URL we're actually going to RSYNC.
- * (They can differ, depending on config_get_sync_strategy().)
+ * (They can differ, depending on config_get_rsync_strategy().)
*/
struct validation *state;
struct uri_list *visited_uris;
struct rpki_uri *rsync_uri;
int error;
- if (config_get_sync_strategy() == SYNC_OFF)
+ if (!config_get_rsync_enabled())
return 0;
state = state_retrieve();
return pr_enomem();
strncpy(tmp, elem->uri, size);
- tmp[size + 1] = '\0';
+ tmp[size] = '\0';
*result = tmp;
return 0;
return "repository/";
}
-enum sync_strategy
-config_get_sync_strategy(void)
+enum rsync_strategy
+config_get_rsync_strategy(void)
{
- return SYNC_ROOT;
+ return RSYNC_ROOT;
}
bool
-config_get_rrdp_disabled(void)
+config_get_rsync_enabled(void)
{
return true;
}
+unsigned int
+config_get_rsync_priority(void)
+{
+ return 50;
+}
+
+bool
+config_get_rrdp_enabled(void)
+{
+ return false;
+}
+
+unsigned int
+config_get_rrdp_priority(void)
+{
+ return 50;
+}
+
+bool
+config_get_work_offline(void)
+{
+ return false;
+}
+
bool
config_get_color_output(void)
{
char const *
config_get_http_user_agent(void)
{
- return "Test/0.1";
+ return "fort-test/0.1";
}
unsigned int
{
return NULL;
}
-
-bool
-config_get_http_disabled(void)
-{
- return true;
-}