]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add struct asn_range
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 7 Jul 2023 19:16:04 +0000 (13:16 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 7 Jul 2023 19:18:13 +0000 (13:18 -0600)
Slightly improves code that needs to deal with groups of contiguous
ASNs.

Also adds a bunch of healthy consts here and there.

Part of a series of patches meant to manually rebase the issue58-proper
branch.

18 files changed:
src/Makefile.am
src/as_number.h [new file with mode: 0644]
src/object/bgpsec.c
src/resource.c
src/resource.h
src/resource/asn.c
src/resource/asn.h
src/resource/ip4.c
src/resource/ip4.h
src/resource/ip6.c
src/resource/ip6.h
src/rtr/db/vrps.c
src/rtr/db/vrps.h
src/sorted_array.c
src/sorted_array.h
src/validation_handler.c
src/validation_handler.h
test/rtr/db/rtr_db_mock.c

index a9d542beaaa0b919a587cf5f311f11fd8bf90c62..bb77d2ada840a5875bfa8a46213332c70e08db79 100644 (file)
@@ -6,6 +6,7 @@ bin_PROGRAMS = fort
 
 fort_SOURCES  = main.c
 
+fort_SOURCES += as_number.h
 fort_SOURCES += algorithm.h algorithm.c
 fort_SOURCES += alloc.h alloc.c
 fort_SOURCES += certificate_refs.h certificate_refs.c
diff --git a/src/as_number.h b/src/as_number.h
new file mode 100644 (file)
index 0000000..65af922
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef SRC_AS_NUMBER_H_
+#define SRC_AS_NUMBER_H_
+
+#include <stdint.h>
+
+struct asn_range {
+       uint32_t min;
+       uint32_t max;
+};
+
+#endif /* SRC_AS_NUMBER_H_ */
index 638b3bb3f90235c607ba55b94eef986284d31fe4..104b9d1a16bb2874154de82e4191a51b2edbba30 100644 (file)
@@ -5,21 +5,21 @@
 #include "validation_handler.h"
 
 struct resource_params {
-       unsigned char const     *ski;
-       unsigned char const     *spk;
-       struct resources        *resources;
+       unsigned char const *ski;
+       unsigned char const *spk;
+       struct resources *parent_resources;
 };
 
 static int
-asn_cb(unsigned long asn, void *arg)
+asn_cb(struct asn_range const *range, void *arg)
 {
        struct resource_params *params = arg;
 
-       if (!resources_contains_asn(params->resources, asn))
-               return pr_val_err("BGPsec certificate is not allowed for ASN %lu.",
-                   asn);
+       if (!resources_contains_asns(params->parent_resources, range))
+               return pr_val_err("BGPsec certificate is not allowed to contain ASN range %u-%u.",
+                   range->min, range->max);
 
-       return vhandler_handle_router_key(params->ski, asn, params->spk);
+       return vhandler_handle_router_key(params->ski, range, params->spk);
 }
 
 int
@@ -29,7 +29,7 @@ handle_bgpsec(X509 *cert, unsigned char const *ski, struct resources *resources)
        X509_PUBKEY *pub_key;
        unsigned char *cert_spk, *tmp;
        int cert_spk_len;
-       int ok;
+       int error;
 
        pub_key = X509_get_X509_PUBKEY(cert);
        if (pub_key == NULL)
@@ -45,9 +45,9 @@ handle_bgpsec(X509 *cert, unsigned char const *ski, struct resources *resources)
 
        res_params.spk = cert_spk;
        res_params.ski = ski;
-       res_params.resources = resources;
+       res_params.parent_resources = resources;
 
-       ok = resources_foreach_asn(resources, asn_cb, &res_params);
+       error = resources_foreach_asn(resources, asn_cb, &res_params);
        free(cert_spk);
-       return ok;
+       return error;
 }
index 0be670af13d5e9aa30974a6391e70f874a868435..e1818a453be9029332691bc7f64c6240073299a7 100644 (file)
@@ -410,12 +410,13 @@ inherit_asiors(struct resources *resources)
 }
 
 static int
