From: Mark Andrews Date: Thu, 16 Jan 2025 05:24:05 +0000 (+1100) Subject: Don't cache lack of EDNS based on received responses X-Git-Tag: v9.18.36~2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ee41c81fde8a3f8ffa74dcd3fe49f3f8b30290e;p=thirdparty%2Fbind9.git Don't cache lack of EDNS based on received responses Caching prevents server upgrades being detected in a timely manner and it can also prevent DNSSEC responses being requested. (cherry picked from commit 90b2f94d9bfa01ae4e8de277f49df26fa2167282) --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 0220bbd6bf5..795791246b4 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -374,7 +374,6 @@ struct fetchctx { dns_fwdpolicy_t fwdpolicy; isc_sockaddrlist_t bad; ISC_LIST(struct tried) edns; - isc_sockaddrlist_t bad_edns; dns_validator_t *validator; ISC_LIST(dns_validator_t) validators; dns_db_t *cache; @@ -2420,40 +2419,6 @@ cleanup_query: return result; } -static bool -bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { - isc_sockaddr_t *sa; - - for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; - sa = ISC_LIST_NEXT(sa, link)) - { - if (isc_sockaddr_equal(sa, address)) { - return true; - } - } - - return false; -} - -static void -add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { - isc_sockaddr_t *sa; - -#ifdef ENABLE_AFL - if (dns_fuzzing_resolver) { - return; - } -#endif /* ifdef ENABLE_AFL */ - if (bad_edns(fctx, address)) { - return; - } - - sa = isc_mem_get(fctx->mctx, sizeof(*sa)); - - *sa = *address; - ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link); -} - static struct tried * triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { struct tried *tried; @@ -4637,12 +4602,6 @@ fctx_destroy(fetchctx_t *fctx, bool exiting) { isc_mem_put(fctx->mctx, tried, sizeof(*tried)); } - for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; sa = next_sa) { - next_sa = ISC_LIST_NEXT(sa, link); - ISC_LIST_UNLINK(fctx->bad_edns, sa, link); - isc_mem_put(fctx->mctx, sa, sizeof(*sa)); - } - isc_counter_detach(&fctx->qc); if (fctx->gqc != NULL) { isc_counter_detach(&fctx->gqc); @@ -5004,7 +4963,6 @@ fctx_create(dns_resolver_t *res, isc_task_t *task, const dns_name_t *name, ISC_LIST_INIT(fctx->forwarders); ISC_LIST_INIT(fctx->bad); ISC_LIST_INIT(fctx->edns); - ISC_LIST_INIT(fctx->bad_edns); ISC_LIST_INIT(fctx->validators); atomic_init(&fctx->attributes, 0); @@ -8541,7 +8499,6 @@ rctx_parse(respctx_t *rctx) { */ rctx->retryopts |= DNS_FETCHOPT_NOEDNS0; rctx->resend = true; - add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { rctx->broken_server = result; @@ -8559,7 +8516,6 @@ rctx_parse(respctx_t *rctx) { */ rctx->retryopts |= DNS_FETCHOPT_NOEDNS0; rctx->resend = true; - add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else { rctx->broken_server = DNS_R_UNEXPECTEDRCODE; @@ -8674,56 +8630,6 @@ rctx_edns(respctx_t *rctx) { resquery_t *query = rctx->query; fetchctx_t *fctx = rctx->fctx; - /* - * We have an affirmative response to the query and we have - * previously got a response from this server which indicated - * EDNS may not be supported so we can now cache the lack of - * EDNS support. - */ - if (rctx->opt == NULL && !EDNSOK(query->addrinfo) && - (query->rmessage->rcode == dns_rcode_noerror || - query->rmessage->rcode == dns_rcode_nxdomain || - query->rmessage->rcode == dns_rcode_refused || - query->rmessage->rcode == dns_rcode_yxdomain) && - bad_edns(fctx, &query->addrinfo->sockaddr)) - { - dns_message_logpacket( - query->rmessage, "received packet (bad edns) from", - &query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), - fctx->res->mctx); - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_NOEDNS0, - FCTX_ADDRINFO_NOEDNS0); - } else if (rctx->opt == NULL && - (query->rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 && - !EDNSOK(query->addrinfo) && - (query->rmessage->rcode == dns_rcode_noerror || - query->rmessage->rcode == dns_rcode_nxdomain) && - (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0) - { - /* - * We didn't get a OPT record in response to a EDNS - * query. - * - * Old versions of named incorrectly drop the OPT record - * when there is a signed, truncated response so we - * check that TC is not set. - * - * Record that the server is not talking EDNS. While - * this should be safe to do for any rcode we limit it - * to NOERROR and NXDOMAIN. - */ - dns_message_logpacket( - query->rmessage, "received packet (no opt) from", - &query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), - fctx->res->mctx); - dns_adb_changeflags(fctx->adb, query->addrinfo, - FCTX_ADDRINFO_NOEDNS0, - FCTX_ADDRINFO_NOEDNS0); - } - /* * If we get a non error EDNS response record the fact so we * won't fallback to plain DNS in the future for this server. @@ -10331,7 +10237,6 @@ rctx_badserver(respctx_t *rctx, isc_result_t result) { /* * Remember that they may not like EDNS0. */ - add_bad_edns(fctx, &query->addrinfo->sockaddr); inc_stats(fctx->res, dns_resstatscounter_edns0fail); } else if (rcode == dns_rcode_formerr) { if (query->rmessage->cc_echoed) {