rpki-client: add rsync baseuri-based batching

Job Snijders <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
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) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.