]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add server.enabled and output.roa arguments, update server.address docs
authorpcarana <pc.moreno2099@gmail.com>
Wed, 5 Jun 2019 17:00:11 +0000 (12:00 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Wed, 5 Jun 2019 17:00:11 +0000 (12:00 -0500)
Now to perform a standalone validation, the server must be disabled (server.enabled = false).
The ROAs in CSV format can be: printed to console (output.roa = '-'), printed to a file (output.roa = '<file>'), not printed (output.roa isn't configured).
'server.address' docs specify the scenario when no value is set to that argument.

15 files changed:
docs/doc/usage.md
src/Makefile.am
src/config.c
src/config.h
src/console_handler.c [deleted file]
src/console_handler.h [deleted file]
src/file.c
src/file.h
src/main.c
src/output_printer.c [new file with mode: 0644]
src/output_printer.h [new file with mode: 0644]
src/rtr/db/vrps.c
src/rtr/rtr.c
test/Makefile.am
test/impersonator.c

index f682bb9c988bf3ef3a9e37dcb6019703832e9dc1..a69ea0cbc6853ab9994ef2fe86c3086ecbba1ec6 100644 (file)
@@ -23,18 +23,20 @@ command: fort
                4. [`root-except-ta`](#root-except-ta)
        7. [`--shuffle-uris`](#--shuffle-uris)
        8. [`--maximum-certificate-depth`](#--maximum-certificate-depth)
-       9. [`--server.address`](#--serveraddress)
-       10. [`--server.port`](#--serverport)
-       11. [`--server.backlog`](#--serverbacklog)
-       12. [`--server.validation-interval`](#--servervalidation-interval)
-       13. [`--slurm`](#--slurm)
-       14. [`--log.color-output`](#--logcolor-output)
-       15. [`--log.file-name-format`](#--logfile-name-format)
-       16. [`--configuration-file`](#--configuration-file)
-       17. [`rsync.program`](#rsyncprogram)
-       18. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
-       19. [`rsync.arguments-flat`](#rsyncarguments-flat)
-       20. [`incidences`](#incidences)
+       9. [`--server.enabled`](#--serverenabled)
+       10. [`--server.address`](#--serveraddress)
+       11. [`--server.port`](#--serverport)
+       12. [`--server.backlog`](#--serverbacklog)
+       13. [`--server.validation-interval`](#--servervalidation-interval)
+       14. [`--slurm`](#--slurm)
+       15. [`--log.color-output`](#--logcolor-output)
+       16. [`--log.file-name-format`](#--logfile-name-format)
+       17. [`--output.roa`](#--outputroa)
+       18. [`--configuration-file`](#--configuration-file)
+       19. [`rsync.program`](#rsyncprogram)
+       20. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
+       21. [`rsync.arguments-flat`](#rsyncarguments-flat)
+       22. [`incidences`](#incidences)
 
 ## Syntax
 
@@ -51,6 +53,7 @@ command: fort
         [--sync-strategy=off|strict|root|root-except-ta]
         [--shuffle-uris]
         [--maximum-certificate-depth=<unsigned integer>]
+        [--server.enabled=true|false]
         [--server.address=<string>]
         [--server.port=<string>]
         [--server.backlog=<unsigned integer>]
@@ -58,6 +61,7 @@ command: fort
         [--slurm=<string>]
         [--log.color-output]
         [--log.file-name-format=global-url|local-path|file-name]
+        [--output.roa=<file>]
 ```
 
 If an argument is declared more than once, the last one takes precedence:
@@ -234,6 +238,16 @@ Maximum allowable RPKI tree height. Meant to protect Fort from iterating infinit
 
 Fort's tree traversal is actually iterative (not recursive), so there should be no risk of stack overflow, regardless of this value.
 
+### `--server.enabled`
+
+- **Type:** Boolean
+- **Availability:** `argv` and JSON
+- **Default:** true
+
+Enable or disable the RTR server.
+
+If set to `false`: the server is disabled, the rest of the `server.*` arguments are discarded, and Fort performs an in-place standalone RPKI validation.
+
 ### `--server.address`
 
 - **Type:** String
@@ -242,7 +256,7 @@ Fort's tree traversal is actually iterative (not recursive), so there should be
 
 Hostname or numeric host address the RTR server will be bound to. Must resolve to (or be) a bindable IP address. IPv4 and IPv6 are supported.
 
-If this field is omitted, Fort falls back to perform an in-place standalone RPKI validation. Presently, this is only intended for debugging.
+If this field is omitted, Fort will attempt to bind the server using the IP address `INADDR_ANY` (for an IPv4 address) or `IN6ADDR_ANY_INIT` (for an IPv6 address); see '`$ man getaddrinfo`'.
 
 ### `--server.port`
 
@@ -334,6 +348,17 @@ $ {{ page.command }} --output-file-name-format file-name  --local-repository rep
 ERR: baz.cer: Certificate validation failed: certificate has expired
 {% endhighlight %}
 
+### `--output.roa`
+
+- **Type:** String (Path to file)
+- **Availability:** `argv` and JSON
+
+File where the ROAs will be stored in CSV format.
+
+When the file is specified, its content will be removed to store the ROAs; if the file doesn't exists, it will be created. To print at console, use a hyphen `"-"`. If RTR server is enabled, then the ROAs will be printed every [`--server.validation-interval`](#--servervalidation-interval) secs.
+
+If a value isn't specified, then the ROAs aren't printed.
+
 ### `--configuration-file`
 
 - **Type:** String (Path to file)
index d4aac56e66eaf52294b54bb7921c240b34e59eed..e10c71dd2c5bbe247fd2647032ba7dcdebf5195d 100644 (file)
@@ -13,7 +13,6 @@ fort_SOURCES += certificate_refs.h certificate_refs.c
 fort_SOURCES += cert_stack.h cert_stack.c
 fort_SOURCES += clients.c clients.h
 fort_SOURCES += common.c common.h
-fort_SOURCES += console_handler.h console_handler.c
 fort_SOURCES += config.h config.c
 fort_SOURCES += debug.h debug.c
 fort_SOURCES += extension.h extension.c
@@ -23,6 +22,7 @@ fort_SOURCES += line_file.h line_file.c
 fort_SOURCES += log.h log.c
 fort_SOURCES += nid.h nid.c
 fort_SOURCES += notify.c notify.h
+fort_SOURCES += output_printer.h output_printer.c
 fort_SOURCES += random.h random.c
 fort_SOURCES += resource.h resource.c
 fort_SOURCES += rpp.h rpp.c
index eb0d57735e04c00e54ee185bfe1be41e5da8cf23..f9f17c47c16313c6988291cec35298193d615ee4 100644 (file)
@@ -48,6 +48,8 @@ struct rpki_config {
        char *slurm;
 
        struct {
+               /** Enable/disable the RTR server. */
+               bool enabled;
                /** The bound listening address of the RTR server. */
                char *address;
                /** The bound listening port of the RTR server. */
@@ -80,6 +82,12 @@ struct rpki_config {
                /** Format in which file names will be printed. */
                enum filename_format filename_format;
        } log;
+
+       struct {
+               /** File where the validated ROAs will be stored */
+               char *roa;
+               /** TODO (next iteration) Add BGPsec output */
+       } output;
 };
 
 static void print_usage(FILE *, bool);
@@ -146,7 +154,7 @@ static const struct option_field options[] = {
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, tal),
                .doc = "Path to the TAL file or TALs directory",
-               .arg_doc = "<file>",
+               .arg_doc = "<file or directory>",
        }, {
                .id = 'r',
                .name = "local-repository",
@@ -190,16 +198,22 @@ static const struct option_field options[] = {
        /* Server fields */
        {
                .id = 5000,
+               .name = "server.enabled",
+               .type = &gt_bool,
+               .offset = offsetof(struct rpki_config, server.enabled),
+               .doc = "Enable or disable the RTR server.",
+       }, {
+               .id = 5001,
                .name = "server.address",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, server.address),
-               .doc = "Address the RTR server will bind itself to. Can be a name, in which case an address will be resolved.",
+               .doc = "Address to which RTR server will bind itself to. Can be a name, in which case an address will be resolved.",
        }, {
-               .id = 5001,
+               .id = 5002,
                .name = "server.port",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, server.port),
-               .doc = "Port the RTR server will bind itself to. Can be a string, in which case a number will be resolved.",
+               .doc = "Port to which RTR server will bind itself to. Can be a string, in which case a number will be resolved.",
        }, {
                .id = 5003,
                .name = "server.backlog",
@@ -281,6 +295,16 @@ static const struct option_field options[] = {
                .availability = AVAILABILITY_JSON,
        },
 
+       /* Output files */
+       {
+               .id = 6000,
+               .name = "output.roa",
+               .type = &gt_string,
+               .offset = offsetof(struct rpki_config, output.roa),
+               .doc = "File where ROAs will be stored in CSV format, use '-' to print at console",
+               .arg_doc = "<file>",
+       },
+
        { 0 },
 };
 
@@ -429,6 +453,7 @@ set_default_values(void)
         * duplicates.
         */
 
+       rpki_config.server.enabled = true;
        rpki_config.server.address = NULL;
        rpki_config.server.port = strdup("323");
        if (rpki_config.server.port == NULL)
@@ -469,6 +494,8 @@ set_default_values(void)
        rpki_config.log.color = false;
        rpki_config.log.filename_format = FNF_GLOBAL;
 
+       rpki_config.output.roa = NULL;
+
        return 0;
 
 revert_recursive_array:
@@ -601,6 +628,12 @@ get_option_metadatas(void)
        return options;
 }
 
+bool
+config_get_server_enabled(void)
+{
+       return rpki_config.server.enabled;
+}
+
 char const *
 config_get_server_address(void)
 {
@@ -701,6 +734,12 @@ config_get_rsync_args(bool is_ta)
        pr_crit("Invalid sync strategy: '%u'", rpki_config.sync_strategy);
 }
 
+char const *
+config_get_output_roa(void)
+{
+       return rpki_config.output.roa;
+}
+
 void
 free_rpki_config(void)
 {
index 866228ec9f2a9405e39c9f000a1be95103967770..f9d41e3c0beabb6263f10ad666de7d3320705b61 100644 (file)
@@ -14,6 +14,7 @@ int handle_flags_config(int , char **);
 void free_rpki_config(void);
 
 /* Getters */
+bool config_get_server_enabled(void);
 char const *config_get_server_address(void);
 char const *config_get_server_port(void);
 int config_get_server_queue(void);
@@ -29,6 +30,7 @@ bool config_get_color_output(void);
 enum filename_format config_get_filename_format(void);
 char *config_get_rsync_program(void);
 struct string_array const *config_get_rsync_args(bool);
+char const *config_get_output_roa(void);
 
 /* Needed public by the JSON module */
 void *get_rpki_config_field(struct option_field const *);
diff --git a/src/console_handler.c b/src/console_handler.c
deleted file mode 100644 (file)
index fca6f5c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "console_handler.h"
-
-#include "thread_var.h"
-#include "validation_handler.h"
-#include "object/tal.h"
-
-static int
-print_v4_roa(uint32_t as, struct ipv4_prefix const *prefix, uint8_t max_length,
-    void *arg)
-{
-       printf("AS%u,%s/%u,%u\n", as, v4addr2str(&prefix->addr), prefix->len,
-           max_length);
-       return 0;
-}
-
-static int
-print_v6_roa(uint32_t as, struct ipv6_prefix const *prefix, uint8_t max_length,
-    void *arg)
-{
-       printf("AS%u,%s/%u,%u\n", as, v6addr2str(&prefix->addr), prefix->len,
-           max_length);
-       return 0;
-}
-
-int
-validate_into_console(void)
-{
-       struct validation_handler handler;
-
-       handler.handle_roa_v4 = print_v4_roa;
-       handler.handle_roa_v6 = print_v6_roa;
-       handler.arg = NULL;
-
-       return perform_standalone_validation(&handler);
-}
diff --git a/src/console_handler.h b/src/console_handler.h
deleted file mode 100644 (file)
index b712f24..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef SRC_CONSOLE_HANDLER_H_
-#define SRC_CONSOLE_HANDLER_H_
-
-int validate_into_console(void);
-
-#endif /* SRC_CONSOLE_HANDLER_H_ */
index bb85e8787bd3738d215ba6760534cad91f981857..d1e26b6f4329d0036f5a4166884d077d44a47af3 100644 (file)
@@ -4,13 +4,14 @@
 #include <stdlib.h>
 #include "log.h"
 
-int
-file_open(char const *file_name, FILE **result, struct stat *stat)
+static int
+file_get(char const *file_name, FILE **result, struct stat *stat,
+    char const *mode)
 {
        FILE *file;
        int error;
 
-       file = fopen(file_name, "rb");
+       file = fopen(file_name, mode);
        if (file == NULL)
                return pr_errno(errno, "Could not open file '%s'", file_name);
 
@@ -31,6 +32,18 @@ fail:
        return error;
 }
 
+int
+file_open(char const *file_name, FILE **result, struct stat *stat)
+{
+       return file_get(file_name, result, stat, "rb");
+}
+
+int
+file_write(char const *file_name, FILE **result, struct stat *stat)
+{
+       return file_get(file_name, result, stat, "wb");
+}
+
 void
 file_close(FILE *file)
 {
index c494a65b021c3f7890794a5cceba2c688c00667b..8440dfe4e6e2d177e152cbe6481fb55d716f3cf1 100644 (file)
@@ -16,6 +16,7 @@ struct file_contents {
 };
 
 int file_open(char const *, FILE **, struct stat *);
+int file_write(char const *, FILE **, struct stat *);
 void file_close(FILE *);
 
 int file_load(char const *, struct file_contents *);
index 4c129c4b028a0257ea26bc70e58ac98b2ff5bd05..373da9ab71990abe6df6bf27c9660545f731e948 100644 (file)
@@ -1,6 +1,5 @@
 #include "clients.h"
 #include "config.h"
-#include "console_handler.h"
 #include "debug.h"
 #include "extension.h"
 #include "nid.h"
@@ -53,9 +52,7 @@ main(int argc, char **argv)
        if (error)
                goto revert_nid;
 
-       error = (config_get_server_address() != NULL)
-           ? start_rtr_server()
-           : validate_into_console();
+       error = start_rtr_server();
 
 revert_nid:
        nid_destroy();
diff --git a/src/output_printer.c b/src/output_printer.c
new file mode 100644 (file)
index 0000000..e5761b5
--- /dev/null
@@ -0,0 +1,99 @@
+#include "output_printer.h"
+
+#include "config.h"
+#include "file.h"
+#include "log.h"
+#include "rtr/db/vrp.h"
+#include <arpa/inet.h>
+
+char addr_buf[INET6_ADDRSTRLEN];
+
+static char const *
+strv4addr(struct in_addr const *addr)
+{
+       return inet_ntop(AF_INET, addr, addr_buf, INET6_ADDRSTRLEN);
+}
+
+static char const *
+strv6addr(struct in6_addr const *addr)
+{
+       return inet_ntop(AF_INET6, addr, addr_buf, INET6_ADDRSTRLEN);
+}
+
+static int
+load_output_file(FILE **result, bool *fopen)
+{
+       FILE *tmp;
+       struct stat stat;
+       char const *output = config_get_output_roa();
+       int error;
+
+       if (output == NULL) {
+               *result = NULL;
+               return 0;
+       }
+
+       *fopen = false;
+       if (strcmp(output, "-") == 0) {
+               *result = stdout;
+               return 0;
+       }
+
+       error = file_write(output, &tmp, &stat);
+       if (error)
+               return error;
+
+       *fopen = true;
+       *result = tmp;
+       return 0;
+}
+
+static int
+print_roa(struct vrp const *vrp, void *arg)
+{
+       FILE *out = arg;
+
+       switch(vrp->addr_fam) {
+       case AF_INET:
+               fprintf(out, "AS%u,%s/%u,%u\n", vrp->asn,
+                   strv4addr(&vrp->prefix.v4), vrp->prefix_length,
+                   vrp->max_prefix_length);
+               break;
+       case AF_INET6:
+               fprintf(out, "AS%u,%s/%u,%u\n", vrp->asn,
+                   strv6addr(&vrp->prefix.v6), vrp->prefix_length,
+                   vrp->max_prefix_length);
+               break;
+       default:
+               pr_crit("Unknown family type");
+       }
+
+       return 0;
+}
+
+void
+output_print_roas(struct roa_table *roas)
+{
+       FILE *out;
+       bool fopen;
+       int error;
+
+       error = load_output_file(&out, &fopen);
+       if (error) {
+               pr_err("Error getting file '%s'", config_get_output_roa());
+               return;
+       }
+
+       /* No output configured */
+       if (out == NULL)
+               return;
+
+       fprintf(out, "ASN,Prefix,Max prefix length\n");
+       error = roa_table_foreach_roa(roas, print_roa, out);
+       if (fopen)
+               file_close(out);
+       if (error) {
+               pr_err("Error printing ROAs");
+               return;
+       }
+}
diff --git a/src/output_printer.h b/src/output_printer.h
new file mode 100644 (file)
index 0000000..47fcdb2
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SRC_OUTPUT_PRINTER_H_
+#define SRC_OUTPUT_PRINTER_H_
+
+#include "rtr/db/roa_table.h"
+
+void output_print_roas(struct roa_table *);
+
+#endif /* SRC_OUTPUT_PRINTER_H_ */
index 579c6ae59f869fd448f0da7cf1ca4e3946f4be7d..897e07f459b1b964fbdd79088355ca008f264800 100644 (file)
@@ -6,6 +6,7 @@
 #include <sys/queue.h>
 #include "clients.h"
 #include "common.h"
+#include "output_printer.h"
 #include "validation_handler.h"
 #include "data_structure/array_list.h"
 #include "object/tal.h"
@@ -127,6 +128,8 @@ __perform_standalone_validation(struct roa_table **result)
        validation_handler.arg = roas;
 
        error = perform_standalone_validation(&validation_handler);
+       /* Print after validation to avoid duplicated info */
+       output_print_roas(roas);
        if (error) {
                roa_table_destroy(roas);
                return error;
index e0d86b95df175132740aa6e0d62931937ac761dc..ffa74293efd1b3826fab788fad23f26010e5d8db 100644 (file)
@@ -17,6 +17,7 @@
 #include "updates_daemon.h"
 #include "rtr/err_pdu.h"
 #include "rtr/pdu.h"
+#include "rtr/db/vrps.h"
 
 struct sigaction act;
 
@@ -351,41 +352,50 @@ join_thread(pthread_t tid, void *arg)
 
 /*
  * Starts the server, using the current thread to listen for RTR client
- * requests.
+ * requests. If configuration parameter 'server.enabled' is false, then the
+ * server runs "one time" (a.k.a. run the validation just once), it doesn't
+ * waits for clients requests.
  *
- * This function blocks.
+ * When listening for client requests, this function blocks.
  */
 int
 rtr_listen(void)
 {
+       bool changed;
        int server_fd; /* "file descriptor" */
        int error;
 
-       error = create_server_socket(&server_fd);
+       error = init_signal_handler();
        if (error)
                return error;
 
-       /* Server ready, start everything else */
        error = clients_db_init();
        if (error)
-               goto revert_server_socket;
+               return error;
 
-       error = updates_daemon_start();
+       if (!config_get_server_enabled()) {
+               error = vrps_update(&changed);
+               if (error)
+                       pr_err("Error %d while trying to update the ROA database.",
+                           error);
+               goto revert_clients_db; /* Error 0 it's ok */
+       }
+
+       error = create_server_socket(&server_fd);
        if (error)
                goto revert_clients_db;
 
-       error = init_signal_handler();
+       error = updates_daemon_start();
        if (error)
-               goto revert_updates_daemon;
+               goto revert_server_socket;
 
        error = handle_client_connections(server_fd);
 
        end_clients();
-revert_updates_daemon:
        updates_daemon_destroy();
-revert_clients_db:
-       clients_db_destroy(join_thread, NULL);
 revert_server_socket:
        close(server_fd);
+revert_clients_db:
+       clients_db_destroy(join_thread, NULL);
        return error;
 }
index 24bde67656c70e30cb0746e9dda05fe90034cf5e..83e45d6e969eb015ae6b3979d74815a7e2e53590 100644 (file)
@@ -62,6 +62,8 @@ line_file_test_LDADD = ${MY_LDADD}
 pdu_handler_test_SOURCES  = ${BASIC_MODULES}
 pdu_handler_test_SOURCES += ${SLURM_SOURCES}
 pdu_handler_test_SOURCES += ../src/common.c
+pdu_handler_test_SOURCES += ../src/file.c
+pdu_handler_test_SOURCES += ../src/output_printer.c
 pdu_handler_test_SOURCES += ../src/rtr/pdu_handler.c
 pdu_handler_test_SOURCES += ../src/rtr/err_pdu.c
 pdu_handler_test_SOURCES += ../src/rtr/db/delta.c
@@ -101,6 +103,8 @@ vcard_test_LDADD = ${MY_LDADD}
 vrps_test_SOURCES  = ${BASIC_MODULES}
 vrps_test_SOURCES += ${SLURM_SOURCES}
 vrps_test_SOURCES += ../src/common.c
+vrps_test_SOURCES += ../src/file.c
+vrps_test_SOURCES += ../src/output_printer.c
 vrps_test_SOURCES += ../src/rtr/db/delta.c
 vrps_test_SOURCES += ../src/rtr/db/roa_table.c
 vrps_test_SOURCES += ../src/rtr/db/vrps.c
index aaaecdfc1e3d1607b9b0787de85fb88a28291083..bbe6a5e68c8870e44269f48555a9317a9507ccb9 100644 (file)
@@ -77,6 +77,18 @@ config_get_slurm(void)
        return NULL;
 }
 
+bool
+config_get_server_enabled(void)
+{
+       return false;
+}
+
+char const *
+config_get_output_roa(void)
+{
+       return "-";
+}
+
 enum incidence_action
 incidence_get_action(enum incidence_id id)
 {