summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rpki-client')
-rw-r--r--usr.sbin/rpki-client/Makefile6
-rw-r--r--usr.sbin/rpki-client/cert.c53
-rw-r--r--usr.sbin/rpki-client/extern.h26
-rw-r--r--usr.sbin/rpki-client/io.c54
-rw-r--r--usr.sbin/rpki-client/ip.c16
-rw-r--r--usr.sbin/rpki-client/main.c224
-rw-r--r--usr.sbin/rpki-client/mft.c19
-rw-r--r--usr.sbin/rpki-client/roa.c30
-rw-r--r--usr.sbin/rpki-client/rsync.c44
-rw-r--r--usr.sbin/rpki-client/tal.c12
10 files changed, 246 insertions, 238 deletions
diff --git a/usr.sbin/rpki-client/Makefile b/usr.sbin/rpki-client/Makefile
index ba83ccaa3c9..151d4889d8a 100644
--- a/usr.sbin/rpki-client/Makefile
+++ b/usr.sbin/rpki-client/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.15 2020/12/09 11:29:04 claudio Exp $
+# $OpenBSD: Makefile,v 1.16 2021/01/08 08:09:07 claudio Exp $
PROG= rpki-client
SRCS= as.c cert.c cms.c crl.c gbr.c io.c ip.c log.c main.c mft.c output.c \
@@ -6,8 +6,8 @@ SRCS= as.c cert.c cms.c crl.c gbr.c io.c ip.c log.c main.c mft.c output.c \
roa.c rsync.c tal.c validate.c x509.c
MAN= rpki-client.8
-LDADD+= -lcrypto
-DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto -lutil
+DPADD+= ${LIBCRYPTO} ${LIBUTIL}
CFLAGS+= -Wall -I${.CURDIR}
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c
index 3023c5a25c7..1d9c2b7b956 100644
--- a/usr.sbin/rpki-client/cert.c
+++ b/usr.sbin/rpki-client/cert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cert.c,v 1.21 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: cert.c,v 1.22 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -1207,7 +1207,6 @@ ta_parse(X509 **xp, const char *fn, const unsigned char *pkey, size_t pkeysz)
void
cert_free(struct cert *p)
{
-
if (p == NULL)
return;
@@ -1223,35 +1222,31 @@ cert_free(struct cert *p)
}
static void
-cert_ip_buffer(char **b, size_t *bsz,
- size_t *bmax, const struct cert_ip *p)
+cert_ip_buffer(struct ibuf *b, const struct cert_ip *p)
{
-
- io_simple_buffer(b, bsz, bmax, &p->afi, sizeof(enum afi));
- io_simple_buffer(b, bsz, bmax, &p->type, sizeof(enum cert_ip_type));
+ 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, bsz, bmax, &p->min, sizeof(p->min));
- io_simple_buffer(b, bsz, bmax, &p->max, sizeof(p->max));
+ 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, bsz, bmax, &p->range);
+ ip_addr_range_buffer(b, &p->range);
else if (p->type == CERT_IP_ADDR)
- ip_addr_buffer(b, bsz, bmax, &p->ip);
+ ip_addr_buffer(b, &p->ip);
}
static void
-cert_as_buffer(char **b, size_t *bsz,
- size_t *bmax, const struct cert_as *p)
+cert_as_buffer(struct ibuf *b, const struct cert_as *p)
{
-
- io_simple_buffer(b, bsz, bmax, &p->type, sizeof(enum cert_as_type));
+ io_simple_buffer(b, &p->type, sizeof(enum cert_as_type));
if (p->type == CERT_AS_RANGE) {
- io_simple_buffer(b, bsz, bmax, &p->range.min, sizeof(uint32_t));
- io_simple_buffer(b, bsz, bmax, &p->range.max, sizeof(uint32_t));
+ 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, bsz, bmax, &p->id, sizeof(uint32_t));
+ io_simple_buffer(b, &p->id, sizeof(uint32_t));
}
/*
@@ -1259,24 +1254,24 @@ cert_as_buffer(char **b, size_t *bsz,
* See cert_read() for the other side of the pipe.
*/
void
-cert_buffer(char **b, size_t *bsz, size_t *bmax, const struct cert *p)
+cert_buffer(struct ibuf *b, const struct cert *p)
{
size_t i;
- io_simple_buffer(b, bsz, bmax, &p->valid, sizeof(int));
- io_simple_buffer(b, bsz, bmax, &p->ipsz, sizeof(size_t));
+ io_simple_buffer(b, &p->valid, sizeof(int));
+ io_simple_buffer(b, &p->ipsz, sizeof(size_t));
for (i = 0; i < p->ipsz; i++)
- cert_ip_buffer(b, bsz, bmax, &p->ips[i]);
+ cert_ip_buffer(b, &p->ips[i]);
- io_simple_buffer(b, bsz, bmax, &p->asz, sizeof(size_t));
+ io_simple_buffer(b, &p->asz, sizeof(size_t));
for (i = 0; i < p->asz; i++)
- cert_as_buffer(b, bsz, bmax, &p->as[i]);
+ cert_as_buffer(b, &p->as[i]);
- io_str_buffer(b, bsz, bmax, p->mft);
- io_str_buffer(b, bsz, bmax, p->notify);
- io_str_buffer(b, bsz, bmax, p->crl);
- io_str_buffer(b, bsz, bmax, p->aki);
- io_str_buffer(b, bsz, bmax, p->ski);
+ io_str_buffer(b, p->mft);
+ io_str_buffer(b, p->notify);
+ io_str_buffer(b, p->crl);
+ io_str_buffer(b, p->aki);
+ io_str_buffer(b, p->ski);
}
static void
diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h
index 8d1510642eb..d0cfdc2a65b 100644
--- a/usr.sbin/rpki-client/extern.h
+++ b/usr.sbin/rpki-client/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.36 2020/12/09 11:29:04 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.37 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -284,30 +284,32 @@ struct stats {
struct timeval system_time;
};
+struct ibuf;
+
/* global variables */
extern int verbose;
/* Routines for RPKI entities. */
-void tal_buffer(char **, size_t *, size_t *, const struct tal *);
+void tal_buffer(struct ibuf *, const struct tal *);
void tal_free(struct tal *);
struct tal *tal_parse(const char *, char *);
char *tal_read_file(const char *);
struct tal *tal_read(int);
-void cert_buffer(char **, size_t *, size_t *, const struct cert *);
+void cert_buffer(struct ibuf *, const struct cert *);
void cert_free(struct cert *);
struct cert *cert_parse(X509 **, const char *, const unsigned char *);
struct cert *ta_parse(X509 **, const char *, const unsigned char *, size_t);
struct cert *cert_read(int);
-void mft_buffer(char **, size_t *, size_t *, const struct mft *);
+void mft_buffer(struct ibuf *, const struct mft *);
void mft_free(struct mft *);
struct mft *mft_parse(X509 **, const char *);
int mft_check(const char *, struct mft *);
struct mft *mft_read(int);
-void roa_buffer(char **, size_t *, size_t *, const struct roa *);
+void roa_buffer(struct ibuf *, const struct roa *);
void roa_free(struct roa *);
struct roa *roa_parse(X509 **, const char *, const unsigned char *);
struct roa *roa_read(int);
@@ -344,9 +346,8 @@ int ip_addr_parse(const ASN1_BIT_STRING *,
enum afi, const char *, struct ip_addr *);
void ip_addr_print(const struct ip_addr *, enum afi, char *,
size_t);
-void ip_addr_buffer(char **, size_t *, size_t *,
- const struct ip_addr *);
-void ip_addr_range_buffer(char **, size_t *, 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(int, struct ip_addr *);
void ip_addr_range_read(int, struct ip_addr_range *);
@@ -385,14 +386,11 @@ void cryptoerrx(const char *, ...)
void io_socket_blocking(int);
void io_socket_nonblocking(int);
-void io_simple_buffer(char **, size_t *, size_t *, const void *,
- size_t);
+void io_simple_buffer(struct ibuf *, const void *, size_t);
+void io_buf_buffer(struct ibuf *, const void *, size_t);
+void io_str_buffer(struct ibuf *, const char *);
void io_simple_read(int, void *, size_t);
-void io_simple_write(int, const void *, size_t);
-void io_buf_buffer(char **, size_t *, size_t *, const void *,
- size_t);
void io_buf_read_alloc(int, void **, size_t *);
-void io_str_buffer(char **, size_t *, size_t *, const char *);
void io_str_read(int, char **);
/* X509 helpers. */
diff --git a/usr.sbin/rpki-client/io.c b/usr.sbin/rpki-client/io.c
index 9b2b8feb021..cade2aa1128 100644
--- a/usr.sbin/rpki-client/io.c
+++ b/usr.sbin/rpki-client/io.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: io.c,v 1.11 2020/12/18 16:58:59 claudio Exp $ */
+/* $OpenBSD: io.c,v 1.12 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <imsg.h>
#include "extern.h"
@@ -50,62 +51,37 @@ io_socket_nonblocking(int fd)
}
/*
- * Blocking write of a binary buffer.
- * Buffers of length zero are simply ignored.
- */
-void
-io_simple_write(int fd, const void *res, size_t sz)
-{
- ssize_t ssz;
-
- if (sz == 0)
- return;
- if ((ssz = write(fd, res, sz)) == -1)
- err(1, "write");
- else if ((size_t)ssz != sz)
- errx(1, "write: short write");
-}
-
-/*
* Like io_simple_write() but into a buffer.
*/
void
-io_simple_buffer(char **b, size_t *bsz,
- size_t *bmax, const void *res, size_t sz)
+io_simple_buffer(struct ibuf *b, const void *res, size_t sz)
{
-
- if (*bsz + sz > *bmax) {
- if ((*b = realloc(*b, *bsz + sz)) == NULL)
- err(1, NULL);
- *bmax = *bsz + sz;
- }
-
- memcpy(*b + *bsz, res, sz);
- *bsz += sz;
+ if (ibuf_add(b, res, sz) == -1)
+ err(1, NULL);
}
/*
- * Like io_buf_write() but into a buffer.
+ * Add a sz sized buffer into the io buffer.
*/
void
-io_buf_buffer(char **b, size_t *bsz,
- size_t *bmax, const void *p, size_t sz)
+io_buf_buffer(struct ibuf *b, const void *p, size_t sz)
{
-
- io_simple_buffer(b, bsz, bmax, &sz, sizeof(size_t));
+ if (ibuf_add(b, &sz, sizeof(size_t)) == -1)
+ err(1, NULL);
if (sz > 0)
- io_simple_buffer(b, bsz, bmax, p, sz);
+ if (ibuf_add(b, p, sz) == -1)
+ err(1, NULL);
}
/*
- * Like io_str_write() but into a buffer.
+ * Add a string into the io buffer.
*/
void
-io_str_buffer(char **b, size_t *bsz, size_t *bmax, const char *p)
+io_str_buffer(struct ibuf *b, const char *p)
{
- size_t sz = (p == NULL) ? 0 : strlen(p);
+ size_t sz = (p == NULL) ? 0 : strlen(p);
- io_buf_buffer(b, bsz, bmax, p, sz);
+ io_buf_buffer(b, p, sz);
}
/*
diff --git a/usr.sbin/rpki-client/ip.c b/usr.sbin/rpki-client/ip.c
index de1f1df5e42..c9c5c2ad914 100644
--- a/usr.sbin/rpki-client/ip.c
+++ b/usr.sbin/rpki-client/ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip.c,v 1.13 2020/09/12 15:46:48 claudio Exp $ */
+/* $OpenBSD: ip.c,v 1.14 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -276,13 +276,13 @@ ip_addr_print(const struct ip_addr *addr,
* Matched with ip_addr_read().
*/
void
-ip_addr_buffer(char **b, size_t *bsz, size_t *bmax, const struct ip_addr *p)
+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, bsz, bmax, &p->prefixlen, sizeof(unsigned char));
- io_simple_buffer(b, bsz, bmax, p->addr, sz);
+ io_simple_buffer(b, &p->prefixlen, sizeof(unsigned char));
+ io_simple_buffer(b, p->addr, sz);
}
/*
@@ -290,12 +290,10 @@ ip_addr_buffer(char **b, size_t *bsz, size_t *bmax, const struct ip_addr *p)
* Matched with ip_addr_range_read().
*/
void
-ip_addr_range_buffer(char **b, size_t *bsz, size_t *bmax,
- const struct ip_addr_range *p)
+ip_addr_range_buffer(struct ibuf *b, const struct ip_addr_range *p)
{
-
- ip_addr_buffer(b, bsz, bmax, &p->min);
- ip_addr_buffer(b, bsz, bmax, &p->max);
+ ip_addr_buffer(b, &p->min);
+ ip_addr_buffer(b, &p->max);
}
/*
diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c
index d1ad28fa925..3c20e2edb3e 100644
--- a/usr.sbin/rpki-client/main.c
+++ b/usr.sbin/rpki-client/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.88 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: main.c,v 1.89 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -66,6 +66,7 @@
#include <limits.h>
#include <syslog.h>
#include <unistd.h>
+#include <imsg.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -141,7 +142,8 @@ struct filepath_tree fpt = RB_INITIALIZER(&fpt);
/*
* Mark that our subprocesses will never return.
*/
-static void entityq_flush(int, struct entityq *, const struct repo *);
+static void entityq_flush(struct msgbuf *, struct entityq *,
+ const struct repo *);
static void proc_parser(int) __attribute__((noreturn));
static void build_chain(const struct auth *, STACK_OF(X509) **);
static void build_crls(const struct auth *, struct crl_tree *,
@@ -240,20 +242,19 @@ entity_read_req(int fd, struct entity *ent)
* Matched by entity_read_req().
*/
static void
-entity_buffer_req(char **b, size_t *bsz, size_t *bmax,
- const struct entity *ent)
+entity_buffer_req(struct ibuf *b, const struct entity *ent)
{
- io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t));
- io_simple_buffer(b, bsz, bmax, &ent->type, sizeof(enum rtype));
- io_str_buffer(b, bsz, bmax, ent->uri);
- io_simple_buffer(b, bsz, bmax, &ent->has_dgst, sizeof(int));
+ io_simple_buffer(b, &ent->id, sizeof(ent->id));
+ io_simple_buffer(b, &ent->type, sizeof(ent->type));
+ io_str_buffer(b, ent->uri);
+ io_simple_buffer(b, &ent->has_dgst, sizeof(int));
if (ent->has_dgst)
- io_simple_buffer(b, bsz, bmax, ent->dgst, sizeof(ent->dgst));
- io_simple_buffer(b, bsz, bmax, &ent->has_pkey, sizeof(int));
+ io_simple_buffer(b, ent->dgst, sizeof(ent->dgst));
+ io_simple_buffer(b, &ent->has_pkey, sizeof(int));
if (ent->has_pkey)
- io_buf_buffer(b, bsz, bmax, ent->pkey, ent->pkeysz);
- io_str_buffer(b, bsz, bmax, ent->descr);
+ io_buf_buffer(b, ent->pkey, ent->pkeysz);
+ io_str_buffer(b, ent->descr);
}
/*
@@ -261,14 +262,14 @@ entity_buffer_req(char **b, size_t *bsz, size_t *bmax,
* Simply a wrapper around entity_buffer_req().
*/
static void
-entity_write_req(int fd, const struct entity *ent)
+entity_write_req(struct msgbuf *msgq, const struct entity *ent)
{
- char *b = NULL;
- size_t bsz = 0, bmax = 0;
+ struct ibuf *b;
- entity_buffer_req(&b, &bsz, &bmax, ent);
- io_simple_write(fd, b, bsz);
- free(b);
+ if ((b = ibuf_dynamic(sizeof(*ent), UINT_MAX)) == NULL)
+ err(1, NULL);
+ entity_buffer_req(b, ent);
+ ibuf_close(msgq, b);
}
/*
@@ -276,14 +277,14 @@ entity_write_req(int fd, const struct entity *ent)
* repo, then flush those into the parser process.
*/
static void
-entityq_flush(int fd, struct entityq *q, const struct repo *repo)
+entityq_flush(struct msgbuf *msgq, struct entityq *q, const struct repo *repo)
{
struct entity *p;
TAILQ_FOREACH(p, q, entries) {
if (p->repo < 0 || repo->id != (size_t)p->repo)
continue;
- entity_write_req(fd, p);
+ entity_write_req(msgq, p);
}
}
@@ -291,13 +292,12 @@ entityq_flush(int fd, struct entityq *q, const struct repo *repo)
* Look up a repository, queueing it for discovery if not found.
*/
static const struct repo *
-repo_lookup(int fd, const char *uri)
+repo_lookup(struct msgbuf *msgq, const char *uri)
{
const char *host, *mod;
size_t hostsz, modsz, i;
struct repo *rp;
- char *b = NULL;
- size_t bsz = 0, bmax = 0;
+ struct ibuf *b;
if (!rsync_uri_parse(&host, &hostsz,
&mod, &modsz, NULL, NULL, NULL, uri))
@@ -334,12 +334,13 @@ repo_lookup(int fd, const char *uri)
if (!noop) {
logx("%s/%s: pulling from network", rp->host, rp->module);
- io_simple_buffer(&b, &bsz, &bmax, &i, sizeof(size_t));
- io_str_buffer(&b, &bsz, &bmax, rp->host);
- io_str_buffer(&b, &bsz, &bmax, rp->module);
+ if ((b = ibuf_dynamic(128, UINT_MAX)) == NULL)
+ err(1, NULL);
+ io_simple_buffer(b, &i, sizeof(i));
+ io_str_buffer(b, rp->host);
+ io_str_buffer(b, rp->module);
- io_simple_write(fd, b, bsz);
- free(b);
+ ibuf_close(msgq, b);
} else {
rp->loaded = 1;
logx("%s/%s: using cache", rp->host, rp->module);
@@ -387,18 +388,16 @@ entityq_next(int fd, struct entityq *q)
}
static void
-entity_buffer_resp(char **b, size_t *bsz, size_t *bmax,
- const struct entity *ent)
+entity_buffer_resp(struct ibuf *b, const struct entity *ent)
{
-
- io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t));
+ io_simple_buffer(b, &ent->id, sizeof(size_t));
}
/*
* Add the heap-allocated file to the queue for processing.
*/
static void
-entityq_add(int fd, struct entityq *q, char *file, enum rtype type,
+entityq_add(struct msgbuf *msgq, struct entityq *q, char *file, enum rtype type,
const struct repo *rp, const unsigned char *dgst,
const unsigned char *pkey, size_t pkeysz, char *descr, size_t *eid)
{
@@ -434,7 +433,7 @@ entityq_add(int fd, struct entityq *q, char *file, enum rtype type,
*/
if (rp == NULL || rp->loaded)
- entity_write_req(fd, p);
+ entity_write_req(msgq, p);
}
/*
@@ -442,7 +441,7 @@ entityq_add(int fd, struct entityq *q, char *file, enum rtype type,
* These are always relative to the directory in which "mft" sits.
*/
static void
-queue_add_from_mft(int fd, struct entityq *q, const char *mft,
+queue_add_from_mft(struct msgbuf *msgq, struct entityq *q, const char *mft,
const struct mftfile *file, enum rtype type, size_t *eid)
{
char *cp, *nfile;
@@ -461,7 +460,7 @@ queue_add_from_mft(int fd, struct entityq *q, const char *mft,
* that the repository has already been loaded.
*/
- entityq_add(fd, q, nfile, type, NULL, file->hash, NULL, 0, NULL, eid);
+ entityq_add(msgq, q, nfile, type, NULL, file->hash, NULL, 0, NULL, eid);
}
/*
@@ -473,8 +472,8 @@ queue_add_from_mft(int fd, struct entityq *q, const char *mft,
* check the suffix anyway).
*/
static void
-queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
- size_t *eid)
+queue_add_from_mft_set(struct msgbuf *msgq, struct entityq *q,
+ const struct mft *mft, size_t *eid)
{
size_t i, sz;
const struct mftfile *f;
@@ -485,7 +484,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
assert(sz > 4);
if (strcasecmp(f->file + sz - 4, ".crl"))
continue;
- queue_add_from_mft(fd, q, mft->file, f, RTYPE_CRL, eid);
+ queue_add_from_mft(msgq, q, mft->file, f, RTYPE_CRL, eid);
}
for (i = 0; i < mft->filesz; i++) {
@@ -494,7 +493,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
assert(sz > 4);
if (strcasecmp(f->file + sz - 4, ".cer"))
continue;
- queue_add_from_mft(fd, q, mft->file, f, RTYPE_CER, eid);
+ queue_add_from_mft(msgq, q, mft->file, f, RTYPE_CER, eid);
}
for (i = 0; i < mft->filesz; i++) {
@@ -503,7 +502,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
assert(sz > 4);
if (strcasecmp(f->file + sz - 4, ".roa"))
continue;
- queue_add_from_mft(fd, q, mft->file, f, RTYPE_ROA, eid);
+ queue_add_from_mft(msgq, q, mft->file, f, RTYPE_ROA, eid);
}
for (i = 0; i < mft->filesz; i++) {
@@ -512,7 +511,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
assert(sz > 4);
if (strcasecmp(f->file + sz - 4, ".gbr"))
continue;
- queue_add_from_mft(fd, q, mft->file, f, RTYPE_GBR, eid);
+ queue_add_from_mft(msgq, q, mft->file, f, RTYPE_GBR, eid);
}
for (i = 0; i < mft->filesz; i++) {
@@ -532,7 +531,8 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft,
* Add a local TAL file (RFC 7730) to the queue of files to fetch.
*/
static void
-queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid)
+queue_add_tal(struct msgbuf *msgq, struct entityq *q, const char *file,
+ size_t *eid)
{
char *nfile, *buf;
@@ -552,7 +552,7 @@ queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid)
}
/* Not in a repository, so directly add to queue. */
- entityq_add(fd, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, buf, eid);
+ entityq_add(msgq, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, buf, eid);
/* entityq_add makes a copy of buf */
free(buf);
}
@@ -561,8 +561,8 @@ queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid)
* Add URIs (CER) from a TAL file, RFC 8630.
*/
static void
-queue_add_from_tal(int proc, int rsync, struct entityq *q,
- const struct tal *tal, size_t *eid)
+queue_add_from_tal(struct msgbuf *procq, struct msgbuf *rsyncq,
+ struct entityq *q, const struct tal *tal, size_t *eid)
{
char *nfile;
const struct repo *repo;
@@ -580,10 +580,10 @@ queue_add_from_tal(int proc, int rsync, struct entityq *q,
errx(1, "TAL file has no rsync:// URI");
/* Look up the repository. */
- repo = repo_lookup(rsync, uri);
+ repo = repo_lookup(rsyncq, uri);
nfile = repo_filename(repo, uri);
- entityq_add(proc, q, nfile, RTYPE_CER, repo, NULL, tal->pkey,
+ entityq_add(procq, q, nfile, RTYPE_CER, repo, NULL, tal->pkey,
tal->pkeysz, tal->descr, eid);
}
@@ -591,8 +591,8 @@ queue_add_from_tal(int proc, int rsync, struct entityq *q,
* Add a manifest (MFT) found in an X509 certificate, RFC 6487.
*/
static void
-queue_add_from_cert(int proc, int rsync, struct entityq *q,
- const char *rsyncuri, const char *rrdpuri, size_t *eid)
+queue_add_from_cert(struct msgbuf *procq, struct msgbuf *rsyncq,
+ struct entityq *q, const char *rsyncuri, const char *rrdpuri, size_t *eid)
{
char *nfile;
const struct repo *repo;
@@ -601,10 +601,10 @@ queue_add_from_cert(int proc, int rsync, struct entityq *q,
return;
/* Look up the repository. */
- repo = repo_lookup(rsync, rsyncuri);
+ repo = repo_lookup(rsyncq, rsyncuri);
nfile = repo_filename(repo, rsyncuri);
- entityq_add(proc, q, nfile, RTYPE_MFT, repo, NULL, NULL, 0, NULL, eid);
+ entityq_add(procq, q, nfile, RTYPE_MFT, repo, NULL, NULL, 0, NULL, eid);
}
/*
@@ -1044,10 +1044,9 @@ proc_parser(int fd)
struct entity *entp;
struct entityq q;
int c, rc = 1;
+ struct msgbuf msgq;
struct pollfd pfd;
- char *b = NULL;
- size_t bsz = 0, bmax = 0, bpos = 0;
- ssize_t ssz;
+ struct ibuf *b;
X509_STORE *store;
X509_STORE_CTX *ctx;
struct auth_tree auths = RB_INITIALIZER(&auths);
@@ -1064,12 +1063,18 @@ proc_parser(int fd)
TAILQ_INIT(&q);
+ msgbuf_init(&msgq);
+ msgq.fd = fd;
+
pfd.fd = fd;
- pfd.events = POLLIN;
io_socket_nonblocking(pfd.fd);
for (;;) {
+ pfd.events = POLLIN;
+ if (msgq.queued)
+ pfd.events |= POLLOUT;
+
if (poll(&pfd, 1, INFTIM) == -1)
err(1, "poll");
if ((pfd.revents & (POLLERR|POLLNVAL)))
@@ -1095,29 +1100,16 @@ proc_parser(int fd)
err(1, NULL);
entity_read_req(fd, entp);
TAILQ_INSERT_TAIL(&q, entp, entries);
- pfd.events |= POLLOUT;
io_socket_nonblocking(fd);
}
- if (!(pfd.revents & POLLOUT))
- continue;
-
- /*
- * If we have a write buffer, then continue trying to
- * push it all out.
- * When it's all pushed out, reset it and get ready to
- * continue sucking down more data.
- */
-
- if (bsz) {
- assert(bpos < bmax);
- if ((ssz = write(fd, b + bpos, bsz)) == -1)
+ if (pfd.revents & POLLOUT) {
+ switch (msgbuf_write(&msgq)) {
+ case 0:
+ errx(1, "write: connection closed");
+ case -1:
err(1, "write");
- bpos += ssz;
- bsz -= ssz;
- if (bsz)
- continue;
- bpos = bsz = 0;
+ }
}
/*
@@ -1133,14 +1125,16 @@ proc_parser(int fd)
entp = TAILQ_FIRST(&q);
assert(entp != NULL);
- entity_buffer_resp(&b, &bsz, &bmax, entp);
+ if ((b = ibuf_dynamic(256, UINT_MAX)) == NULL)
+ err(1, NULL);
+ entity_buffer_resp(b, entp);
switch (entp->type) {
case RTYPE_TAL:
assert(!entp->has_dgst);
if ((tal = tal_parse(entp->uri, entp->descr)) == NULL)
goto out;
- tal_buffer(&b, &bsz, &bmax, tal);
+ tal_buffer(b, tal);
tal_free(tal);
break;
case RTYPE_CER:
@@ -1151,9 +1145,9 @@ proc_parser(int fd)
cert = proc_parser_root_cert(entp, store, ctx,
&auths, &crlt);
c = (cert != NULL);
- io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
+ io_simple_buffer(b, &c, sizeof(int));
if (cert != NULL)
- cert_buffer(&b, &bsz, &bmax, cert);
+ cert_buffer(b, cert);
/*
* The parsed certificate data "cert" is now
* managed in the "auths" table, so don't free
@@ -1163,9 +1157,9 @@ proc_parser(int fd)
case RTYPE_MFT:
mft = proc_parser_mft(entp, store, ctx, &auths, &crlt);
c = (mft != NULL);
- io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
+ io_simple_buffer(b, &c, sizeof(int));
if (mft != NULL)
- mft_buffer(&b, &bsz, &bmax, mft);
+ mft_buffer(b, mft);
mft_free(mft);
break;
case RTYPE_CRL:
@@ -1175,9 +1169,9 @@ proc_parser(int fd)
assert(entp->has_dgst);
roa = proc_parser_roa(entp, store, ctx, &auths, &crlt);
c = (roa != NULL);
- io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
+ io_simple_buffer(b, &c, sizeof(int));
if (roa != NULL)
- roa_buffer(&b, &bsz, &bmax, roa);
+ roa_buffer(b, roa);
roa_free(roa);
break;
case RTYPE_GBR:
@@ -1187,6 +1181,7 @@ proc_parser(int fd)
abort();
}
+ ibuf_close(&msgq, b);
TAILQ_REMOVE(&q, entp, entries);
entity_free(entp);
}
@@ -1203,7 +1198,7 @@ out:
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
- free(b);
+ msgbuf_clear(&msgq);
exit(rc);
}
@@ -1215,8 +1210,8 @@ out:
* In all cases, we gather statistics.
*/
static void
-entity_process(int proc, int rsync, struct stats *st,
- struct entityq *q, const struct entity *ent,
+entity_process(int proc, struct msgbuf *procq, struct msgbuf *rsyncq,
+ struct stats *st, struct entityq *q, const struct entity *ent,
size_t *eid, struct vrp_tree *tree)
{
struct tal *tal;
@@ -1236,7 +1231,7 @@ entity_process(int proc, int rsync, struct stats *st,
case RTYPE_TAL:
st->tals++;
tal = tal_read(proc);
- queue_add_from_tal(proc, rsync, q, tal, eid);
+ queue_add_from_tal(procq, rsyncq, q, tal, eid);
tal_free(tal);
break;
case RTYPE_CER:
@@ -1254,7 +1249,7 @@ entity_process(int proc, int rsync, struct stats *st,
* we're revoked and then we don't want to
* process the MFT.
*/
- queue_add_from_cert(proc, rsync,
+ queue_add_from_cert(procq, rsyncq,
q, cert->mft, cert->notify, eid);
} else
st->certs_invalid++;
@@ -1270,7 +1265,7 @@ entity_process(int proc, int rsync, struct stats *st,
mft = mft_read(proc);
if (mft->stale)
st->mfts_stale++;
- queue_add_from_mft_set(proc, q, mft, eid);
+ queue_add_from_mft_set(procq, q, mft, eid);
mft_free(mft);
break;
case RTYPE_CRL:
@@ -1430,6 +1425,7 @@ main(int argc, char *argv[])
int fd[2];
struct entityq q;
struct entity *ent;
+ struct msgbuf procq, rsyncq;
struct pollfd pfd[2];
struct roa **out = NULL;
char *rsync_prog = "openrsync";
@@ -1609,14 +1605,10 @@ main(int argc, char *argv[])
if (pledge("stdio rpath wpath cpath fattr", NULL) == -1)
err(1, "pledge");
- /*
- * Prime the process with our TAL file.
- * This will contain (hopefully) links to our manifest and we
- * can get the ball rolling.
- */
-
- for (i = 0; i < talsz; i++)
- queue_add_tal(proc, &q, tals[i], &eid);
+ msgbuf_init(&procq);
+ msgbuf_init(&rsyncq);
+ procq.fd = proc;
+ rsyncq.fd = rsync;
/*
* The main process drives the top-down scan to leaf ROAs using
@@ -1626,9 +1618,24 @@ main(int argc, char *argv[])
pfd[0].fd = rsync;
pfd[1].fd = proc;
- pfd[0].events = pfd[1].events = POLLIN;
+
+ /*
+ * Prime the process with our TAL file.
+ * This will contain (hopefully) links to our manifest and we
+ * can get the ball rolling.
+ */
+
+ for (i = 0; i < talsz; i++)
+ queue_add_tal(&procq, &q, tals[i], &eid);
while (!TAILQ_EMPTY(&q) && !killme) {
+ pfd[0].events = POLLIN;
+ if (rsyncq.queued)
+ pfd[0].events = POLLOUT;
+ pfd[1].events = POLLIN;
+ if (procq.queued)
+ pfd[1].events = POLLOUT;
+
if ((c = poll(pfd, 2, verbose ? 10000 : INFTIM)) == -1) {
if (errno == EINTR)
continue;
@@ -1656,6 +1663,23 @@ main(int argc, char *argv[])
(pfd[1].revents & POLLHUP))
errx(1, "poll: hangup");
+ if (pfd[0].revents & POLLOUT) {
+ switch (msgbuf_write(&rsyncq)) {
+ case 0:
+ errx(1, "write: connection closed");
+ case -1:
+ err(1, "write");
+ }
+ }
+ if (pfd[1].revents & POLLOUT) {
+ switch (msgbuf_write(&procq)) {
+ case 0:
+ errx(1, "write: connection closed");
+ case -1:
+ err(1, "write");
+ }
+ }
+
/*
* Check the rsync process.
* This means that one of our modules has completed
@@ -1678,7 +1702,7 @@ main(int argc, char *argv[])
"fallback to cache",
rt.repos[i].host, rt.repos[i].module);
stats.repos++;
- entityq_flush(proc, &q, &rt.repos[i]);
+ entityq_flush(&procq, &q, &rt.repos[i]);
}
/*
@@ -1688,7 +1712,7 @@ main(int argc, char *argv[])
if ((pfd[1].revents & POLLIN)) {
ent = entityq_next(proc, &q);
- entity_process(proc, rsync, &stats,
+ entity_process(proc, &procq, &rsyncq, &stats,
&q, ent, &eid, &v);
if (verbose > 2)
fprintf(stderr, "%s\n", ent->uri);
diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c
index 3b0d06635a4..767a84da490 100644
--- a/usr.sbin/rpki-client/mft.c
+++ b/usr.sbin/rpki-client/mft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mft.c,v 1.22 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: mft.c,v 1.23 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -519,22 +519,21 @@ mft_free(struct mft *p)
* See mft_read() for the other side of the pipe.
*/
void
-mft_buffer(char **b, size_t *bsz, size_t *bmax, const struct mft *p)
+mft_buffer(struct ibuf *b, const struct mft *p)
{
size_t i;
- io_simple_buffer(b, bsz, bmax, &p->stale, sizeof(int));
- io_str_buffer(b, bsz, bmax, p->file);
- io_simple_buffer(b, bsz, bmax, &p->filesz, sizeof(size_t));
+ io_simple_buffer(b, &p->stale, sizeof(int));
+ io_str_buffer(b, p->file);
+ io_simple_buffer(b, &p->filesz, sizeof(size_t));
for (i = 0; i < p->filesz; i++) {
- io_str_buffer(b, bsz, bmax, p->files[i].file);
- io_simple_buffer(b, bsz, bmax,
- p->files[i].hash, SHA256_DIGEST_LENGTH);
+ io_str_buffer(b, p->files[i].file);
+ io_simple_buffer(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
}
- io_str_buffer(b, bsz, bmax, p->aki);
- io_str_buffer(b, bsz, bmax, p->ski);
+ io_str_buffer(b, p->aki);
+ io_str_buffer(b, p->ski);
}
/*
diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c
index b6044d13681..98985b15a42 100644
--- a/usr.sbin/rpki-client/roa.c
+++ b/usr.sbin/rpki-client/roa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roa.c,v 1.10 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: roa.c,v 1.11 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -388,29 +388,25 @@ roa_free(struct roa *p)
* See roa_read() for reader.
*/
void
-roa_buffer(char **b, size_t *bsz, size_t *bmax, const struct roa *p)
+roa_buffer(struct ibuf *b, const struct roa *p)
{
size_t i;
- io_simple_buffer(b, bsz, bmax, &p->valid, sizeof(int));
- io_simple_buffer(b, bsz, bmax, &p->asid, sizeof(uint32_t));
- io_simple_buffer(b, bsz, bmax, &p->ipsz, sizeof(size_t));
+ io_simple_buffer(b, &p->valid, sizeof(int));
+ io_simple_buffer(b, &p->asid, sizeof(uint32_t));
+ io_simple_buffer(b, &p->ipsz, sizeof(size_t));
for (i = 0; i < p->ipsz; i++) {
- io_simple_buffer(b, bsz, bmax,
- &p->ips[i].afi, sizeof(enum afi));
- io_simple_buffer(b, bsz, bmax,
- &p->ips[i].maxlength, sizeof(size_t));
- io_simple_buffer(b, bsz, bmax,
- p->ips[i].min, sizeof(p->ips[i].min));
- io_simple_buffer(b, bsz, bmax,
- p->ips[i].max, sizeof(p->ips[i].max));
- ip_addr_buffer(b, bsz, bmax, &p->ips[i].addr);
+ 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_str_buffer(b, bsz, bmax, p->aki);
- io_str_buffer(b, bsz, bmax, p->ski);
- io_str_buffer(b, bsz, bmax, p->tal);
+ io_str_buffer(b, p->aki);
+ io_str_buffer(b, p->ski);
+ io_str_buffer(b, p->tal);
}
/*
diff --git a/usr.sbin/rpki-client/rsync.c b/usr.sbin/rpki-client/rsync.c
index 5d4bee0e98e..dfe15e04600 100644
--- a/usr.sbin/rpki-client/rsync.c
+++ b/usr.sbin/rpki-client/rsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rsync.c,v 1.12 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: rsync.c,v 1.13 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -15,6 +15,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/queue.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
@@ -28,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <imsg.h>
#include "extern.h"
@@ -171,21 +173,25 @@ proc_child(int signal)
void
proc_rsync(char *prog, char *bind_addr, int fd)
{
- size_t id, i, idsz = 0, bsz = 0, bmax = 0;
+ size_t id, i, idsz = 0;
ssize_t ssz;
char *host = NULL, *mod = NULL, *uri = NULL,
- *dst = NULL, *path, *save, *cmd, *b = NULL;
+ *dst = NULL, *path, *save, *cmd;
const char *pp;
pid_t pid;
char *args[32];
int st, rc = 0;
struct stat stt;
struct pollfd pfd;
+ struct msgbuf msgq;
+ struct ibuf *b;
sigset_t mask, oldmask;
struct rsyncproc *ids = NULL;
pfd.fd = fd;
- pfd.events = POLLIN;
+
+ msgbuf_init(&msgq);
+ msgq.fd = fd;
/*
* Unveil the command we want to run.
@@ -236,6 +242,10 @@ proc_rsync(char *prog, char *bind_addr, int fd)
err(1, NULL);
for (;;) {
+ pfd.events = POLLIN;
+ if (msgq.queued)
+ pfd.events |= POLLOUT;
+
if (ppoll(&pfd, 1, NULL, &oldmask) == -1) {
if (errno != EINTR)
err(1, "ppoll");
@@ -265,12 +275,12 @@ proc_rsync(char *prog, char *bind_addr, int fd)
ok = 0;
}
- io_simple_buffer(&b, &bsz, &bmax,
- &ids[i].id, sizeof(size_t));
- io_simple_buffer(&b, &bsz, &bmax,
- &ok, sizeof(ok));
- io_simple_write(fd, b, bsz);
- bsz = 0;
+ b = ibuf_open(sizeof(size_t) + sizeof(ok));
+ if (b == NULL)
+ err(1, NULL);
+ io_simple_buffer(b, &ids[i].id, sizeof(size_t));
+ io_simple_buffer(b, &ok, sizeof(ok));
+ ibuf_close(&msgq, b);
free(ids[i].uri);
ids[i].uri = NULL;
@@ -282,6 +292,18 @@ proc_rsync(char *prog, char *bind_addr, int fd)
continue;
}
+ if (pfd.revents & POLLOUT) {
+ switch (msgbuf_write(&msgq)) {
+ case 0:
+ errx(1, "write: connection closed");
+ case -1:
+ err(1, "write");
+ }
+ }
+
+ if (!(pfd.revents & POLLIN))
+ continue;
+
/*
* Read til the parent exits.
* That will mean that we can safely exit.
@@ -370,7 +392,7 @@ proc_rsync(char *prog, char *bind_addr, int fd)
free(ids[i].uri);
}
- free(b);
+ msgbuf_clear(&msgq);
free(ids);
exit(rc);
/* NOTREACHED */
diff --git a/usr.sbin/rpki-client/tal.c b/usr.sbin/rpki-client/tal.c
index f3db5d4f2eb..a724e5de2e6 100644
--- a/usr.sbin/rpki-client/tal.c
+++ b/usr.sbin/rpki-client/tal.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tal.c,v 1.25 2020/12/21 11:35:55 claudio Exp $ */
+/* $OpenBSD: tal.c,v 1.26 2021/01/08 08:09:07 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -301,16 +301,16 @@ tal_free(struct tal *p)
* See tal_read() for the other side of the pipe.
*/
void
-tal_buffer(char **b, size_t *bsz, size_t *bmax, const struct tal *p)
+tal_buffer(struct ibuf *b, const struct tal *p)
{
size_t i;
- io_buf_buffer(b, bsz, bmax, p->pkey, p->pkeysz);
- io_str_buffer(b, bsz, bmax, p->descr);
- io_simple_buffer(b, bsz, bmax, &p->urisz, sizeof(size_t));
+ io_buf_buffer(b, p->pkey, p->pkeysz);
+ io_str_buffer(b, p->descr);
+ io_simple_buffer(b, &p->urisz, sizeof(size_t));
for (i = 0; i < p->urisz; i++)
- io_str_buffer(b, bsz, bmax, p->uri[i]);
+ io_str_buffer(b, p->uri[i]);
}
/*