]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Index sequences properly
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 5 Dec 2024 15:13:52 +0000 (12:13 -0300)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 5 Dec 2024 15:13:52 +0000 (12:13 -0300)
Postponed task from some previous refactor; the object was only
partially being serialized.

Fixes XXX-style TODO.

src/cache.c
src/file.c
src/file.h
src/json_util.c
src/json_util.h
src/rrdp.c

index 07dab4c90d11a828934a0f63b091126a585faa6d..2ea3039865804723eb56d2410ff0a007444924c7 100644 (file)
@@ -421,11 +421,20 @@ json2tbl(json_t *root, struct cache_table *tbl)
        struct cache_node *node;
        size_t urlen;
 
-       // XXX load (and save) seqs
-       if (json_get_ulong(root, "next", &tbl->seq.next_id))
+       if (json_get_object(root, tbl->name, &root))
                return;
-       if (json_get_array(root, tbl->name, &array))
+
+       if (json_get_seq(root, "seq", &tbl->seq)) {
+               // XXX this is grouds to reset the cache...
+               pr_op_warn("Unable to load the 'seq' child for the %s table.",
+                   tbl->name);
+               return;
+       }
+       if (json_get_array(root, "nodes", &array)) {
+               pr_op_warn("Unable to load the 'nodes' child for the %s table.",
+                   tbl->name);
                return;
+       }
 
        json_array_foreach(array, index, child) {
                node = json2node(child);
@@ -564,7 +573,7 @@ tbl2json(struct cache_table *tbl)
        if (!json)
                return NULL;
 
-       if (json_add_ulong(json, "next", tbl->seq.next_id))
+       if (json_add_seq(json, "seq", &tbl->seq))
                goto fail;
 
        nodes = json_array_new();
index 98f224ab3ed54b88fa46e9042aa4c6d4d2f4b81f..970de0ed43df6614114a9e93fad3fe3155277c53 100644 (file)
@@ -252,6 +252,13 @@ cseq_init(struct cache_sequence *seq, char *prefix, bool free_prefix)
        seq->free_prefix = free_prefix;
 }
 
