]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Handle FORMERR on unknown EDNS option that are echoed
authorMark Andrews <marka@isc.org>
Mon, 8 May 2023 07:39:51 +0000 (17:39 +1000)
committerMark Andrews <marka@isc.org>
Wed, 10 May 2023 23:32:02 +0000 (09:32 +1000)
If the resolver received a FORMERR response to a request with
an DNS COOKIE option present that echoes the option back, resend
the request without an DNS COOKIE option present.

lib/dns/include/dns/message.h
lib/dns/resolver.c

index 0c7cb4ee44964ce053dc0bd7727ec93103618faa..637675fd9ae8a0ddf76c86e7082b990a064c741e 100644 (file)
@@ -279,6 +279,7 @@ struct dns_message {
        unsigned int free_saved       : 1;
        unsigned int cc_ok            : 1;
        unsigned int cc_bad           : 1;
+       unsigned int cc_echoed        : 1;
        unsigned int tkey             : 1;
        unsigned int rdclass_set      : 1;
        unsigned int fuzzing          : 1;
index 2564f09de08c6e1b0ac86acb992b6ae5be72d3e5..3295b55a9a0df6040745e9018db644962f15e4b3 100644 (file)
@@ -7996,10 +7996,15 @@ rctx_opt(respctx_t *rctx) {
                        }
 
                        /* Cookie OK */
-                       query->rmessage->cc_ok = 1;
-                       inc_stats(fctx->res, dns_resstatscounter_cookieok);
-                       dns_adb_setcookie(fctx->adb, query->addrinfo, optvalue,
-                                         optlen);
+                       if (optlen == CLIENT_COOKIE_SIZE) {
+                               query->rmessage->cc_echoed = 1;
+                       } else {
+                               query->rmessage->cc_ok = 1;
+                               inc_stats(fctx->res,
+                                         dns_resstatscounter_cookieok);
+                               dns_adb_setcookie(fctx->adb, query->addrinfo,
+                                                 optvalue, optlen);
+                       }
                        break;
                default:
                        break;
@@ -9663,13 +9668,23 @@ rctx_badserver(respctx_t *rctx, isc_result_t result) {
                add_bad_edns(fctx, &query->addrinfo->sockaddr);
                inc_stats(fctx->res, dns_resstatscounter_edns0fail);
        } else if (rcode == dns_rcode_formerr) {
-               /*
-                * The server (or forwarder) doesn't understand us,
-                * but others might.
-                */
-               rctx->next_server = true;
-               rctx->broken_server = DNS_R_REMOTEFORMERR;
-               log_formerr(fctx, "server sent FORMERR");
+               if (query->rmessage->cc_echoed) {
+                       /*
+                        * Retry without DNS COOKIE.
+                        */
+                       query->addrinfo->flags |= FCTX_ADDRINFO_NOCOOKIE;
+                       rctx->resend = true;
+                       log_formerr(fctx, "server sent FORMERR with echoed DNS "
+                                         "COOKIE");
+               } else {
+                       /*
+                        * The server (or forwarder) doesn't understand us,
+                        * but others might.
+                        */
+                       rctx->next_server = true;
+                       rctx->broken_server = DNS_R_REMOTEFORMERR;
+                       log_formerr(fctx, "server sent FORMERR");
+               }
        } else if (rcode == dns_rcode_badvers) {
                unsigned int version;
 #if DNS_EDNS_VERSION > 0