From: Job Snijders Subject: rpki-client: add rsync baseuri-based batching To: tech@openbsd.org Date: Tue, 7 Jul 2026 12:09:12 +0000 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, ¬ifys, entry, fle_tmp) {