From: Vladimír Čunát Date: Mon, 1 Feb 2021 09:09:16 +0000 (+0100) Subject: when FORMERR comes, differentiate based on OPT X-Git-Tag: v5.3.0~13^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cdd2d234183ad1050e3e00559fc700a0435e8be;p=thirdparty%2Fknot-resolver.git when FORMERR comes, differentiate based on OPT 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. --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index b1c1ff77f..94342cfb5 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -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; diff --git a/lib/selection.c b/lib/selection.c index d4925481a..1f47e159b 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -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; diff --git a/lib/selection.h b/lib/selection.h index ef7cffd4a..59e478bca 100644 --- a/lib/selection.h +++ b/lib/selection.h @@ -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, diff --git a/tests/integration/deckard b/tests/integration/deckard index 63b699aac..ff1e84717 160000 --- a/tests/integration/deckard +++ b/tests/integration/deckard @@ -1 +1 @@ -Subproject commit 63b699aac11583da61647b8d1d920745b053dd66 +Subproject commit ff1e8471785cedada669bf2304442ac0e86b7988