]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Move rrdp.* args to http.* configurations
authorpcarana <pc.moreno2099@gmail.com>
Thu, 23 Jul 2020 16:46:10 +0000 (11:46 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Thu, 23 Jul 2020 16:46:10 +0000 (11:46 -0500)
+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.

18 files changed:
src/Makefile.am
src/config.c
src/config.h
src/config/rrdp_conf.c [new file with mode: 0644]
src/config/rrdp_conf.h [new file with mode: 0644]
src/config/uint.c
src/config/uint.h
src/config/uint32.c
src/config/uint32.h
src/config/work_offline.c
src/http/http.c
src/object/certificate.c
src/object/tal.c
src/object/tal.h
src/rrdp/rrdp_loader.c
src/rrdp/rrdp_parser.c
test/impersonator.c
test/tal_test.c

index b03cb514ec1a69435de933aff2d0c536c5b48865..ccf10fc8cd31415b06ac5dd4b3c289c34baddc11 100644 (file)
@@ -47,6 +47,7 @@ fort_SOURCES += config/filename_format.h config/filename_format.c
 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
index c8b358e8a30cddb9130b5b8b5a8f82b9abce9254..2d03935ee3a0393a1f4a863b463fbdedfd698ad3 100644 (file)
@@ -15,6 +15,7 @@
 #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"
@@ -118,6 +119,22 @@ struct rpki_config {
        } 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 */
@@ -457,31 +474,31 @@ static const struct option_field options[] = {
        {
                .id = 10000,
                .name = "rrdp.enabled",
-               .type = &gt_bool,
+               .type = &gt_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 = &gt_uint32,
+               .type = &gt_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 = &gt_uint,
+               .type = &gt_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 = &gt_uint,
+               .type = &gt_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,
        },
@@ -489,13 +506,47 @@ static const struct option_field options[] = {
        /* HTTP requests parameters */
        {
                .id = 9000,
+               .name = "http.enabled",
+               .type = &gt_rrdp_enabled,
+               .offset = offsetof(struct rpki_config, http.enabled),
+               .doc = "Enables outgoing HTTP requests",
+       },
+       {
+               .id = 9001,
+               .name = "http.priority",
+               .type = &gt_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 = &gt_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 = &gt_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 = &gt_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 = &gt_uint,
                .offset = offsetof(struct rpki_config, http.connect_timeout),
@@ -504,7 +555,7 @@ static const struct option_field options[] = {
                .max = UINT_MAX,
        },
        {
-               .id = 9002,
+               .id = 9006,
                .name = "http.transfer-timeout",
                .type = &gt_uint,
                .offset = offsetof(struct rpki_config, http.transfer_timeout),
@@ -513,7 +564,7 @@ static const struct option_field options[] = {
                .max = UINT_MAX,
        },
        {
-               .id = 9003,
+               .id = 9007,
                .name = "http.idle-timeout",
                .type = &gt_uint,
                .offset = offsetof(struct rpki_config, http.idle_timeout),
@@ -522,7 +573,7 @@ static const struct option_field options[] = {
                .max = UINT_MAX,
        },
        {
-               .id = 9004,
+               .id = 9008,
                .name = "http.ca-path",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, http.ca_path),
@@ -875,11 +926,11 @@ set_default_values(void)
        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();
@@ -890,6 +941,15 @@ set_default_values(void)
        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;
@@ -1318,27 +1378,27 @@ config_get_rsync_args(bool is_ta)
 }
 
 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 *
@@ -1401,6 +1461,25 @@ config_set_rsync_enabled(bool value)
        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)
 {
@@ -1420,11 +1499,37 @@ config_set_rsync_strategy(enum rsync_strategy 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;
 }
index 0e7858624ed23c2bc4ba4c1e8e8b9db777f428d5..0a8c8d642360ac6d0a49da662b80abc1b31d1296 100644 (file)
@@ -43,10 +43,10 @@ unsigned int config_get_rsync_retry_count(void);
 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);
@@ -74,12 +74,22 @@ uint32_t config_get_val_log_facility(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);
diff --git a/src/config/rrdp_conf.c b/src/config/rrdp_conf.c
new file mode 100644 (file)
index 0000000..4ec952f
--- /dev/null
@@ -0,0 +1,209 @@
+#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>",
+};
diff --git a/src/config/rrdp_conf.h b/src/config/rrdp_conf.h
new file mode 100644 (file)
index 0000000..85112bd
--- /dev/null
@@ -0,0 +1,11 @@
+#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_ */
index 6888489defc3c53807ce3deb054b88e815feee4a..3534109a36b5f7fa451c0ae1b60b7a3442de5a47 100644 (file)
@@ -6,7 +6,7 @@
 #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));
index b7869e5464cae933e0f873480a9f8d7bbd0f8b67..61c793588abd2f952c29cd8ccf6cec153cdf3591 100644 (file)
@@ -5,6 +5,7 @@
 
 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 *);
 
index 942cfcfe20693f88b91ab8356303749113029afe..cbd825928d9451c883cf0bdb073f91a76148c0e8 100644 (file)
@@ -7,13 +7,13 @@
 #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)
 {
@@ -29,7 +29,7 @@ parse_argv_uint32(struct option_field const *field, char const *str,
        return 0;
 }
 
-static int
+int
 parse_json_uint32(struct option_field const *opt, json_t *json, void *result)
 {
        unsigned int tmp;
index 44ae1d7702f64a9db38cedbbf980cc9c5592b025..7878e4a0b416c0412c0dbe36aa8270f6ba4c538d 100644 (file)
@@ -5,4 +5,8 @@
 
 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_ */
index 8488e2333243b774de787390db4a1cbd777950a3..6adc161daf5176811eac364480cb45edeaceec75 100644 (file)
@@ -19,6 +19,7 @@ parse_argv_offline(struct option_field const *field, char const *str, void *resu
 
        config_set_rsync_enabled(!DEREFERENCE(result));
        config_set_rrdp_enabled(!DEREFERENCE(result));
+       config_set_http_enabled(!DEREFERENCE(result));
 
        return 0;
 }
@@ -35,6 +36,7 @@ parse_json_offline(struct option_field const *opt, struct json_t *json,
 
        config_set_rsync_enabled(!DEREFERENCE(result));
        config_set_rrdp_enabled(!DEREFERENCE(result));
+       config_set_http_enabled(!DEREFERENCE(result));
 
        return 0;
 }
index d34e17de36f3f2a4b5b9a27b127ca4ab86d8f2f0..99cce080f190f7c3b5e2fa13b82d988f6f662ee3 100644 (file)
@@ -1,5 +1,6 @@
 #include "http.h"
 
+#include <unistd.h>
 #include <curl/curl.h>
 #include <sys/stat.h>
 #include "common.h"
@@ -168,10 +169,12 @@ __http_download_file(struct rpki_uri *uri, http_write_cb cb,
        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;
        }
@@ -184,19 +187,36 @@ __http_download_file(struct rpki_uri *uri, http_write_cb cb,
        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);
 
index de0b9d9e51cc5873abbb4b745fccfe735bc36af5..878be5176062c66c02194d4b94cff16c6faedebb 100644 (file)
@@ -2049,7 +2049,7 @@ use_access_method(struct sia_ca_uris *sia_uris,
         * 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;
        }
@@ -2083,12 +2083,12 @@ use_access_method(struct sia_ca_uris *sia_uris,
        }
 
        /* 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;
index 2c940d68b4255e07893da73c94a3821c8d1a7c25..cdf331b083349b39c8b66f20ff9e018e5308aab1 100644 (file)
 #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 {
@@ -76,9 +79,11 @@ static int
 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
@@ -104,6 +109,11 @@ uris_add(struct uris *uris, char *uri)
        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,
@@ -409,7 +419,7 @@ foreach_uri(struct tal *tal, foreach_uri_cb cb, void *arg)
        return 0;
 }
 
-void
+static void
 tal_shuffle_uris(struct tal *tal)
 {
        struct rpki_uri **array = tal->uris.array;
@@ -428,6 +438,48 @@ tal_shuffle_uris(struct tal *tal)
        }
 }
 
+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)
 {
@@ -514,8 +566,7 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
                        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);
@@ -637,8 +688,10 @@ do_file_validation(void *thread_arg)
        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;
index 62227535b89db68fdb38a6843e6ac6b7134174e5..dba2644b9095a72c609b7e91e9ad7eed9c2b43e4 100644 (file)
@@ -12,10 +12,6 @@ struct tal;
 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 *);
 
index 62be80c67fbb0892758151d64b7d680328efc3f7..3755051ebf7c24631aa3a2dbb842f3f7e401e694 100644 (file)
@@ -115,7 +115,7 @@ rrdp_load(struct rpki_uri *uri)
        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 */
index 7fecc65ba42f3eedc7b7a36bb17a3c8b0ceaea38..759ec3efa49d1f54ab3f608baa22fe5b161f6ea0 100644 (file)
@@ -112,40 +112,25 @@ write_local(unsigned char *content, size_t size, size_t nmemb, void *arg)
 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 */
index 94b0a03e1deb4e87e269852225b126c3f640cb40..3e82f904e2b49e32b4588a7c7070c08acebc01fb 100644 (file)
@@ -10,6 +10,9 @@
 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)
 {
@@ -85,19 +88,19 @@ config_get_rsync_enabled(void)
 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
@@ -286,3 +289,15 @@ config_get_http_ca_path(void)
 {
        return NULL;
 }
+
+void
+config_set_rsync_priority(unsigned int value)
+{
+       rsync_priority = value;
+}
+
+void
+config_set_http_priority(unsigned int value)
+{
+       http_priority = value;
+}
index 797b15f6ceb6bd9cc9210d988d55b1509a73367b..ad65c7c0fc242cb7e66d66c08f6c36e2a0d1bbbb 100644 (file)
@@ -149,16 +149,59 @@ START_TEST(tal_load_normal)
 }
 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;
 }