]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Validate list of deltas at update notification file.
authorpcarana <pc.moreno2099@gmail.com>
Thu, 5 Dec 2019 23:57:19 +0000 (17:57 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Thu, 5 Dec 2019 23:57:19 +0000 (17:57 -0600)
+Assure that the list of deltas is ordered to facilitate the validation of contiguous serials, and the processing of only the required deltas (only if there's a delta update).
+Change enum 'rrdp_uri_cmp_result' to a type 'rrdp_uri_cmp_result_t'.
+Process the snapshot if there's an error processing deltas.
+Make 'delta_head' attributes public, global and doc data init methods are now void.
+Remove 'SLIST' usage at 'deltas_head' struct, use instead an array list implementation, ready to store a defined amount of elements.

src/rrdp/db_rrdp.c
src/rrdp/db_rrdp.h
src/rrdp/rrdp_handler.c
src/rrdp/rrdp_handler.h
src/rrdp/rrdp_loader.c
src/rrdp/rrdp_objects.c
src/rrdp/rrdp_objects.h
src/rrdp/rrdp_parser.c
src/rtr/db/vrps.c
src/rtr/db/vrps.h

index 379dab57fbc3cd1551d64f5fc01173d8b5f13b8a..86e36b3e80507d8c080883274b4172a6e9ef546a 100644 (file)
@@ -98,7 +98,7 @@ add_rrdp_uri(struct db_rrdp *db, struct db_rrdp_uri *new_uri)
        return 0;
 }
 
-enum rrdp_uri_cmp_result
+rrdp_uri_cmp_result_t
 db_rrdp_cmp_uri(struct db_rrdp *db, char const *uri, char const *session_id,
     unsigned long serial)
 {
index 2dff90b6837d809182d69eebe810bf9a57b850a5..9aca0769257afd80aa26720052a746750ee552ac 100644 (file)
@@ -12,7 +12,7 @@ struct db_rrdp;
 int db_rrdp_create(struct db_rrdp **);
 void db_rddp_destroy(struct db_rrdp *);
 
-enum rrdp_uri_cmp_result db_rrdp_cmp_uri(struct db_rrdp *, char const *,
+rrdp_uri_cmp_result_t db_rrdp_cmp_uri(struct db_rrdp *, char const *,
     char const *, unsigned long);
 int db_rrdp_add_uri(struct db_rrdp *, char const *, char const *,
     unsigned long);
index b6ce91ecf99e60b93c65be65c69733a5176abc25..94a9eb05a59dc8d61b90b9c625a7ff41727fedb2 100644 (file)
@@ -32,7 +32,7 @@ get_current_threads_handler(struct rrdp_handler const **result)
        return 0;
 }
 
-enum rrdp_uri_cmp_result
+rrdp_uri_cmp_result_t
 rhandler_uri_cmp(char const *uri, char const *session_id, unsigned long serial)
 {
        CALL_HANDLER_FUNC(uri_cmp, uri_cmp(uri, session_id, serial))
index aebe582bcf74fcd3c296c8963676effd7b55d911..db6f7327e43b1846a57cb0855362b09840d214ef 100644 (file)
@@ -18,7 +18,7 @@ struct rrdp_handler {
         * Search the RRDP URI, returns the corresponding enum to indicate
         * the comparison result.
         */
-       enum rrdp_uri_cmp_result (*uri_cmp)(char const *, char const *,
+       rrdp_uri_cmp_result_t (*uri_cmp)(char const *, char const *,
            unsigned long);
        /* Add or update an RRDP URI */
        int (*uri_update)(char const *, char const *, unsigned long);
@@ -37,7 +37,8 @@ struct rrdp_handler {
        int (*uri_set_last_update)(char const *);
 };
 
-enum rrdp_uri_cmp_result rhandler_uri_cmp(char const *, char const *, unsigned long);
+rrdp_uri_cmp_result_t rhandler_uri_cmp(char const *, char const *,
+    unsigned long);
 int rhandler_uri_update(char const *, char const *, unsigned long);
 int rhandler_uri_get_serial(char const *, unsigned long *);
 int rhandler_uri_get_last_update(char const *, long *);
index 256f1f3488ae138532a51226373ee9f9a8744c01..1ff706bc73b59617895babeec6df13cb2899523b 100644 (file)
@@ -31,8 +31,8 @@ int
 rrdp_load(struct rpki_uri *uri)
 {
        struct update_notification *upd_notification;
+       rrdp_uri_cmp_result_t res;
        long last_update;
-       enum rrdp_uri_cmp_result res;
        int error;
 
        last_update = 0;
@@ -51,12 +51,17 @@ rrdp_load(struct rpki_uri *uri)
        res = rhandler_uri_cmp(uri_get_global(uri),
            upd_notification->global_data.session_id,
            upd_notification->global_data.serial);
-       switch(res) {
+       switch (res) {
        case RRDP_URI_EQUAL:
                goto set_update;
        case RRDP_URI_DIFF_SERIAL:
                error = process_diff_serial(upd_notification,
                    uri_get_global(uri));
+               /* Something went wrong, use snapshot */
+               if (!error)
+                       break;
+               pr_warn("There was an error processing RRDP deltas, using the snapshot instead.");
+               error = process_snapshot(upd_notification, uri_get_global(uri));
                break;
        case RRDP_URI_DIFF_SESSION:
                /* FIXME (now) delete the old session files */
index 63acb41a0c03bd9cf40f52ba4a01b5d28ddf8b1f..31160fac9cb683e94d1f9f7f6846f7d4326435ef 100644 (file)
@@ -1,24 +1,35 @@
 #include "rrdp_objects.h"
 
-#include <sys/queue.h>
+#include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 #include "log.h"
 
-struct delta_head {
-       unsigned long serial;
-       struct doc_data doc_data;
-       unsigned int references;
-       SLIST_ENTRY(delta_head) next;
+/*
+ * List of deltas inside an update notification file.
+ *
+ * The structure functions are extended and will have the following meaning:
+ *   - capacity : is the size of the array, must be set before using the array
+ *                and can't be modified.
+ *   - len      : number of elements set in the array.
+ *
+ * This struct is a diff version of array_list, utilized to store only the
+ * amount of deltas that may be needed and validate that an update notification
+ * file has a contiguous set of deltas.
+ */
+struct deltas_head {
+       /** Unidimensional array. Initialized lazily. */
+       struct delta_head **array;
+       /** Number of elements in @array. */
+       size_t len;
+       /** Actual allocated slots in @array. */
+       size_t capacity;
 };
 
-/* List of deltas inside an update notification file */
-SLIST_HEAD(deltas_head, delta_head);
-
-int
+void
 global_data_init(struct global_data *data)
 {
        data->session_id = NULL;
-       return 0;
 }
 
 void
@@ -27,13 +38,12 @@ global_data_cleanup(struct global_data *data)
        free(data->session_id);
 }
 
-int
+void
 doc_data_init(struct doc_data *data)
 {
        data->hash = NULL;
        data->hash_len = 0;
        data->uri = NULL;
-       return 0;
 }
 
 void
@@ -53,38 +63,37 @@ delta_head_create(struct delta_head **result)
                return pr_enomem();
 
        doc_data_init(&tmp->doc_data);
-       tmp->references = 1;
 
        *result = tmp;
        return 0;
 }
 
-unsigned long
-delta_head_get_serial(struct delta_head *delta_head)
+static void
+delta_head_destroy(struct delta_head *delta_head)
 {
-       return delta_head->serial;
+       if (delta_head) {
+               doc_data_cleanup(&delta_head->doc_data);
+               free(delta_head);
+       }
 }
 
-struct doc_data *
-delta_head_get_doc_data(struct delta_head *delta_head)
+static void
+deltas_head_init(struct deltas_head *list)
 {
-       return &delta_head->doc_data;
+       list->array = NULL;
+       list->len = 0;
+       list->capacity = 0;
 }
 
-void
-delta_head_refget(struct delta_head *delta_head)
+static void
+deltas_head_cleanup(struct deltas_head *list)
 {
-       delta_head->references++;
-}
+       size_t i;
 
-void
-delta_head_refput(struct delta_head *delta_head)
-{
-       delta_head->references--;
-       if (delta_head->references == 0) {
-               doc_data_cleanup(&delta_head->doc_data);
-               free(delta_head);
-       }
+       for (i = 0; i < list->capacity; i++)
+               delta_head_destroy(list->array[i]);
+       if (list->array)
+               free(list->array);
 }
 
 static int
@@ -96,7 +105,7 @@ deltas_head_create(struct deltas_head **deltas)
        if (tmp == NULL)
                return pr_enomem();
 
-       SLIST_INIT(tmp);
+       deltas_head_init(tmp);
 
        *deltas = tmp;
        return 0;
@@ -105,56 +114,64 @@ deltas_head_create(struct deltas_head **deltas)
 static void
 deltas_head_destroy(struct deltas_head *deltas)
 {
-       struct delta_head *head;
-
-       while (!SLIST_EMPTY(deltas)) {
-               head = deltas->slh_first;
-               SLIST_REMOVE_HEAD(deltas, next);
-               delta_head_refput(head);
-       }
+       deltas_head_cleanup(deltas);
        free(deltas);
 }
 
 int
-update_notification_create(struct update_notification **file)
+deltas_head_set_size(struct deltas_head *deltas, size_t capacity)
 {
-       struct update_notification *tmp;
-       int error;
+       size_t i;
 
-       tmp = malloc(sizeof(struct update_notification));
-       if (tmp == NULL)
-               return pr_enomem();
+       if (deltas->array != NULL)
+               pr_crit("Size of this list can't be modified");
 
-       error = deltas_head_create(&tmp->deltas_list);
-       if (error) {
-               free(tmp);
-               return error;
-       }
+       deltas->capacity = capacity;
+       if (capacity == 0)
+               return 0; /* Ok, list can have 0 elements */
 
-       global_data_init(&tmp->global_data);
-       doc_data_init(&tmp->snapshot);
+       deltas->array = malloc(deltas->capacity
+           * sizeof(struct delta_head *));
+       if (deltas->array == NULL)
+               return pr_enomem();
+
+       /* Point all elements to NULL */
+       for (i = 0; i < deltas->capacity; i++)
+               deltas->array[i] = NULL;
 
-       *file = tmp;
        return 0;
 }
 
-void
-update_notification_destroy(struct update_notification *file)
+size_t
+deltas_head_get_size(struct deltas_head *deltas)
 {
-       doc_data_cleanup(&file->snapshot);
-       global_data_cleanup(&file->global_data);
-       deltas_head_destroy(file->deltas_list);
-       free(file);
+       return deltas->capacity;
 }
 
-/* A new delta_head will be allocated, as well as its URI and HASH */
+/*
+ * A new delta_head will be allocated at the @position inside @deltas (also its
+ * URI and HASH will be allocated).
+ *
+ * The following errors can be returned due to a wrong @position:
+ *   -EEXIST: There's already an element at @position.
+ *   -EINVAL: @position can't be inside @deltas list, meaning that such element
+ *            isn't part of a contiguous list.
+ *
+ * Don't forget to call deltas_head_set_size() before this!!
+ */
 int
-deltas_head_add(struct deltas_head *deltas, unsigned long serial,
-    char *uri, unsigned char *hash, size_t hash_len)
+deltas_head_add(struct deltas_head *deltas, size_t position,
+    unsigned long serial, char *uri, unsigned char *hash, size_t hash_len)
 {
        struct delta_head *elem;
        int error;
 
+       if (position < 0 || position > deltas->capacity - 1)
+               return -EINVAL;
+
+       if (deltas->array[position] != NULL)
+               return -EEXIST;
+
        elem = NULL;
        error = delta_head_create(&elem);
        if (error)
@@ -177,19 +194,34 @@ deltas_head_add(struct deltas_head *deltas, unsigned long serial,
        }
        memcpy(elem->doc_data.hash, hash, hash_len);
 
-       SLIST_INSERT_HEAD(deltas, elem, next);
+       deltas->array[position] = elem;
+       deltas->len++;
 
        return 0;
 }
 
+/* Are all expected values set? */
+bool
+deltas_head_values_set(struct deltas_head *deltas)
+{
+       return deltas->len == deltas->capacity;
+}
+
 int
-deltas_head_for_each(struct deltas_head *deltas, delta_head_cb cb, void *arg)
+deltas_head_for_each(struct deltas_head *deltas, size_t from, delta_head_cb cb,
+    void *arg)
 {
-       struct delta_head *cursor;
+       size_t index;
        int error;
 
-       SLIST_FOREACH(cursor, deltas, next) {
-               error = cb(cursor, arg);
+       /* No elements, send error so that the snapshot is processed */
+       if (deltas->capacity == 0) {
+               pr_warn("There's no delta list to process.");
+               return -ENOENT;
+       }
+
+       for (index = from; index < deltas->capacity; index++) {
+               error = cb(deltas->array[index], arg);
                if (error)
                        return error;
        }
@@ -197,6 +229,41 @@ deltas_head_for_each(struct deltas_head *deltas, delta_head_cb cb, void *arg)
        return 0;
 }
 
+int
+update_notification_create(struct update_notification **file)
+{
+       struct update_notification *tmp;
+       struct deltas_head *list;
+       int error;
+
+       tmp = malloc(sizeof(struct update_notification));
+       if (tmp == NULL)
+               return pr_enomem();
+
+       list = NULL;
+       error = deltas_head_create(&list);
+       if (error) {
+               free(tmp);
+               return pr_enomem();
+       }
+       tmp->deltas_list = list;
+
+       global_data_init(&tmp->global_data);
+       doc_data_init(&tmp->snapshot);
+
+       *file = tmp;
+       return 0;
+}
+
+void
+update_notification_destroy(struct update_notification *file)
+{
+       doc_data_cleanup(&file->snapshot);
+       global_data_cleanup(&file->global_data);
+       deltas_head_destroy(file->deltas_list);
+       free(file);
+}
+
 int
 snapshot_create(struct snapshot **file)
 {
index 7f7ce4a7fa8677dd34fe556835c6e141f06b36b3..b062b49ebdc7537df38739803a94b60f7d908fc1 100644 (file)
@@ -2,9 +2,10 @@
 #define SRC_RRDP_RRDP_OBJECTS_H_
 
 #include <stddef.h>
+#include <stdbool.h>
 
 /* Possible results for an RRDP URI comparison */
-enum rrdp_uri_cmp_result {
+typedef enum {
        /* The URI exists and has the same session ID and serial */
        RRDP_URI_EQUAL,
 
@@ -16,7 +17,7 @@ enum rrdp_uri_cmp_result {
 
        /* The URI doesn't exists */
        RRDP_URI_NOTFOUND,
-};
+} rrdp_uri_cmp_result_t;
 
 /* Global RRDP files data */
 struct global_data {
@@ -51,7 +52,8 @@ struct delta {
        struct global_data global_data;
 };
 
-/* Snapshot file content
+/*
+ * Snapshot file content
  * Publish list isn't remember, is processed ASAP.
  */
 struct snapshot {
@@ -59,37 +61,39 @@ struct snapshot {
 };
 
 /* Delta element located at an update notification file */
-struct delta_head;
+struct delta_head {
+       unsigned long serial;
+       struct doc_data doc_data;
+};
 
 /* List of deltas inside an update notification file */
 struct deltas_head;
 
+/* Update notification file content */
 struct update_notification {
        struct global_data global_data;
        struct doc_data snapshot;
        struct deltas_head *deltas_list;
 };
 
-int global_data_init(struct global_data *);
+void global_data_init(struct global_data *);
 void global_data_cleanup(struct global_data *);
 
-int doc_data_init(struct doc_data *);
+void doc_data_init(struct doc_data *);
 void doc_data_cleanup(struct doc_data *);
 
 int update_notification_create(struct update_notification **);
 void update_notification_destroy(struct update_notification *);
 
-unsigned long delta_head_get_serial(struct delta_head *);
-struct doc_data *delta_head_get_doc_data(struct delta_head *);
-
-void delta_head_refget(struct delta_head *);
-void delta_head_refput(struct delta_head *);
-
 typedef int (*delta_head_cb)(struct delta_head *, void *);
-int deltas_head_for_each(struct deltas_head *, delta_head_cb, void *);
-int deltas_head_add(struct deltas_head *, unsigned long, char *,
+int deltas_head_for_each(struct deltas_head *, size_t, delta_head_cb, void *);
+int deltas_head_add(struct deltas_head *, size_t, unsigned long, char *,
     unsigned char *, size_t);
 
+int deltas_head_set_size(struct deltas_head *, size_t);
+size_t deltas_head_get_size(struct deltas_head *);
+bool deltas_head_values_set(struct deltas_head *);
+
 int snapshot_create(struct snapshot **);
 void snapshot_destroy(struct snapshot *);
 
index 7eb2b895e919d6ce0715bc977fcf01eaf8759745..6444267f16d97c723350660ecf3b393e5c09c91d 100644 (file)
 #define RRDP_ATTR_URI          "uri"
 #define RRDP_ATTR_HASH         "hash"
 
-struct deltas_proc_args {
-       struct delta_head **deltas;
-       unsigned long serial;
-       size_t deltas_set;
-};
-
 static int
 get_root_element(xmlDoc *doc, xmlNode **result)
 {
@@ -418,6 +412,13 @@ parse_doc_data(xmlNode *root, bool parse_hash, bool hash_req,
                return error;
        }
 end:
+       /* Function called just to do the validation */
+       if (data == NULL) {
+               doc_data_init(data);
+               free(hash);
+               free(uri);
+               return 0;
+       }
        data->uri = uri;
        data->hash = hash;
        data->hash_len = hash_len;
@@ -425,11 +426,12 @@ end:
 }
 
 static int
-parse_notification_deltas(xmlNode *root, struct deltas_head *deltas,
-    unsigned long *parsed_serial)
+parse_notification_deltas(xmlNode *root, unsigned long max_serial,
+    unsigned long deltas_len, struct deltas_head *deltas)
 {
        struct doc_data doc_data;
        unsigned long serial;
+       size_t position;
        int error;
 
        error = parse_long(root, RRDP_ATTR_SERIAL, &serial);
@@ -443,52 +445,83 @@ parse_notification_deltas(xmlNode *root, struct deltas_head *deltas,
                return error;
        }
 
-       error = deltas_head_add(deltas, serial, doc_data.uri, doc_data.hash,
-           doc_data.hash_len);
+       /*
+        * The delta will be added to the position it belongs, assuring that
+        * the deltas list will be ordered.
+        */
+       position = deltas_len - 1 - (max_serial - serial);
+       error = deltas_head_add(deltas, position, serial, doc_data.uri,
+           doc_data.hash, doc_data.hash_len);
 
        /* Always release data */
        doc_data_cleanup(&doc_data);
-       if (error)
-               return error;
+       if (!error)
+               return 0;
 
-       *parsed_serial = serial;
-       return 0;
+       if (error == -EINVAL)
+               return pr_err("Serial '%lu' at delta elements isn't part of a contiguous list of serials.",
+                   serial);
+
+       if (error == -EEXIST)
+               return pr_err("Duplicated serial '%lu' at delta elements.",
+                   serial);
+
+       return error;
 }
 
 /* Get the notification data. In case of error, the caller must cleanup @file */
 static int
-parse_notification_data(xmlNode *root, struct update_notification *file)
+parse_notification_data(xmlNode *root, struct update_notification *file,
+    char const *uri)
 {
        xmlNode *cur_node;
-       unsigned long loaded_serial, min_serial;
-       unsigned long delta_count;
-       int snapshot_count;
+       rrdp_uri_cmp_result_t res;
+       unsigned long from_serial, max_serial;
+       unsigned long deltas_len;
+       bool create_snapshot;
        int error;
 
-       snapshot_count = 0;
-       delta_count = 0;
-       loaded_serial = 0;
-       min_serial = ULONG_MAX;
+       create_snapshot = false;
+       from_serial = 0;
+       max_serial = file->global_data.serial;
+
+       /* By schema, at least one snapshot element will be present */
+       deltas_len = xmlChildElementCount(root) - 1;
+
+       error = deltas_head_set_size(file->deltas_list, deltas_len);
+       if (error)
+               return error;
+
+       res = rhandler_uri_cmp(uri, file->global_data.session_id,
+           file->global_data.serial);
+       switch (res) {
+       case RRDP_URI_EQUAL:
+               /* Just validate content */
+               break;
+       case RRDP_URI_DIFF_SERIAL:
+               /* Get only the deltas to process and the snapshot */
+               create_snapshot = true;
+               error = rhandler_uri_get_serial(uri, &from_serial);
+               if (error)
+                       return pr_err("Couldn't get serial of '%s'.", uri);
+               break;
+       case RRDP_URI_DIFF_SESSION:
+               /* Get only the snapshot */
+       case RRDP_URI_NOTFOUND:
+               create_snapshot = true;
+               break;
+       default:
+               pr_crit("Unexpected RRDP URI comparison result");
+       }
 
        for (cur_node = root->children; cur_node; cur_node = cur_node->next) {
                if (xmlStrEqual(cur_node->name, BAD_CAST RRDP_ELEM_DELTA)) {
-                       delta_count++;
-                       error = parse_notification_deltas(cur_node,
-                           file->deltas_list, &loaded_serial);
-                       /* Note that the elements may not be ordered. (¬¬) */
-                       if (!error && loaded_serial < min_serial)
-                               min_serial = loaded_serial;
+                       error = parse_notification_deltas(cur_node, max_serial,
+                           deltas_len, file->deltas_list);
                } else if (xmlStrEqual(cur_node->name,
                    BAD_CAST RRDP_ELEM_SNAPSHOT)) {
-                       /*
-                        * The Update Notification File MUST contain exactly
-                        * one 'snapshot' element for the current repository
-                        * version.
-                        */
-                       if (++snapshot_count > 1)
-                               return pr_err("More than one snapshot element found");
                        error = parse_doc_data(cur_node, true, true,
-                           &file->snapshot);
+                           (create_snapshot ? &file->snapshot : NULL));
                }
 
                if (error)
@@ -496,16 +529,14 @@ parse_notification_data(xmlNode *root, struct update_notification *file)
        }
 
        /*
-        * If delta elements are included, they MUST form a contiguous
+        * "If delta elements are included, they MUST form a contiguous
         * sequence of serial numbers starting at a revision determined by
         * the Repository Server, up to the serial number mentioned in the
-        * notification element.
+        * notification element."
         *
-        * FIXME (now) running out of time, this needs an improvement, but why
-        * should we validate this? Anyways, leaving it for later.
+        * If all expected elements are set, everything is ok.
         */
-       if (delta_count > 0 &&
-           file->global_data.serial - min_serial + 1 != delta_count)
+       if (!deltas_head_values_set(file->deltas_list))
                return pr_err("Deltas listed don't have a contiguous sequence of serial numbers");
 
        return 0;
@@ -789,7 +820,7 @@ parse_notification(struct rpki_uri *uri, struct update_notification **file)
        if (error)
                goto release_update;
 
-       error = parse_notification_data(root, tmp);
+       error = parse_notification_data(root, tmp, uri_get_global(uri));
        if (error)
                goto release_update;
 
@@ -876,7 +907,7 @@ parse_delta(struct rpki_uri *uri, struct update_notification *parent,
        if (error)
                goto release_doc;
 
-       expected_data = delta_head_get_doc_data(parents_data);
+       expected_data = &parents_data->doc_data;
 
        error = hash_validate_file("sha256", uri, expected_data->hash,
            expected_data->hash_len);
@@ -895,7 +926,7 @@ parse_delta(struct rpki_uri *uri, struct update_notification *parent,
        /* session_id must be the same as the parent */
        error = parse_global_data(root, &delta->global_data,
            parent->global_data.session_id,
-           delta_head_get_serial(parents_data));
+           parents_data->serial);
        if (error)
                goto release_delta;
 
@@ -912,38 +943,14 @@ pop_fnstack:
 }
 
 static int
-get_pending_delta(struct delta_head **delta_head, unsigned long pos,
-    struct deltas_proc_args *args)
-{
-       /* Ref to the delta element */
-       args->deltas[pos] = *delta_head;
-       args->deltas_set++;
-       delta_head_refget(*delta_head);
-
-       return 0;
-}
-
-static int
-__get_pending_delta(struct delta_head *delta_head, void *arg)
-{
-       struct deltas_proc_args *args = arg;
-       unsigned long serial;
-
-       serial = delta_head_get_serial(delta_head);
-       if (serial <= args->serial)
-               return 0;
-
-       return get_pending_delta(&delta_head, serial - args->serial - 1, args);
-}
-
-static int
-process_delta(struct delta_head *delta_head, struct update_notification *parent)
+process_delta(struct delta_head *delta_head, void *arg)
 {
+       struct update_notification *parent = arg;
        struct rpki_uri *uri;
        struct doc_data *head_data;
        int error;
 
-       head_data = delta_head_get_doc_data(delta_head);
+       head_data = &delta_head->doc_data;
 
        error = uri_create_https_str(&uri, head_data->uri,
            strlen(head_data->uri));
@@ -1023,46 +1030,15 @@ release_uri:
 }
 
 int
-rrdp_process_deltas(struct update_notification *parent, unsigned long serial)
+rrdp_process_deltas(struct update_notification *parent,
+    unsigned long cur_serial)
 {
-       struct delta_head *deltas[parent->global_data.serial - serial];
-       struct deltas_proc_args args;
        size_t deltas_len;
-       size_t index;
-       int error;
-
-       deltas_len = parent->global_data.serial - serial;
-       for (index = 0; index < deltas_len; index++)
-               deltas[index] = NULL;
-
-       args.deltas = deltas;
-       args.serial = serial;
-       args.deltas_set = 0;
-
-       error = deltas_head_for_each(parent->deltas_list, __get_pending_delta,
-           &args);
-       if (error)
-               goto release_deltas;
-
-       /* Check that all expected deltas are set */
-       if (args.deltas_set != deltas_len) {
-               error = pr_err("Less deltas than expected: should be from serial %lu to %lu (%lu), but got only %lu",
-                   serial, parent->global_data.serial, deltas_len,
-                   args.deltas_set);
-               goto release_deltas;
-       }
+       size_t from;
 
-       /* Now process each delta in order */
-       for (index = 0; index < deltas_len; index++) {
-               error = process_delta(deltas[index], parent);
-               if (error)
-                       break;
-       }
-       /* Error 0 it's ok */
-release_deltas:
-       for (index = 0; index < deltas_len; index++)
-               if (deltas[index] != NULL)
-                       delta_head_refput(deltas[index]);
+       deltas_len = deltas_head_get_size(parent->deltas_list);
+       from = deltas_len - (parent->global_data.serial - cur_serial);
 
-       return error;
+       return deltas_head_for_each(parent->deltas_list, from, process_delta,
+           parent);
 }
index 62f575dd2951610fd3f2736307e515d51a6c4cc2..f39b88190ac97972cd434e847c9bb9212d2570b6 100644 (file)
@@ -181,7 +181,7 @@ handle_router_key(unsigned char const *ski, uint32_t as,
            rtrhandler_handle_router_key(arg, ski, as, spk))
 }
 
-enum rrdp_uri_cmp_result
+rrdp_uri_cmp_result_t
 rrdp_uri_cmp(char const *uri, char const *session_id, unsigned long serial)
 {
        RLOCK_HANDLER(&state_lock,
index 3cab65b9b7f85229e9a2e637d05f4cf31cafdbea..a303f428abf1dd4c884544c8805e46a7a73edb6e 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include "data_structure/array_list.h"
+#include "rrdp/rrdp_objects.h"
 #include "rtr/db/delta.h"
 
 /*
@@ -41,7 +42,7 @@ int handle_roa_v6(uint32_t, struct ipv6_prefix const *, uint8_t, void *);
 int handle_router_key(unsigned char const *, uint32_t, unsigned char const *,
     void *);
 
-enum rrdp_uri_cmp_result rrdp_uri_cmp(char const *, char const *,
+rrdp_uri_cmp_result_t rrdp_uri_cmp(char const *, char const *,
     unsigned long);
 int rrdp_uri_update(char const *, char const *, unsigned long);
 int rrdp_uri_get_serial(char const *, unsigned long *);