Index | Thread | Search

From:
Job Snijders <job@bsd.nl>
Subject:
rpki-client: add rsync baseuri-based batching
To:
tech@openbsd.org
Date:
Tue, 7 Jul 2026 12:09:12 +0000

Download raw body.

Thread
Hi,

This changeset adds batching of retries based on rsync base URIs, which
makes backoff retry in rsync-only mode work better (rpki-client -R), and
also helps in case rsync-only CAs reappear in the future. Follows the
same approach as the existing RRDP rpkiNotify-based batching.

Question: I'm not sure the newly added calls to rsync_base_uri()
could ever fail, because nca_history_load() will already have called
rsync_base_uri() via valid_uri() on those same C strings, so perhaps
instead of 'continue' I should use an errx()? Or something else?

Kind regards,

Job

Index: nca.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/nca.c,v
diff -u -p -r1.7 nca.c
--- nca.c	1 Jul 2026 11:09:12 -0000	1.7
+++ nca.c	7 Jul 2026 11:59:31 -0000
@@ -31,6 +31,8 @@
 
 #include "extern.h"
 
+extern int rrdpon;
+
 /*
  * Add a given CA cert into the non-functional CA tree.
  * Return 1 if a synchronization attempt is to be made, 0 otherwise.
@@ -123,6 +125,7 @@ certidcmp(const struct nonfunc_ca *a, co
 
 RB_GENERATE(nca_tree, nonfunc_ca, entry, certidcmp);
 
+static LIST_HEAD(, fqdnlistentry) baseuris = LIST_HEAD_INITIALIZER(baseuris);
 static LIST_HEAD(, fqdnlistentry) notifys = LIST_HEAD_INITIALIZER(notifys);
 
 static RB_HEAD(nca_hist_tree, nca_hist) ncas_hist = RB_INITIALIZER(&ncas_hist);
@@ -230,7 +233,8 @@ ncas_plan_retries(void)
 {
 	struct nca_hist *nca_hist;
 	struct fqdnlistentry *fle, *fle_tmp;
-	size_t notify_len;
+	char *baseuri = NULL;
+	size_t notify_len, baseuri_len;
 
 	RB_FOREACH(nca_hist, nca_hist_tree, &ncas_hist) {
 		if (nca_decide_retry(nca_hist) == 0) {
@@ -238,7 +242,18 @@ ncas_plan_retries(void)
 			continue;
 		}
 
-		if (nca_hist->notify == NULL)
+		if (!rsync_base_uri(nca_hist->mfturi, &baseuri))
+			continue;
+
+		if ((fle = malloc(sizeof(*fle))) == NULL)
+			err(1, NULL);
+
+		fle->fqdn = baseuri;
+		baseuri = NULL;
+		LIST_INSERT_HEAD(&baseuris, fle, entry);
+		fle = NULL;
+
+		if (nca_hist->notify == NULL || !rrdpon)
 			continue;
 
 		if ((fle = malloc(sizeof(*fle))) == NULL)
@@ -251,7 +266,23 @@ ncas_plan_retries(void)
 	}
 
 	RB_FOREACH(nca_hist, nca_hist_tree, &ncas_hist) {
-		if (nca_hist->notify == NULL)
+		if (!rsync_base_uri(nca_hist->mfturi, &baseuri))
+			continue;
+
+		baseuri_len = strlen(baseuri);
+
+		LIST_FOREACH(fle, &baseuris, entry) {
+			if (strlen(fle->fqdn) == baseuri_len &&
+			    strncasecmp(baseuri, fle->fqdn, baseuri_len) == 0) {
+				nca_hist->defer = 0;
+				break;
+			}
+		}
+
+		free(baseuri);
+		baseuri = NULL;
+
+		if (nca_hist->notify == NULL || !rrdpon || !nca_hist->defer)
 			continue;
 
 		notify_len = strlen(nca_hist->notify);
@@ -264,6 +295,12 @@ ncas_plan_retries(void)
 				break;
 			}
 		}
+	}
+
+	LIST_FOREACH_SAFE(fle, &baseuris, entry, fle_tmp) {
+		LIST_REMOVE(fle, entry);
+		free(fle->fqdn);
+		free(fle);
 	}
 
 	LIST_FOREACH_SAFE(fle, &notifys, entry, fle_tmp) {