Noticed the other day. The ip addr arrays and as number array are
marshalled element by element which is not very efficent.
All the data is in one big blob of memory so just use the basic io
operations for a memory blob and ship the full array at once.

This seems to reduce runtime by 5-10% (in my unscientific testing).
Also it makes the code a fair bit simpler.
-- 
:wq Claudio

Index: cert.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.46
diff -u -p -r1.46 cert.c
--- cert.c      4 Nov 2021 11:32:55 -0000       1.46
+++ cert.c      5 Nov 2021 07:53:50 -0000
@@ -1225,34 +1225,6 @@ cert_free(struct cert *p)
        free(p);
 }
 
-static void
-cert_ip_buffer(struct ibuf *b, const struct cert_ip *p)
-{
-       io_simple_buffer(b, &p->afi, sizeof(enum afi));
-       io_simple_buffer(b, &p->type, sizeof(enum cert_ip_type));
-
-       if (p->type != CERT_IP_INHERIT) {
-               io_simple_buffer(b, &p->min, sizeof(p->min));
-               io_simple_buffer(b, &p->max, sizeof(p->max));
-       }
-
-       if (p->type == CERT_IP_RANGE)
-               ip_addr_range_buffer(b, &p->range);
-       else if (p->type == CERT_IP_ADDR)
-               ip_addr_buffer(b, &p->ip);
-}
-
-static void
-cert_as_buffer(struct ibuf *b, const struct cert_as *p)
-{
-       io_simple_buffer(b, &p->type, sizeof(enum cert_as_type));
-       if (p->type == CERT_AS_RANGE) {
-               io_simple_buffer(b, &p->range.min, sizeof(uint32_t));
-               io_simple_buffer(b, &p->range.max, sizeof(uint32_t));
-       } else if (p->type == CERT_AS_ID)
-               io_simple_buffer(b, &p->id, sizeof(uint32_t));
-}
-
 /*
  * Write certificate parsed content into buffer.
  * See cert_read() for the other side of the pipe.
@@ -1260,18 +1232,15 @@ cert_as_buffer(struct ibuf *b, const str
 void
 cert_buffer(struct ibuf *b, const struct cert *p)
 {
-       size_t   i;
-
        io_simple_buffer(b, &p->expires, sizeof(p->expires));
        io_simple_buffer(b, &p->purpose, sizeof(p->purpose));
        io_simple_buffer(b, &p->talid, sizeof(p->talid));
        io_simple_buffer(b, &p->ipsz, sizeof(p->ipsz));
-       for (i = 0; i < p->ipsz; i++)
-               cert_ip_buffer(b, &p->ips[i]);
-
        io_simple_buffer(b, &p->asz, sizeof(p->asz));
-       for (i = 0; i < p->asz; i++)
-               cert_as_buffer(b, &p->as[i]);
+
+       io_simple_buffer(b, p->ips, p->ipsz * sizeof(p->ips[0]));
+       io_simple_buffer(b, p->as, p->asz * sizeof(p->as[0]));
+
        io_str_buffer(b, p->mft);
        io_str_buffer(b, p->notify);
        io_str_buffer(b, p->repo);
@@ -1282,34 +1251,6 @@ cert_buffer(struct ibuf *b, const struct
        io_str_buffer(b, p->pubkey);
 }
 
-static void
-cert_ip_read(struct ibuf *b, struct cert_ip *p)
-{
-       io_read_buf(b, &p->afi, sizeof(enum afi));
-       io_read_buf(b, &p->type, sizeof(enum cert_ip_type));
-
-       if (p->type != CERT_IP_INHERIT) {
-               io_read_buf(b, &p->min, sizeof(p->min));
-               io_read_buf(b, &p->max, sizeof(p->max));
-       }
-
-       if (p->type == CERT_IP_RANGE)
-               ip_addr_range_read(b, &p->range);
-       else if (p->type == CERT_IP_ADDR)
-               ip_addr_read(b, &p->ip);
-}
-
-static void
-cert_as_read(struct ibuf *b, struct cert_as *p)
-{
-       io_read_buf(b, &p->type, sizeof(enum cert_as_type));
-       if (p->type == CERT_AS_RANGE) {
-               io_read_buf(b, &p->range.min, sizeof(uint32_t));
-               io_read_buf(b, &p->range.max, sizeof(uint32_t));
-       } else if (p->type == CERT_AS_ID)
-               io_read_buf(b, &p->id, sizeof(uint32_t));
-}
-
 /*
  * Allocate and read parsed certificate content from descriptor.
  * The pointer must be freed with cert_free().
@@ -1319,7 +1260,6 @@ struct cert *
 cert_read(struct ibuf *b)
 {
        struct cert     *p;
-       size_t           i;
 
        if ((p = calloc(1, sizeof(struct cert))) == NULL)
                err(1, NULL);
@@ -1328,19 +1268,17 @@ cert_read(struct ibuf *b)
        io_read_buf(b, &p->purpose, sizeof(p->purpose));
        io_read_buf(b, &p->talid, sizeof(p->talid));
        io_read_buf(b, &p->ipsz, sizeof(p->ipsz));
+       io_read_buf(b, &p->asz, sizeof(p->asz));
 
        p->ips = calloc(p->ipsz, sizeof(struct cert_ip));
        if (p->ips == NULL)
                err(1, NULL);
-       for (i = 0; i < p->ipsz; i++)
-               cert_ip_read(b, &p->ips[i]);
+       io_read_buf(b, p->ips, p->ipsz * sizeof(p->ips[0]));
 
-       io_read_buf(b, &p->asz, sizeof(p->asz));
        p->as = calloc(p->asz, sizeof(struct cert_as));
        if (p->as == NULL)
                err(1, NULL);
-       for (i = 0; i < p->asz; i++)
-               cert_as_read(b, &p->as[i]);
+       io_read_buf(b, p->as, p->asz * sizeof(p->as[0]));
 
        io_read_str(b, &p->mft);
        io_read_str(b, &p->notify);
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.93
diff -u -p -r1.93 extern.h
--- extern.h    4 Nov 2021 14:24:41 -0000       1.93
+++ extern.h    5 Nov 2021 07:53:33 -0000
@@ -463,11 +463,6 @@ int                 ip_addr_parse(const ASN1_BIT_STRIN
                        enum afi, const char *, struct ip_addr *);
 void            ip_addr_print(const struct ip_addr *, enum afi, char *,
                        size_t);
-void            ip_addr_buffer(struct ibuf *, const struct ip_addr *);
-void            ip_addr_range_buffer(struct ibuf *,
-                       const struct ip_addr_range *);
-void            ip_addr_read(struct ibuf *, struct ip_addr *);
-void            ip_addr_range_read(struct ibuf *, struct ip_addr_range *);
 int             ip_addr_cmp(const struct ip_addr *, const struct ip_addr *);
 int             ip_addr_check_overlap(const struct cert_ip *,
                        const char *, const struct cert_ip *, size_t);
Index: ip.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/ip.c,v
retrieving revision 1.18
diff -u -p -r1.18 ip.c
--- ip.c        23 Oct 2021 16:06:04 -0000      1.18
+++ ip.c        5 Nov 2021 07:53:13 -0000
@@ -285,57 +285,6 @@ ip_addr_print(const struct ip_addr *addr
 }
 
 /*
- * Serialise an ip_addr for sending over the wire.
- * Matched with ip_addr_read().
- */
-void
-ip_addr_buffer(struct ibuf *b, const struct ip_addr *p)
-{
-       size_t sz = PREFIX_SIZE(p->prefixlen);
-
-       assert(sz <= 16);
-       io_simple_buffer(b, &p->prefixlen, sizeof(unsigned char));
-       io_simple_buffer(b, p->addr, sz);
-}
-
-/*
- * Serialise an ip_addr_range for sending over the wire.
- * Matched with ip_addr_range_read().
- */
-void
-ip_addr_range_buffer(struct ibuf *b, const struct ip_addr_range *p)
-{
-       ip_addr_buffer(b, &p->min);
-       ip_addr_buffer(b, &p->max);
-}
-
-/*
- * Read an ip_addr from the wire.
- * Matched with ip_addr_buffer().
- */
-void
-ip_addr_read(struct ibuf *b, struct ip_addr *p)
-{
-       size_t sz;
-
-       io_read_buf(b, &p->prefixlen, sizeof(unsigned char));
-       sz = PREFIX_SIZE(p->prefixlen);
-       assert(sz <= 16);
-       io_read_buf(b, p->addr, sz);
-}
-
-/*
- * Read an ip_addr_range from the wire.
- * Matched with ip_addr_range_buffer().
- */
-void
-ip_addr_range_read(struct ibuf *b, struct ip_addr_range *p)
-{
-       ip_addr_read(b, &p->min);
-       ip_addr_read(b, &p->max);
-}
-
-/*
  * Given the addresses (range or IP) in cert_ip, fill in the "min" and
  * "max" fields with the minimum and maximum possible IP addresses given
  * those ranges (or singleton prefixed range).
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.31
diff -u -p -r1.31 roa.c
--- roa.c       4 Nov 2021 11:32:55 -0000       1.31
+++ roa.c       5 Nov 2021 07:54:03 -0000
@@ -419,21 +419,13 @@ roa_free(struct roa *p)
 void
 roa_buffer(struct ibuf *b, const struct roa *p)
 {
-       size_t   i;
-
        io_simple_buffer(b, &p->valid, sizeof(p->valid));
        io_simple_buffer(b, &p->asid, sizeof(p->asid));
        io_simple_buffer(b, &p->talid, sizeof(p->talid));
        io_simple_buffer(b, &p->ipsz, sizeof(p->ipsz));
        io_simple_buffer(b, &p->expires, sizeof(p->expires));
 
-       for (i = 0; i < p->ipsz; i++) {
-               io_simple_buffer(b, &p->ips[i].afi, sizeof(enum afi));
-               io_simple_buffer(b, &p->ips[i].maxlength, sizeof(size_t));
-               io_simple_buffer(b, p->ips[i].min, sizeof(p->ips[i].min));
-               io_simple_buffer(b, p->ips[i].max, sizeof(p->ips[i].max));
-               ip_addr_buffer(b, &p->ips[i].addr);
-       }
+       io_simple_buffer(b, p->ips, p->ipsz * sizeof(p->ips[0]));
 
        io_str_buffer(b, p->aia);
        io_str_buffer(b, p->aki);
@@ -449,7 +441,6 @@ struct roa *
 roa_read(struct ibuf *b)
 {
        struct roa      *p;
-       size_t           i;
 
        if ((p = calloc(1, sizeof(struct roa))) == NULL)
                err(1, NULL);
@@ -462,14 +453,7 @@ roa_read(struct ibuf *b)
 
        if ((p->ips = calloc(p->ipsz, sizeof(struct roa_ip))) == NULL)
                err(1, NULL);
-
-       for (i = 0; i < p->ipsz; i++) {
-               io_read_buf(b, &p->ips[i].afi, sizeof(enum afi));
-               io_read_buf(b, &p->ips[i].maxlength, sizeof(size_t));
-               io_read_buf(b, &p->ips[i].min, sizeof(p->ips[i].min));
-               io_read_buf(b, &p->ips[i].max, sizeof(p->ips[i].max));
-               ip_addr_read(b, &p->ips[i].addr);
-       }
+       io_read_buf(b, p->ips, p->ipsz * sizeof(p->ips[0]));
 
        io_read_str(b, &p->aia);
        io_read_str(b, &p->aki);

Reply via email to