]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
selection: retry after DNSSEC fail
authorŠtěpán Balážik <stepan.balazik@nic.cz>
Mon, 19 Oct 2020 14:23:40 +0000 (16:23 +0200)
committerŠtěpán Balážik <stepan.balazik@nic.cz>
Mon, 19 Oct 2020 15:13:27 +0000 (17:13 +0200)
Some other server might not have bogus signatures.

lib/resolve.c
lib/selection.h
lib/selection_iter.c

index 0d4fe2799a43313fde504602cb695af37f1e0540..463d80fe028d3044e778ba5556d3f4f0d2e43a7f 100644 (file)
@@ -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;
index c16cc15e715b491f2a7d54bcc085aa5b72e4caff..ef9436a6de4aaf5cfdc6665af0b39b3fbb5fcac4 100644 (file)
@@ -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,
index 9cb850f5d1a98c2f5b89822aa2db51254101ff1e..3f13269cc7967c7cb6269049da3dcd5df59a9358 100644 (file)
@@ -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);
 }