+void
+cseq_cleanup(struct cache_sequence *seq)
+{
+       if (seq->free_prefix)
+               free(seq->prefix);
+}
+
 char *
 cseq_next(struct cache_sequence *seq)
 {
index 6cdf2604e15702a2004b38a6261ec239eb0183a5..a615d48914fb4d387cc7f2206c8717f3beb64647 100644 (file)
@@ -47,6 +47,7 @@ struct cache_sequence {
 };
 
 void cseq_init(struct cache_sequence *, char *, bool);
+void cseq_cleanup(struct cache_sequence *);
 char *cseq_next(struct cache_sequence *);
 
 /*
index 0f2a3d705dccd771867e0a38f9c87003e275f6e8..4d2173a56834bf737c41daca78852d52a552c74b 100644 (file)
@@ -4,6 +4,7 @@
 #include <limits.h>
 #include <time.h>
 
+#include "alloc.h"
 #include "common.h"
 #include "log.h"
 
@@ -170,6 +171,35 @@ json_get_object(json_t *parent, char const *name, json_t **obj)
        return 0;
 }
 
+int
+json_get_seq(json_t *parent, char const *name, struct cache_sequence *seq)
+{
+       json_t *child;
+       char const *pfx;
+       int error;
+
+       error = json_get_object(parent, name, &child);
+       if (error)
+               return error;
+
+       error = json_get_str(child, "pfx", &pfx);
+       if (error < 0)
+               return error;
+       if (error > 0)
+               return pr_op_err(
+                   "The '%s' JSON object is missing mandatory child 'pfx'.",
+                   name
+               );
+       error = json_get_ulong(child, "next", &seq->next_id);
+       if (error < 0)
+               return error;
+
+       seq->prefix = pstrdup(pfx);
+       seq->pathlen = strlen(pfx) + 4;
+       seq->free_prefix = true;
+       return 0;
+}
+
 /*
  * Any unknown members should be treated as errors, RFC8416 3.1:
  * "JSON members that are not defined here MUST NOT be used in SLURM
@@ -256,6 +286,33 @@ json_add_ts(json_t *parent, char const *name, time_t value)
        return 0;
 }
 
+int
+json_add_seq(json_t *parent, char const *name,
+    struct cache_sequence const *value)
+{
+       json_t *seq;
+
+       seq = json_obj_new();
+       if (seq == NULL)
+               return -EINVAL;
+
+       if (json_add_ulong(seq, "next", value->next_id))
+               goto fail;
+       if (json_add_str(seq, "pfx", value->prefix))
+               goto fail;
+
+       if (json_object_set_new(parent, name, seq))
+               return pr_op_err(
+                   "Cannot convert sequence [%s, %lu] to json; unknown cause.",
+                   value->prefix, value->next_id
+               );
+
+       return 0;
+
+fail:  json_decref(seq);
+       return -EINVAL;
+}
+
 #define OOM_PFX " Likely out of memory (but there is no contract)."
 
 json_t *
index 6dfb7566148509437749ea4cee7d7d21eb426ef0..7d0261b6f7f8a4bd2ece040727cfd1023ef4a234 100644 (file)
@@ -17,6 +17,7 @@
 #include <unistd.h>
 
 #include "asn1/asn1c/INTEGER.h"
+#include "file.h"
 
 /*
  * Contract of get functions:
@@ -34,6 +35,7 @@ int json_get_ts(json_t *, char const *, time_t *);
 int json_get_str(json_t *, char const *, char const **);
 int json_get_array(json_t *, char const *, json_t **);
 int json_get_object(json_t *, char const *, json_t **);
+int json_get_seq(json_t *, char const *, struct cache_sequence *);
 
 bool json_valid_members_count(json_t *, size_t);
 
@@ -42,6 +44,7 @@ int json_add_ulong(json_t *, char const *, unsigned long);
 int json_add_bigint(json_t *, char const *, INTEGER_t *);
 int json_add_str(json_t *, char const *, char const *);
 int json_add_ts(json_t *, char const *, time_t);
+int json_add_seq(json_t *, char const *, struct cache_sequence const *);
 
 json_t *json_obj_new(void);
 json_t *json_array_new(void);
index 4c38952f148129693a9fc73e538d25c2d3aeee5c..20e2b49048b1eff70d119769c48241c90936d39d 100644 (file)
@@ -1383,7 +1383,7 @@ rrdp_state2json(struct rrdp_state *state)
        if (state->files)
                if (json_object_add(json, "files", files2json(state)))
                        goto fail;
-       if (json_add_ulong(json, "next", state->seq.next_id))
+       if (json_add_seq(json, "seq", &state->seq))
                goto fail;
        if (!STAILQ_EMPTY(&state->delta_hashes))
                if (json_object_add(json, TAGNAME_DELTAS, dh2json(state)))
@@ -1431,18 +1431,46 @@ clear_delta_hashes(struct rrdp_state *state)
        }
 }
 
+static int
+json2dhs(json_t *json, struct rrdp_state *state)
+{
+       json_t *jdeltas;
+       size_t d, dn;
+       struct rrdp_hash *hash;
+       int error;
+
+       STAILQ_INIT(&state->delta_hashes);
+
+       error = json_get_array(json, TAGNAME_DELTAS, &jdeltas);
+       if (error)
+               return (error > 0) ? 0 : error;
+
+       dn = json_array_size(jdeltas);
+       if (dn == 0)
+               return 0;
+       if (dn > config_get_rrdp_delta_threshold())
+               dn = config_get_rrdp_delta_threshold();
+
+       for (d = 0; d < dn; d++) {
+               error = json2dh(json_array_get(jdeltas, d), &hash);
+               if (error) {
+                       clear_delta_hashes(state);
+                       return error;
+               }
+               STAILQ_INSERT_TAIL(&state->delta_hashes, hash, hook);
+       }
+
+       return 0;
+}
+
 int
 rrdp_json2state(json_t *json, struct rrdp_state **result)
 {
        struct rrdp_state *state;
        char const *str;
-       json_t *jdeltas;
-       size_t d, dn;
-       struct rrdp_hash *hash;
        int error;
 
        state = pzalloc(sizeof(struct rrdp_state));
-       STAILQ_INIT(&state->delta_hashes);
 
        error = json_get_str(json, TAGNAME_SESSION, &str);
        if (error < 0)
@@ -1460,32 +1488,19 @@ rrdp_json2state(json_t *json, struct rrdp_state **result)
                goto revert_serial;
        }
 
-       error = json_get_array(json, TAGNAME_DELTAS, &jdeltas);
-       if (error) {
-               if (error > 0)
-                       goto success;
+       error = json_get_seq(json, "seq", &state->seq);
+       if (error)
                goto revert_serial;
-       }
 
-       dn = json_array_size(jdeltas);
-       if (dn == 0)
-               goto success;
-       if (dn > config_get_rrdp_delta_threshold())
-               dn = config_get_rrdp_delta_threshold();
-
-       for (d = 0; d < dn; d++) {
-               error = json2dh(json_array_get(jdeltas, d), &hash);
-               if (error)
-                       goto revert_deltas;
-               STAILQ_INSERT_TAIL(&state->delta_hashes, hash, hook);
-       }
+       error = json2dhs(json, state);
+       if (error)
+               goto revert_seq;
 
-success:
        *result = state;
        return 0;
 
-revert_deltas:
-       clear_delta_hashes(state);
+revert_seq:
+       cseq_cleanup(&state->seq);
 revert_serial:
        BN_free(state->session.serial.num);
        free(state->session.serial.str);
@@ -1510,8 +1525,7 @@ rrdp_state_free(struct rrdp_state *state)
                map_cleanup(&file->map);
                free(file);
        }
-       if (state->seq.free_prefix)
-               free(state->seq.prefix);
+       cseq_cleanup(&state->seq);
        clear_delta_hashes(state);
        free(state);
 }