-ASId2ulong(ASId_t *as_id, unsigned long *result)
+ASId2u32(ASId_t *as_id, uint32_t *result)
 {
        static const unsigned long ASN_MAX = UINT32_MAX;
+       unsigned long ulong;
        int error;
 
-       error = asn_INTEGER2ulong(as_id, result);
+       error = asn_INTEGER2ulong(as_id, &ulong);
        if (error) {
                if (errno) {
                        pr_val_err("Error converting ASN value: %s",
@@ -424,31 +425,34 @@ ASId2ulong(ASId_t *as_id, unsigned long *result)
                return pr_val_err("ASN value is not a valid unsigned long");
        }
 
-       if ((*result) > ASN_MAX) {
+       if (ulong > ASN_MAX) {
                return pr_val_err("ASN value '%lu' is out of bounds. (0-%lu)",
-                   *result, ASN_MAX);
+                   ulong, ASN_MAX);
        }
 
+       *result = ulong;
        return 0;
 }
 
 static int
-add_asn(struct resources *resources, unsigned long min, unsigned long max,
+add_asn(struct resources *resources, struct asn_range const *asns,
     struct resources *parent)
 {
        int error;
 
-       if (min > max)
-               return pr_val_err("The ASN range %lu-%lu is inverted.", min, max);
+       if (asns->min > asns->max) {
+               return pr_val_err("The ASN range %u-%u is inverted.",
+                   asns->min, asns->max);
+       }
 
-       if (parent && !rasn_contains(parent->asns, min, max)) {
+       if (parent && !rasn_contains(parent->asns, asns)) {
                switch (resources->policy) {
                case RPKI_POLICY_RFC6484:
-                       return pr_val_err("Parent certificate doesn't own ASN range '%lu-%lu'.",
-                           min, max);
+                       return pr_val_err("Parent certificate doesn't own ASN range '%u-%u'.",
+                           asns->min, asns->max);
                case RPKI_POLICY_RFC8360:
-                       return pr_val_warn("Certificate is overclaiming the ASN range '%lu-%lu'.",
-                           min, max);
+                       return pr_val_warn("Certificate is overclaiming the ASN range '%u-%u'.",
+                           asns->min, asns->max);
                }
        }
 
@@ -458,17 +462,17 @@ add_asn(struct resources *resources, unsigned long min, unsigned long max,
                        enomem_panic();
        }
 
-       error = rasn_add(resources->asns, min, max);
+       error = rasn_add(resources->asns, asns);
        if (error){
-               pr_val_err("Error adding ASN range '%lu-%lu' to certificate resources: %s",
-                   min, max, sarray_err2str(error));
+               pr_val_err("Error adding ASN range '%u-%u' to certificate resources: %s",
+                   asns->min, asns->max, sarray_err2str(error));
                return error;
        }
 
-       if (min == max)
-               pr_val_debug("ASN: %lu", min);
+       if (asns->min == asns->max)
+               pr_val_debug("ASN: %u", asns->min);
        else
-               pr_val_debug("ASN: %lu-%lu", min, max);
+               pr_val_debug("ASN: %u-%u", asns->min, asns->max);
        return 0;
 }
 
@@ -476,8 +480,7 @@ static int
 add_asior(struct resources *resources, struct ASIdOrRange *obj)
 {
        struct resources *parent;
-       unsigned long asn_min;
-       unsigned long asn_max;
+       struct asn_range asns;
        int error;
 
        parent = get_parent_resources();
@@ -490,19 +493,20 @@ add_asior(struct resources *resources, struct ASIdOrRange *obj)
                break;
 
        case ASIdOrRange_PR_id:
-               error = ASId2ulong(&obj->choice.id, &asn_min);
+               error = ASId2u32(&obj->choice.id, &asns.min);
                if (error)
                        return error;
-               return add_asn(resources, asn_min, asn_min, parent);
+               asns.max = asns.min;
+               return add_asn(resources, &asns, parent);
 
        case ASIdOrRange_PR_range:
-               error = ASId2ulong(&obj->choice.range.min, &asn_min);
+               error = ASId2u32(&obj->choice.range.min, &asns.min);
                if (error)
                        return error;
-               error = ASId2ulong(&obj->choice.range.max, &asn_max);
+               error = ASId2u32(&obj->choice.range.max, &asns.max);
                if (error)
                        return error;
-               return add_asn(resources, asn_min, asn_max, parent);
+               return add_asn(resources, &asns, parent);
        }
 
        return pr_val_err("Unknown ASIdOrRange type: %u", obj->present);
@@ -564,19 +568,19 @@ resources_empty(struct resources *res)
 }
 
 bool
-resources_contains_asn(struct resources *res, unsigned long asn)
+resources_contains_asns(struct resources *res, struct asn_range const *range)
 {
-       return rasn_contains(res->asns, asn, asn);
+       return rasn_contains(res->asns, range);
 }
 
 bool
-resources_contains_ipv4(struct resources *res, struct ipv4_prefix *prefix)
+resources_contains_ipv4(struct resources *res, struct ipv4_prefix const *prefix)
 {
        return res4_contains_prefix(res->ip4s, prefix);
 }
 
 bool
-resources_contains_ipv6(struct resources *res, struct ipv6_prefix *prefix)
+resources_contains_ipv6(struct resources *res, struct ipv6_prefix const *prefix)
 {
        return res6_contains_prefix(res->ip6s, prefix);
 }
index e18bed10d36077f8dc1fb9903d3ea63c490899f8..6be0124643547508fc5c5ed567258eb8c245e5d7 100644 (file)
@@ -31,9 +31,9 @@ int resources_add_ip(struct resources *, struct IPAddressFamily *);
 int resources_add_asn(struct resources *, struct ASIdentifiers *, bool);
 
 bool resources_empty(struct resources *);
-bool resources_contains_asn(struct resources *, unsigned long);
-bool resources_contains_ipv4(struct resources *, struct ipv4_prefix *);
-bool resources_contains_ipv6(struct resources *, struct ipv6_prefix *);
+bool resources_contains_asns(struct resources *, struct asn_range const *);
+bool resources_contains_ipv4(struct resources *, struct ipv4_prefix const *);
+bool resources_contains_ipv6(struct resources *, struct ipv6_prefix const *);
 
 enum rpki_policy resources_get_policy(struct resources *);
 void resources_set_policy(struct resources *, enum rpki_policy);
index c80fa89841f893445bc4d515c8210e9ff7b71d2b..6b472064b596a508050b217de8d3c390c3c37c67 100644 (file)
@@ -6,23 +6,18 @@
 #include "log.h"
 #include "sorted_array.h"
 
-struct asn_node {
-       unsigned long min;
-       unsigned long max;
-};
-
 struct asn_cb {
        foreach_asn_cb cb;
        void *arg;
 };
 
 static enum sarray_comparison
-asn_cmp(void *arg1, void *arg2)
+asn_cmp(void const *arg1, void const *arg2)
 {
-       unsigned long n1min = ((struct asn_node *) arg1)->min;
-       unsigned long n1max = ((struct asn_node *) arg1)->max;
-       unsigned long n2min = ((struct asn_node *) arg2)->min;
-       unsigned long n2max = ((struct asn_node *) arg2)->max;
+       uint32_t n1min = ((struct asn_range const *) arg1)->min;
+       uint32_t n1max = ((struct asn_range const *) arg1)->max;
+       uint32_t n2min = ((struct asn_range const *) arg2)->min;
+       uint32_t n2max = ((struct asn_range const *) arg2)->max;
 
        if (n1min == n2min && n1max == n2max)
                return SACMP_EQUAL;
@@ -46,7 +41,7 @@ struct resources_asn *
 rasn_create(void)
 {
        return (struct resources_asn *)
-           sarray_create(sizeof(struct asn_node), asn_cmp);
+           sarray_create(sizeof(struct asn_range), asn_cmp);
 }
 
 void
@@ -62,10 +57,9 @@ rasn_put(struct resources_asn *asns)
 }
 
 int
-rasn_add(struct resources_asn *asns, unsigned long min, unsigned long max)
+rasn_add(struct resources_asn *asns, struct asn_range const *range)
 {
-       struct asn_node n = { min, max };
-       return sarray_add((struct sorted_array *) asns, &n);
+       return sarray_add((struct sorted_array *) asns, range);
 }
 
 bool
@@ -75,44 +69,22 @@ rasn_empty(struct resources_asn *asns)
 }
 
 bool
-rasn_contains(struct resources_asn *asns, unsigned long min, unsigned long max)
+rasn_contains(struct resources_asn *asns, struct asn_range const *range)
 {
-       struct asn_node n = { min, max };
-       return sarray_contains((struct sorted_array *) asns, &n);
+       return sarray_contains((struct sorted_array *) asns, range);
 }
 
 static int
-asn_node_cb(void *elem, void *arg)
+asn_range_cb(void *node, void *arg)
 {
-       struct asn_node *node = elem;
        struct asn_cb *param = arg;
-       unsigned long index;
-       int error;
-
-       for (index = node->min; index <= node->max; index++) {
-               error = param->cb(index, param->arg);
-               if (error)
-                       return error;
-               if (index == ULONG_MAX)
-                       break;
-       }
-
-       return 0;
+       return param->cb(node, param->arg);
 }
 
 int
 rasn_foreach(struct resources_asn *asns, foreach_asn_cb cb, void *arg)
 {
-       struct asn_cb param;
-       int error;
-
-       param.cb = cb;
-       param.arg = arg;
-
-       rasn_get(asns);
-       error = sarray_foreach((struct sorted_array *) asns, asn_node_cb,
+       struct asn_cb param = { .cb = cb, .arg = arg };
+       return sarray_foreach((struct sorted_array *) asns, asn_range_cb,
            &param);
-       rasn_put(asns);
-
-       return error;
 }
index 42c9dc44f1ae7f2179eac93961cc9787d223d785..665f40023d76b692c0b86d5131df82f99df5bac0 100644 (file)
@@ -2,19 +2,30 @@
 #define SRC_RESOURCE_ASN_H_
 
 #include <stdbool.h>
+#include "as_number.h"
 #include "asn1/asn1c/ASId.h"
 
+/*
+ * Implementation note: This is just a casted struct sorted_array.
+ * Why? Because this module doesn't have anything to add.
+ * Why not make the methods return a sorted_array? Because they're not meant to
+ * be tied to the sorted array implementation.
+ * Why not convert this into a structure that contains a sorted_array? Because
+ * sorted_array is private, so resources_asn would have to contain a pointer to
+ * it, which is another level of indirection, which is slightly wasted
+ * performance.
+ */
 struct resources_asn;
 
 struct resources_asn *rasn_create(void);
 void rasn_get(struct resources_asn *);
 void rasn_put(struct resources_asn *);
 
-int rasn_add(struct resources_asn *, unsigned long, unsigned long);
+int rasn_add(struct resources_asn *, struct asn_range const *);
 bool rasn_empty(struct resources_asn *);
-bool rasn_contains(struct resources_asn *, unsigned long, unsigned long);
+bool rasn_contains(struct resources_asn *, struct asn_range const *);
 
-typedef int (*foreach_asn_cb)(unsigned long, void *);
+typedef int (*foreach_asn_cb)(struct asn_range const *, void *);
 int rasn_foreach(struct resources_asn *, foreach_asn_cb, void *);
 
 #endif /* SRC_RESOURCE_ASN_H_ */
index ff0201bb957260ce7dac9a7395308029b3c36da8..b1109dd0e4bd0bb8fc7127648b91d80b898d0828 100644 (file)
@@ -8,12 +8,12 @@ struct r4_node {
 };
 
 static enum sarray_comparison
-r4_cmp(void *arg1, void *arg2)
+r4_cmp(void const *arg1, void const *arg2)
 {
-       uint32_t n1min = ((struct r4_node *) arg1)->min;
-       uint32_t n2min = ((struct r4_node *) arg2)->min;
-       uint32_t n1max = ((struct r4_node *) arg1)->max;
-       uint32_t n2max = ((struct r4_node *) arg2)->max;
+       uint32_t n1min = ((struct r4_node const *) arg1)->min;
+       uint32_t n2min = ((struct r4_node const *) arg2)->min;
+       uint32_t n1max = ((struct r4_node const *) arg1)->max;
+       uint32_t n2max = ((struct r4_node const *) arg2)->max;
 
        if (n1min == n2min && n1max == n2max)
                return SACMP_EQUAL;
@@ -34,14 +34,14 @@ r4_cmp(void *arg1, void *arg2)
 }
 
 static void
-pton(struct ipv4_prefix *p, struct r4_node *n)
+pton(struct ipv4_prefix const *p, struct r4_node *n)
 {
        n->min = ntohl(p->addr.s_addr);
        n->max = n->min | u32_suffix_mask(p->len);
 }
 
 static void
-rton(struct ipv4_range *r, struct r4_node *n)
+rton(struct ipv4_range const *r, struct r4_node *n)
 {
        n->min = ntohl(r->min.s_addr);
        n->max = ntohl(r->max.s_addr);
@@ -67,7 +67,7 @@ res4_put(struct resources_ipv4 *ips)
 }
 
 int
-res4_add_prefix(struct resources_ipv4 *ips, struct ipv4_prefix *prefix)
+res4_add_prefix(struct resources_ipv4 *ips, struct ipv4_prefix const *prefix)
 {
        struct r4_node n;
        pton(prefix, &n);
@@ -75,7 +75,7 @@ res4_add_prefix(struct resources_ipv4 *ips, struct ipv4_prefix *prefix)
 }
 
 int
-res4_add_range(struct resources_ipv4 *ips, struct ipv4_range *range)
+res4_add_range(struct resources_ipv4 *ips, struct ipv4_range const *range)
 {
        struct r4_node n;
        rton(range, &n);
@@ -83,13 +83,14 @@ res4_add_range(struct resources_ipv4 *ips, struct ipv4_range *range)
 }
 
 bool
-res4_empty(struct resources_ipv4 *ips)
+res4_empty(struct resources_ipv4 const *ips)
 {
-       return sarray_empty((struct sorted_array *) ips);
+       return sarray_empty((struct sorted_array const *) ips);
 }
 
 bool
-res4_contains_prefix(struct resources_ipv4 *ips, struct ipv4_prefix *prefix)
+res4_contains_prefix(struct resources_ipv4 *ips,
+    struct ipv4_prefix const *prefix)
 {
        struct r4_node n;
 
@@ -101,7 +102,7 @@ res4_contains_prefix(struct resources_ipv4 *ips, struct ipv4_prefix *prefix)
 }
 
 bool
-res4_contains_range(struct resources_ipv4 *ips, struct ipv4_range *range)
+res4_contains_range(struct resources_ipv4 *ips, struct ipv4_range const *range)
 {
        struct r4_node n;
        rton(range, &n);
index 861e888f749e0e05a51cf5ad1a30e7503469541b..5a9a871e70829c94e20fa1fdffa9e17cd63e88cf 100644 (file)
@@ -10,10 +10,10 @@ struct resources_ipv4 *res4_create(void);
 void res4_get(struct resources_ipv4 *);
 void res4_put(struct resources_ipv4 *);
 
-int res4_add_prefix(struct resources_ipv4 *, struct ipv4_prefix *);
-int res4_add_range(struct resources_ipv4 *, struct ipv4_range *);
-bool res4_empty(struct resources_ipv4 *);
-bool res4_contains_prefix(struct resources_ipv4 *, struct ipv4_prefix *);
-bool res4_contains_range(struct resources_ipv4 *, struct ipv4_range *);
+int res4_add_prefix(struct resources_ipv4 *, struct ipv4_prefix const *);
+int res4_add_range(struct resources_ipv4 *, struct ipv4_range const *);
+bool res4_empty(struct resources_ipv4 const *);
+bool res4_contains_prefix(struct resources_ipv4 *, struct ipv4_prefix const *);
+bool res4_contains_range(struct resources_ipv4 *, struct ipv4_range const *);
 
 #endif /* SRC_RESOURCE_IP4_H_ */
index f73d84d2b73842d1b37e5578fbe5e1e2d3e6cc58..81ed83649204a7da33775167c61b775da470689c 100644 (file)
@@ -51,12 +51,12 @@ addr_is_successor(struct in6_addr const *a, struct in6_addr const *b)
 }
 
 static enum sarray_comparison
-r6_cmp(void *arg1, void *arg2)
+r6_cmp(void const *arg1, void const *arg2)
 {
-       struct in6_addr const *a1min = &((struct ipv6_range *) arg1)->min;
-       struct in6_addr const *a2min = &((struct ipv6_range *) arg2)->min;
-       struct in6_addr const *a1max = &((struct ipv6_range *) arg1)->max;
-       struct in6_addr const *a2max = &((struct ipv6_range *) arg2)->max;
+       struct in6_addr const *a1min = &((struct ipv6_range const *) arg1)->min;
+       struct in6_addr const *a2min = &((struct ipv6_range const *) arg2)->min;
+       struct in6_addr const *a1max = &((struct ipv6_range const *) arg1)->max;
+       struct in6_addr const *a2max = &((struct ipv6_range const *) arg2)->max;
 
        if (addr_equals(a1min, a2min) && addr_equals(a1max, a2max))
                return SACMP_EQUAL;
@@ -104,7 +104,7 @@ res6_put(struct resources_ipv6 *ips)
 }
 
 int
-res6_add_prefix(struct resources_ipv6 *ips, struct ipv6_prefix *prefix)
+res6_add_prefix(struct resources_ipv6 *ips, struct ipv6_prefix const *prefix)
 {
        struct ipv6_range r;
        ptor(prefix, &r);
@@ -112,19 +112,20 @@ res6_add_prefix(struct resources_ipv6 *ips, struct ipv6_prefix *prefix)
 }
 
 int
-res6_add_range(struct resources_ipv6 *ips, struct ipv6_range *range)
+res6_add_range(struct resources_ipv6 *ips, struct ipv6_range const *range)
 {
        return sarray_add((struct sorted_array *) ips, range);
 }
 
 bool
-res6_empty(struct resources_ipv6 *ips)
+res6_empty(struct resources_ipv6 const *ips)
 {
-       return sarray_empty((struct sorted_array *) ips);
+       return sarray_empty((struct sorted_array const *) ips);
 }
 
 bool
-res6_contains_prefix(struct resources_ipv6 *ips, struct ipv6_prefix *prefix)
+res6_contains_prefix(struct resources_ipv6 *ips,
+    struct ipv6_prefix const *prefix)
 {
        struct ipv6_range r;
        ptor(prefix, &r);
@@ -132,7 +133,7 @@ res6_contains_prefix(struct resources_ipv6 *ips, struct ipv6_prefix *prefix)
 }
 
 bool
-res6_contains_range(struct resources_ipv6 *ips, struct ipv6_range *range)
+res6_contains_range(struct resources_ipv6 *ips, struct ipv6_range const *range)
 {
        return sarray_contains((struct sorted_array *) ips, range);
 }
index ce962110e7ce9ef9cb3db756cb68238ec4139380..b1530c6e397ae76616f58c2f9930af46221b81d0 100644 (file)
@@ -10,10 +10,10 @@ struct resources_ipv6 *res6_create(void);
 void res6_get(struct resources_ipv6 *);
 void res6_put(struct resources_ipv6 *);
 
-int res6_add_prefix(struct resources_ipv6 *ps, struct ipv6_prefix *);
-int res6_add_range(struct resources_ipv6 *, struct ipv6_range *);
-bool res6_empty(struct resources_ipv6 *ips);
-bool res6_contains_prefix(struct resources_ipv6 *, struct ipv6_prefix *);
-bool res6_contains_range(struct resources_ipv6 *, struct ipv6_range *);
+int res6_add_prefix(struct resources_ipv6 *ps, struct ipv6_prefix const *);
+int res6_add_range(struct resources_ipv6 *, struct ipv6_range const *);
+bool res6_empty(struct resources_ipv6 const *ips);
+bool res6_contains_prefix(struct resources_ipv6 *, struct ipv6_prefix const *);
+bool res6_contains_range(struct resources_ipv6 *, struct ipv6_range const *);
 
 #endif /* SRC_RESOURCE_IP6_H_ */
index 90c61d02d052dcd914216ef17f7afcb1b499aba5..dd1c9091a4c801ed81b736b0e2c856a039ee23bf 100644 (file)
@@ -191,10 +191,27 @@ handle_roa_v6(uint32_t as, struct ipv6_prefix const * prefix,
 }
 
 int
-handle_router_key(unsigned char const *ski, uint32_t as,
+handle_router_key(unsigned char const *ski, struct asn_range const *asns,
     unsigned char const *spk, void *arg)
 {
-       WLOCK_HANDLER(rtrhandler_handle_router_key(arg, ski, as, spk))
+       uint64_t asn;
+       int error = 0;
+
+       mutex_lock(&table_lock);
+
+       /*
+        * TODO (warning) Umm... this is begging for a limit.
+        * If the issuer gets it wrong, we can iterate up to 2^32 times.
+        * The RFCs don't seem to care about this.
+        */
+       for (asn = asns->min; asn <= asns->max; asn++) {
+               error = rtrhandler_handle_router_key(arg, ski, asn, spk);
+               if (error)
+                       break;
+       }
+
+       mutex_unlock(&table_lock);
+       return error;
 }
 
 static int
index f3698bb09797549768464cfb81a766e933071e84..4a82c7800310c58106463d00f390a21d1a6649b8 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <stdbool.h>
+#include "as_number.h"
 #include "types/address.h"
 #include "rtr/db/deltas_array.h"
 
@@ -29,8 +30,8 @@ int get_last_serial_number(serial_t *);
 
 int handle_roa_v4(uint32_t, struct ipv4_prefix const *, uint8_t, void *);
 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 *);
+int handle_router_key(unsigned char const *, struct asn_range const *,
+    unsigned char const *, void *);
 
 uint16_t get_current_session_id(uint8_t);
 
index add39180299948e44d5a4547b56494a3a2cc8d50..24de54f4d9dc1b0b4b111c1d3e0c36283cfc4561 100644 (file)
@@ -56,7 +56,7 @@ sarray_put(struct sorted_array *sarray)
 
 /* Does not check boundaries. */
 static void *
-get_nth_element(struct sorted_array *sarray, unsigned int index)
+get_nth_element(struct sorted_array const *sarray, unsigned int index)
 {
        return ((char *)sarray->array) + index * sarray->size;
 }
@@ -67,7 +67,7 @@ get_nth_element(struct sorted_array *sarray, unsigned int index)
  * @array.)
  */
 static int
-compare(struct sorted_array *sarray, void *new)
+compare(struct sorted_array *sarray, void const *new)
 {
        enum sarray_comparison cmp;
 
@@ -98,7 +98,7 @@ compare(struct sorted_array *sarray, void *new)
 }
 
 int
-sarray_add(struct sorted_array *sarray, void *element)
+sarray_add(struct sorted_array *sarray, void const *element)
 {
        int error;
 
@@ -118,13 +118,13 @@ sarray_add(struct sorted_array *sarray, void *element)
 }
 
 bool
-sarray_empty(struct sorted_array *sarray)
+sarray_empty(struct sorted_array const *sarray)
 {
        return (sarray == NULL) || (sarray->count == 0);
 }
 
 bool
-sarray_contains(struct sorted_array *sarray, void *elem)
+sarray_contains(struct sorted_array const *sarray, void const *elem)
 {
        unsigned int left, mid, right;
        enum sarray_comparison cmp;
index 41fd9d1e29d1694d931410ca5dc8374fe9a34c6a..b06a685d642dfcdbc9c64d3158e7c3f19845f5dd 100644 (file)
@@ -24,7 +24,7 @@ enum sarray_comparison {
        SACMP_INTERSECTION,
 };
 
-typedef enum sarray_comparison (*sarray_cmp)(void *, void *);
+typedef enum sarray_comparison (*sarray_cmp)(void const *, void const *);
 
 struct sorted_array *sarray_create(size_t, sarray_cmp);
 void sarray_get(struct sorted_array *);
@@ -38,9 +38,9 @@ void sarray_put(struct sorted_array *);
 #define EADJRIGHT      7899
 #define EINTERSECTION  7900
 
-int sarray_add(struct sorted_array *, void *);
-bool sarray_empty(struct sorted_array *);
-bool sarray_contains(struct sorted_array *, void *);
+int sarray_add(struct sorted_array *, void const *);
+bool sarray_empty(struct sorted_array const *);
+bool sarray_contains(struct sorted_array const *, void const *);
 
 typedef int (*sarray_foreach_cb)(void *, void *);
 int sarray_foreach(struct sorted_array *, sarray_foreach_cb, void *);
index 9461f8f0a952abc86511288fa6377df0c265d987..34d074ac2be7b2684ee1c1f1758f8bfc34229618 100644 (file)
@@ -46,14 +46,14 @@ vhandler_handle_roa_v6(uint32_t as, struct ipv6_prefix const *prefix,
 }
 
 int
-vhandler_handle_router_key(unsigned char const *ski, uint32_t as,
-    unsigned char const *spk)
+vhandler_handle_router_key(unsigned char const *ski,
+    struct asn_range const *asns, unsigned char const *spk)
 {
        struct validation_handler const *handler;
 
        handler = get_current_threads_handler();
 
        return (handler->handle_router_key != NULL)
-           ? handler->handle_router_key(ski, as, spk, handler->arg)
+           ? handler->handle_router_key(ski, asns, spk, handler->arg)
            : 0;
 }
index 542a64f03da98e890308145b42607fbfb5ca1016..e70ca1ad55b621f854234df0ca295f1ced185762 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SRC_VALIDATION_HANDLER_H_
 #define SRC_VALIDATION_HANDLER_H_
 
+#include "as_number.h"
 #include "types/address.h"
 #include "types/router_key.h"
 #include "object/name.h"
@@ -30,15 +31,15 @@ struct validation_handler {
        int (*handle_roa_v6)(uint32_t, struct ipv6_prefix const *, uint8_t,
            void *);
        /** Called every time Fort has successfully validated a BGPsec cert */
-       int (*handle_router_key)(unsigned char const *, uint32_t,
-           unsigned char const *, void *);
+       int (*handle_router_key)(unsigned char const *,
+           struct asn_range const *, unsigned char const *, void *);
        /** Generic user-defined argument for the functions above. */
        void *arg;
 };
 
 int vhandler_handle_roa_v4(uint32_t, struct ipv4_prefix const *, uint8_t);
 int vhandler_handle_roa_v6(uint32_t, struct ipv6_prefix const *, uint8_t);
-int vhandler_handle_router_key(unsigned char const *, uint32_t,
+int vhandler_handle_router_key(unsigned char const *, struct asn_range const *,
     unsigned char const *);
 
 #endif /* SRC_VALIDATION_HANDLER_H_ */
index b9e9c5a39ab1d1b2a4f99fb579dbb52cac672917..58e1a6d4e2f9ea897d6d59496d0775081d08d48b 100644 (file)
@@ -44,7 +44,8 @@ add_v6(struct validation_handler *handler, uint32_t as)
 static void
 add_rk(struct validation_handler *handler, uint32_t as)
 {
-       ck_assert_int_eq(0, handler->handle_router_key(db_imp_ski, as,
+       struct asn_range range = { .min = as, .max = as };
+       ck_assert_int_eq(0, handler->handle_router_key(db_imp_ski, &range,
            db_imp_spk, handler->arg));
 }
 
@@ -63,10 +64,19 @@ __handle_roa_v6(uint32_t as, struct ipv6_prefix const *prefix,
 }
 
 int
-__handle_router_key(unsigned char const *ski, uint32_t as,
+__handle_router_key(unsigned char const *ski, struct asn_range const *range,
     unsigned char const *spk, void *arg)
 {
-       return rtrhandler_handle_router_key(arg, ski, as, spk);
+       uint64_t as;
+       int error;
+
+       for (as = range->min; as <= range->max; as++) {
+               error = rtrhandler_handle_router_key(arg, ski, as, spk);
+               if (error)
+                       break;
+       }
+
+       return error;
 }
 
 int