summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2022-01-13 13:18:42 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2022-01-13 13:18:42 +0000
commitcf017c9839d7346d630456513c02b7f4cf6cb2c5 (patch)
treec75c667c34b42f02d9950869f60bafe124784a92 /usr.sbin
parentea30a6cc1a219a8de8a50efc760426876d58aaa3 (diff)
Implement a RRDP_CLEAR message that instructs the parent to cleanup
the rrdp directory. This is used before a snapshot download to ensure that the snapshot is applied to a clean repo. Similar cleanup happens if the transfer fails. In that case remove the temp directory contents only. This uses a new function remove_contents() to remove everything below a base directory (a bit like rm -r X/*). OK tb@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rpki-client/extern.h6
-rw-r--r--usr.sbin/rpki-client/main.c5
-rw-r--r--usr.sbin/rpki-client/repo.c93
-rw-r--r--usr.sbin/rpki-client/rrdp.c19
4 files changed, 95 insertions, 28 deletions
diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h
index 737aa4588a0..c69fb03c417 100644
--- a/usr.sbin/rpki-client/extern.h
+++ b/usr.sbin/rpki-client/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.101 2022/01/11 13:06:07 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.102 2022/01/13 13:18:41 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -309,10 +309,11 @@ enum rrdp_msg {
RRDP_START,
RRDP_SESSION,
RRDP_FILE,
+ RRDP_CLEAR,
RRDP_END,
RRDP_HTTP_REQ,
RRDP_HTTP_INI,
- RRDP_HTTP_FIN
+ RRDP_HTTP_FIN,
};
/*
@@ -501,6 +502,7 @@ void proc_rrdp(int);
/* Repository handling */
int filepath_add(struct filepath_tree *, char *);
+void rrdp_clear(unsigned int);
void rrdp_save_state(unsigned int, struct rrdp_session *);
int rrdp_handle_file(unsigned int, enum publish_type, char *,
char *, size_t, char *, size_t);
diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c
index 1a976d8064b..e8084bc745f 100644
--- a/usr.sbin/rpki-client/main.c
+++ b/usr.sbin/rpki-client/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.174 2022/01/13 11:50:29 claudio Exp $ */
+/* $OpenBSD: main.c,v 1.175 2022/01/13 13:18:41 claudio Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -632,6 +632,9 @@ rrdp_process(struct ibuf *b)
free(uri);
free(data);
break;
+ case RRDP_CLEAR:
+ rrdp_clear(id);
+ break;
default:
errx(1, "unexpected rrdp response");
}
diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c
index 5451021f519..6bd584d9601 100644
--- a/usr.sbin/rpki-client/repo.c
+++ b/usr.sbin/rpki-client/repo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: repo.c,v 1.21 2022/01/13 11:47:44 claudio Exp $ */
+/* $OpenBSD: repo.c,v 1.22 2022/01/13 13:18:41 claudio Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -106,6 +106,7 @@ static SLIST_HEAD(, repo) repos = SLIST_HEAD_INITIALIZER(repos);
unsigned int repoid;
static struct rsyncrepo *rsync_get(const char *, int);
+static void remove_contents(char *);
/*
* Database of all file path accessed during a run.
@@ -788,6 +789,23 @@ fail:
}
/*
+ * Remove RRDP repo and start over.
+ */
+void
+rrdp_clear(unsigned int id)
+{
+ struct rrdprepo *rr;
+
+ rr = rrdp_find(id);
+ if (rr == NULL)
+ errx(1, "non-existant rrdp repo %u", id);
+
+ /* remove rrdp repository contents */
+ remove_contents(rr->basedir);
+ remove_contents(rr->temp);
+}
+
+/*
* Write a file into the temporary RRDP dir but only after checking
* its hash (if required). The function also makes sure that the file
* tracking is properly adjusted.
@@ -932,24 +950,6 @@ fail:
return 0;
}
-static void
-rrdp_clean_temp(struct rrdprepo *rr)
-{
- struct filepath *fp, *nfp;
- char *fn;
-
- filepath_free(&rr->deleted);
-
- RB_FOREACH_SAFE(fp, filepath_tree, &rr->added, nfp) {
- if ((fn = rrdp_filename(rr, fp->file, 1)) != NULL) {
- if (unlink(fn) == -1)
- warn("unlink %s", fn);
- free(fn);
- }
- filepath_put(&rr->added, fp);
- }
-}
-
/*
* RSYNC sync finished, either with or without success.
*/
@@ -981,10 +981,10 @@ rsync_finish(unsigned int id, int ok)
rr = rsync_find(id);
if (rr == NULL)
errx(1, "unknown rsync repo %u", id);
-
/* repository changed state already, ignore request */
if (rr->state != REPO_LOADING)
return;
+
if (ok) {
logx("%s: loaded from network", rr->basedir);
stats.rsync_repos++;
@@ -1016,15 +1016,15 @@ rrdp_finish(unsigned int id, int ok)
if (ok && rrdp_merge_repo(rr)) {
logx("%s: loaded from network", rr->notifyuri);
- rr->state = REPO_DONE;
stats.rrdp_repos++;
+ rr->state = REPO_DONE;
repo_done(rr, ok);
} else {
- rrdp_clean_temp(rr);
- stats.rrdp_fails++;
- rr->state = REPO_FAILED;
logx("%s: load from network failed, fallback to rsync",
rr->notifyuri);
+ stats.rrdp_fails++;
+ rr->state = REPO_FAILED;
+ remove_contents(rr->temp);
repo_done(rr, 0);
}
}
@@ -1418,3 +1418,48 @@ repo_free(void)
rrdp_free();
rsync_free();
}
+
+static void
+remove_contents(char *base)
+{
+ char *argv[2] = { base, NULL };
+ FTS *fts;
+ FTSENT *e;
+
+ if ((fts = fts_open(argv, FTS_PHYSICAL | FTS_NOSTAT, NULL)) == NULL)
+ err(1, "fts_open");
+ errno = 0;
+ while ((e = fts_read(fts)) != NULL) {
+ switch (e->fts_info) {
+ case FTS_NSOK:
+ case FTS_SL:
+ case FTS_SLNONE:
+ if (unlink(e->fts_accpath) == -1)
+ warn("unlink %s", e->fts_path);
+ break;
+ case FTS_D:
+ break;
+ case FTS_DP:
+ /* keep root directory */
+ if (e->fts_level == FTS_ROOTLEVEL)
+ break;
+ if (rmdir(e->fts_accpath) == -1)
+ warn("rmdir %s", e->fts_path);
+ break;
+ case FTS_NS:
+ case FTS_ERR:
+ warnx("fts_read %s: %s", e->fts_path,
+ strerror(e->fts_errno));
+ break;
+ default:
+ warnx("unhandled[%x] %s", e->fts_info,
+ e->fts_path);
+ break;
+ }
+ errno = 0;
+ }
+ if (errno)
+ err(1, "fts_read");
+ if (fts_close(fts) == -1)
+ err(1, "fts_close");
+}
diff --git a/usr.sbin/rpki-client/rrdp.c b/usr.sbin/rpki-client/rrdp.c
index 3ee191f74d6..80c22b97207 100644
--- a/usr.sbin/rpki-client/rrdp.c
+++ b/usr.sbin/rpki-client/rrdp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rrdp.c,v 1.19 2021/12/22 09:35:14 claudio Exp $ */
+/* $OpenBSD: rrdp.c,v 1.20 2022/01/13 13:18:41 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -142,6 +142,21 @@ rrdp_state_send(struct rrdp *s)
}
/*
+ * Inform parent to clear the RRDP repository before start of snapshot.
+ */
+static void
+rrdp_clear_repo(struct rrdp *s)
+{
+ enum rrdp_msg type = RRDP_CLEAR;
+ struct ibuf *b;
+
+ b = io_new_buffer();
+ io_simple_buffer(b, &type, sizeof(type));
+ io_simple_buffer(b, &s->id, sizeof(s->id));
+ io_close_buffer(&msgq, b);
+}
+
+/*
* Send a blob of data to the main process to store it in the repository.
*/
void
@@ -246,6 +261,7 @@ rrdp_failed(struct rrdp *s)
/* fallback to a snapshot as per RFC8182 */
free_delta_xml(s->dxml);
s->dxml = NULL;
+ rrdp_clear_repo(s);
s->sxml = new_snapshot_xml(s->parser, &s->current, s);
s->task = SNAPSHOT;
s->state = RRDP_STATE_REQ;
@@ -315,6 +331,7 @@ rrdp_finished(struct rrdp *s)
break;
case SNAPSHOT:
logx("%s: downloading snapshot", s->local);
+ rrdp_clear_repo(s);
s->sxml = new_snapshot_xml(p, &s->current, s);
s->state = RRDP_STATE_REQ;
break;