]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't cache lack of EDNS based on received responses
authorMark Andrews <marka@isc.org>
Thu, 16 Jan 2025 05:24:05 +0000 (16:24 +1100)
committerNicki Křížek <nicki@isc.org>
Thu, 3 Apr 2025 10:44:21 +0000 (12:44 +0200)
Caching prevents server upgrades being detected in a timely manner
and it can also prevent DNSSEC responses being requested.

(cherry picked from commit 90b2f94d9bfa01ae4e8de277f49df26fa2167282)

lib/dns/resolver.c

index 0220bbd6bf5be02a6477608717b1c99df4c9983e..795791246b4ca3e3b07f8206d9e477dbeba11559 100644 (file)
@@ -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) {