]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
when FORMERR comes, differentiate based on OPT
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 1 Feb 2021 09:09:16 +0000 (10:09 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 2 Feb 2021 18:22:08 +0000 (19:22 +0100)
In particular, non-support of EDNS is implied iff FORMERR without OPT
comes.  If OPT is there, one possibility is that there was something
wrong in the OPT that *we* sent, but it seems much more likely that
this particular server is just bad and we want to try another one.
https://tools.ietf.org/html/rfc6891#section-7
In particular, we would be in trouble if we dropped OPT in a zone
that is covered by DNSSEC.

lib/layer/iterate.c
lib/selection.c
lib/selection.h
tests/integration/deckard

index b1c1ff77f6f93d22fd91c7e8638c745d7158d002..94342cfb510eccdf09d31ef3b76c09c33ea34512 100644 (file)
@@ -1094,7 +1094,11 @@ static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt)
                break;
        case KNOT_RCODE_FORMERR:
                ret = KR_STATE_FAIL;
-               selection_error = KR_SELECTION_FORMERR;
+               if (knot_pkt_has_edns(pkt)) {
+                       selection_error = KR_SELECTION_FORMERR_EDNS;
+               } else {
+                       selection_error = KR_SELECTION_FORMERR;
+               }
                break;
        case KNOT_RCODE_NOTIMPL:
                ret = KR_STATE_FAIL;
index d4925481afbfabaadaa064e75061b66e63e5109e..1f47e159b602e06b0a1e5bae3848ae60c3e48d0d 100644 (file)
@@ -42,6 +42,7 @@ static const char *kr_selection_error_str(enum kr_selection_error err) {
                X(REFUSED);
                X(SERVFAIL);
                X(FORMERR);
+               X(FORMERR_EDNS);
                X(NOTIMPL);
                X(OTHER_RCODE);
                X(MALFORMED);
@@ -524,6 +525,9 @@ void error(struct kr_query *qry, struct address_state *addr_state,
                        qry->flags.NO_EDNS = true;
                }
                break;
+       case KR_SELECTION_FORMERR_EDNS:
+               addr_state->broken = true;
+               break;
        case KR_SELECTION_MISMATCHED:
                if (qry->flags.NO_0X20 && qry->flags.TCP) {
                        addr_state->broken = true;
index ef7cffd4ae1370f4e5feb1ade32811bc81366925..59e478bca7c814206a2f5edaf8222300b91ddd0a 100644 (file)
@@ -32,7 +32,8 @@ enum kr_selection_error {
        // RCODEs
        KR_SELECTION_REFUSED,
        KR_SELECTION_SERVFAIL,
-       KR_SELECTION_FORMERR,
+       KR_SELECTION_FORMERR,      /// inside an answer without an OPT record
+       KR_SELECTION_FORMERR_EDNS, /// with an OPT record
        KR_SELECTION_NOTIMPL,
        KR_SELECTION_OTHER_RCODE,
 
index 63b699aac11583da61647b8d1d920745b053dd66..ff1e8471785cedada669bf2304442ac0e86b7988 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 63b699aac11583da61647b8d1d920745b053dd66
+Subproject commit ff1e8471785cedada669bf2304442ac0e86b7988