summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client/repo.c
diff options
context:
space:
mode:
authorJob Snijders <job@cvs.openbsd.org>2023-05-30 16:02:29 +0000
committerJob Snijders <job@cvs.openbsd.org>2023-05-30 16:02:29 +0000
commit1ea9138ac843d8bd5306d25edf0c4b18f2ff8469 (patch)
tree01d5ce08eac609e49256a058a1a83b290c663973 /usr.sbin/rpki-client/repo.c
parent5c681176934959ca1c98655146b0eff4d53e4530 (diff)
Fixup file modification timestamps to optimize failover from RRDP to RSYNC
In the RSYNC protocol a file's last modification time and its size are used to determine whether sending a (partial) copy over the wire is needed. Previously, when RRDP data structures are serialized to disk, the mtime of files in DIR_VALID ended up being UTIME_NOW. Thus, the mtimes of files obtained through RRDP will never match the mtimes of the same files available through RSYNC - causing each and every file to be added to the file transfer list. Instead, use the internal timestamps of RPKI files as the last modified timestamp. Specifically, for Signed Objects (ROAs, MFTs, GBRs, TAKs, ASPAs) the CMS signing-time, for .cer files the X.509 notBefore, and for .crl files the CRL lastUpdate. This results in a surprising optimization for the number files which have to be transfered. OK claudio@
Diffstat (limited to 'usr.sbin/rpki-client/repo.c')
-rw-r--r--usr.sbin/rpki-client/repo.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c
index ee79b1e3195..009ce254613 100644
--- a/usr.sbin/rpki-client/repo.c
+++ b/usr.sbin/rpki-client/repo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: repo.c,v 1.46 2023/05/25 12:49:39 claudio Exp $ */
+/* $OpenBSD: repo.c,v 1.47 2023/05/30 16:02:28 job Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -119,6 +119,7 @@ static void remove_contents(char *);
struct filepath {
RB_ENTRY(filepath) entry;
char *file;
+ time_t mtime;
};
static inline int
@@ -133,12 +134,13 @@ RB_PROTOTYPE(filepath_tree, filepath, entry, filepathcmp);
* Functions to lookup which files have been accessed during computation.
*/
int
-filepath_add(struct filepath_tree *tree, char *file)
+filepath_add(struct filepath_tree *tree, char *file, time_t mtime)
{
struct filepath *fp;
if ((fp = malloc(sizeof(*fp))) == NULL)
err(1, NULL);
+ fp->mtime = mtime;
if ((fp->file = strdup(file)) == NULL)
err(1, NULL);
@@ -838,7 +840,7 @@ rrdp_handle_file(unsigned int id, enum publish_type pt, char *uri,
/* write new content or mark uri as deleted. */
if (pt == PUB_DEL) {
- filepath_add(&rr->deleted, uri);
+ filepath_add(&rr->deleted, uri, 0);
} else {
fp = filepath_find(&rr->deleted, uri);
if (fp != NULL)
@@ -1536,6 +1538,28 @@ repo_move_valid(struct filepath_tree *tree)
base = strchr(fp->file + rrdpsz, '/');
assert(base != NULL);
fn = base + 1;
+
+ /*
+ * Adjust file last modification time in order to
+ * minimize RSYNC synchronization load after transport
+ * failover.
+ * While serializing RRDP datastructures to disk, set
+ * the last modified timestamp to the CMS signing-time,
+ * the X.509 notBefore, or CRL lastUpdate timestamp.
+ */
+ if (fp->mtime != 0) {
+ int ret;
+ struct timespec ts[2];
+
+ ts[0].tv_nsec = UTIME_OMIT;
+ ts[1].tv_sec = fp->mtime;
+ ts[1].tv_nsec = 0;
+ ret = utimensat(AT_FDCWD, fp->file, ts, 0);
+ if (ret == -1) {
+ warn("utimensat %s", fp->file);
+ continue;
+ }
+ }
}
if (repo_mkpath(AT_FDCWD, fn) == -1)