From d44d4e5c77df3df8d4d700fdbf588cc3e0b76ee2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=A0t=C4=9Bp=C3=A1n=20Bal=C3=A1=C5=BEik?= Date: Mon, 19 Oct 2020 16:23:40 +0200 Subject: [PATCH] selection: retry after DNSSEC fail Some other server might not have bogus signatures. --- lib/resolve.c | 7 ++++++- lib/selection.h | 2 ++ lib/selection_iter.c | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/resolve.c b/lib/resolve.c index 0d4fe2799..463d80fe0 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -818,7 +818,12 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo /* Do not finish with bogus answer. */ if (qry->flags.DNSSEC_BOGUS) { - return KR_STATE_FAIL; + if (qry->flags.FORWARD || qry->flags.STUB) { + return KR_STATE_FAIL; + } + /* Other servers might not have broken DNSSEC. */ + qry->flags.DNSSEC_BOGUS = false; + return KR_STATE_PRODUCE; } return kr_rplan_empty(&request->rplan) ? KR_STATE_DONE : KR_STATE_PRODUCE; diff --git a/lib/selection.h b/lib/selection.h index c16cc15e7..ef9436a6d 100644 --- a/lib/selection.h +++ b/lib/selection.h @@ -16,6 +16,8 @@ * See `kr_server_selection::error` for more details. */ enum kr_selection_error { + KR_SELECTION_OK = 0, + // Network errors KR_SELECTION_TIMEOUT, KR_SELECTION_TLS_HANDSHAKE_FAILED, diff --git a/lib/selection_iter.c b/lib/selection_iter.c index 9cb850f5d..3f13269cc 100644 --- a/lib/selection_iter.c +++ b/lib/selection_iter.c @@ -17,6 +17,7 @@ struct iter_local_state { trie_t *names; trie_t *addresses; unsigned int generation; // Used to distinguish old and valid records in tries + enum kr_selection_error last_error; }; enum record_state { @@ -249,6 +250,9 @@ void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport *transport = choose_transport(choices, valid_addresses, unresolved_types, num_to_resolve, qry->server_selection.timeouts, mempool, tcp, NULL); } else { *transport = NULL; + if (local_state->last_error == KR_SELECTION_DNSSEC_ERROR) { + qry->flags.DNSSEC_BOGUS = true; + } } update_name_state(*transport, local_state->names); @@ -286,6 +290,7 @@ void iter_error(struct kr_query *qry, const struct kr_transport *transport, enum } struct iter_local_state *local_state = qry->server_selection.local_state; struct address_state *addr_state = get_address_state(local_state, transport); + local_state->last_error = sel_error; error(qry, addr_state, transport, sel_error); } -- 2.47.2