From 47de54a6f7f3f73b0ee25b88bb332954ad049b74 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 2 Sep 2022 21:56:45 +0000 Subject: [PATCH] Introduce a deadline timer that aborts all repository syncs. With this rpki-client has a chance to still finish and produce an output even when a CA is excessivly slow and holds back progress. With and OK benno@ tb@ and job@ --- usr.sbin/rpki-client/main.c | 7 ++++++- usr.sbin/rpki-client/repo.c | 31 +++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index 4a60208c6da..f5e5ab31254 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.217 2022/09/02 19:14:04 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.218 2022/09/02 21:56:45 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -66,6 +66,7 @@ int noop; int filemode; int rrdpon = 1; int repo_timeout; +time_t deadline; struct skiplist skiplist = LIST_HEAD_INITIALIZER(skiplist); @@ -1044,6 +1045,10 @@ main(int argc, char *argv[]) */ alarm(timeout); signal(SIGALRM, suicide); + + /* give up a bit before the hard timeout and try to finish up */ + if (!noop) + deadline = getmonotime() + timeout - repo_timeout / 2; } if (pledge("stdio rpath wpath cpath fattr sendfd unveil", NULL) == -1) diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c index c953d55a339..84550a9e7e9 100644 --- a/usr.sbin/rpki-client/repo.c +++ b/usr.sbin/rpki-client/repo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: repo.c,v 1.38 2022/09/02 19:10:37 claudio Exp $ */ +/* $OpenBSD: repo.c,v 1.39 2022/09/02 21:56:45 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -41,6 +41,8 @@ extern struct stats stats; extern int noop; extern int rrdpon; extern int repo_timeout; +extern time_t deadline; +int nofetch; enum repo_state { REPO_LOADING = 0, @@ -288,7 +290,7 @@ repo_done(const void *vp, int ok) if (vp == rp->rsync) entityq_flush(&rp->queue, rp); if (vp == rp->rrdp) { - if (!ok) { + if (!ok && !nofetch) { /* try to fall back to rsync */ rp->rrdp = NULL; rp->rsync = rsync_get(rp->repouri, @@ -937,8 +939,8 @@ rrdp_finish(unsigned int id, int ok) stats.rrdp_repos++; rr->state = REPO_DONE; } else { - warnx("%s: load from network failed, fallback to rsync", - rr->notifyuri); + warnx("%s: load from network failed, fallback to %s", + rr->notifyuri, nofetch ? "cache" : "rsync"); stats.rrdp_fails++; rr->state = REPO_FAILED; /* clear the RRDP repo since it failed */ @@ -1044,7 +1046,6 @@ repo_lookup(int talid, const char *uri, const char *notify) { struct repo *rp; char *repouri; - int nofetch = 0; if ((repouri = rsync_base_uri(uri)) == NULL) errx(1, "bad caRepository URI: %s", uri); @@ -1223,8 +1224,26 @@ repo_check_timeout(int timeout) { struct repo *rp; time_t now; + int diff; now = getmonotime(); + + /* check against our runtime deadline first */ + if (deadline != 0) { + if (deadline <= now) { + warnx("deadline reached, giving up on repository sync"); + nofetch = 1; + /* clear deadline since nofetch is set */ + deadline = 0; + /* increase now enough so that all pending repos fail */ + now += repo_timeout; + } else { + diff = deadline - now; + diff *= 1000; + if (timeout == INFTIM || diff < timeout) + timeout = diff; + } + } /* Look up in repository table. (Lookup should actually fail here) */ SLIST_FOREACH(rp, &repos, entry) { if (repo_state(rp) == REPO_LOADING) { @@ -1233,7 +1252,7 @@ repo_check_timeout(int timeout) rp->repouri); repo_abort(rp); } else { - int diff = rp->alarm - now; + diff = rp->alarm - now; diff *= 1000; if (timeout == INFTIM || diff < timeout) timeout = diff; -- 2.20.1