]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add "+showbadvers" to dig and reset EDNS version
authorMark Andrews <marka@isc.org>
Tue, 11 Mar 2025 23:02:05 +0000 (10:02 +1100)
committerMark Andrews <marka@isc.org>
Thu, 13 Mar 2025 21:36:14 +0000 (21:36 +0000)
Add "+showbadvers" to display the BADVERS response similarly
to "+showbadcookie".  Additionally reset the EDNS version to
the requested version in "dig +trace" so that EDNS version
negotiation can be tested at all levels of the trace rather
that just when requesting the root nameservers.

bin/dig/dig.c
bin/dig/dig.rst
bin/dig/dighost.c
bin/dig/dighost.h

index 23f5b57130db7303d0b176a48efc5c95bbbe3baf..ff3148eacf65fbc7164fbf5cafa883989fe1ce65 100644 (file)
@@ -289,6 +289,7 @@ help(void) {
               "                                      form of answers - global "
               "option)\n"
               "                 +[no]showbadcookie  (Show BADCOOKIE message)\n"
+              "                 +[no]showbadvers    (Show BADVERS message)\n"
               "                 +[no]showsearch     (Search with intermediate "
               "results)\n"
               "                 +[no]split=##       (Split hex/base64 fields "
@@ -1772,6 +1773,8 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
                                                FULLCHECK("edns");
                                                if (!state) {
                                                        lookup->edns = -1;
+                                                       lookup->original_edns =
+                                                               -1;
                                                        break;
                                                }
                                                if (value == NULL) {
@@ -1788,6 +1791,7 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
                                                        goto exit_or_usage;
                                                }
                                                lookup->edns = num;
+                                               lookup->original_edns = num;
                                                break;
                                        case 'f':
                                                FULLCHECK("ednsflags");
@@ -2306,8 +2310,18 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
                        case 'w': /* showsearch */
                                switch (cmd[4]) {
                                case 'b':
-                                       FULLCHECK("showbadcookie");
-                                       lookup->showbadcookie = state;
+                                       switch (cmd[7]) {
+                                       case 'c':
+                                               FULLCHECK("showbadcookie");
+                                               lookup->showbadcookie = state;
+                                               break;
+                                       case 'v':
+                                               FULLCHECK("showbadvers");
+                                               lookup->showbadvers = state;
+                                               break;
+                                       default:
+                                               goto invalid_option;
+                                       }
                                        break;
                                case 's':
                                        FULLCHECK("showsearch");
index fa436fefacfe2381ef5dd19fcff200a5f74acde5..3b961f8feef53c6b7be48cb678b28a48fe3ccbdf 100644 (file)
@@ -614,6 +614,12 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
    BADCOOKIE rcode before retrying the request or not. The default
    is to not show the messages.
 
+.. option:: +showbadvers, +noshowbadvers
+
+   This option toggles whether to show the message containing the
+   BADVERS rcode before retrying the request or not. The default
+   is to not show the messages.
+
 .. option:: +showsearch, +noshowsearch
 
    This option performs [or does not perform] a search showing intermediate results.
index 69a310d2f3c2d04f3a58e59a972bd27f9ae8a164..5069af6b4f8bd01574d668d05def2908f85ac542 100644 (file)
@@ -605,6 +605,7 @@ make_empty_lookup(void) {
                .idnout = idnout,
                .udpsize = -1,
                .edns = -1,
+               .original_edns = -1,
                .recurse = true,
                .retries = tries,
                .comments = true,
@@ -738,6 +739,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
        }
 
        looknew->showbadcookie = lookold->showbadcookie;
+       looknew->showbadvers = lookold->showbadvers;
        looknew->sendcookie = lookold->sendcookie;
        looknew->seenbadcookie = lookold->seenbadcookie;
        looknew->badcookie = lookold->badcookie;
@@ -764,6 +766,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
        looknew->idnout = lookold->idnout;
        looknew->udpsize = lookold->udpsize;
        looknew->edns = lookold->edns;
+       looknew->original_edns = lookold->original_edns;
        looknew->recurse = lookold->recurse;
        looknew->aaonly = lookold->aaonly;
        looknew->adflag = lookold->adflag;
@@ -1938,6 +1941,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) {
                                }
                                domain = dns_fixedname_name(&lookup->fdomain);
                                dns_name_copy(name, domain);
+                               lookup->edns = lookup->original_edns;
                        }
                        debug("adding server %s", namestr);
                        num = getaddresses(lookup, namestr, &lresult);
@@ -2456,7 +2460,8 @@ setup_lookup(dig_lookup_t *lookup) {
                        lookup->udpsize = DEFAULT_EDNS_BUFSIZE;
                }
                if (lookup->edns < 0) {
-                       lookup->edns = DEFAULT_EDNS_VERSION;
+                       lookup->original_edns = lookup->edns =
+                               DEFAULT_EDNS_VERSION;
                }
 
                if (lookup->nsid) {
@@ -4300,6 +4305,11 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
        if (msg->rcode == dns_rcode_badvers && msg->opt != NULL &&
            (newedns = ednsvers(msg->opt)) < l->edns && l->ednsneg)
        {
+               if (l->showbadvers) {
+                       dighost_printmessage(query, &b, msg, true);
+                       dighost_received(isc_buffer_usedlength(&b), &peer,
+                                        query);
+               }
                /*
                 * Add minimum EDNS version required checks here if needed.
                 */
index 8c404d115d3aa3968bf21a46d85bf597c09afc4f..db8c842f752b07683bcfc7c0d6a2a83222ad5930 100644 (file)
@@ -117,9 +117,9 @@ struct dig_lookup {
                section_answer, section_authority, section_question,
                seenbadcookie, sendcookie, servfail_stops,
                setqid, /*% use a speciied query ID */
-               showbadcookie, stats, tcflag, tcp_keepalive, tcp_mode,
-               tcp_mode_set, tls_mode, /*% connect using TLS */
-               trace,                  /*% dig +trace */
+               showbadcookie, showbadvers, stats, tcflag, tcp_keepalive,
+               tcp_mode, tcp_mode_set, tls_mode, /*% connect using TLS */
+               trace,                            /*% dig +trace */
                trace_root, /*% initial query for either +trace or +nssearch */
                ttlunits, use_usec, waiting_connect, zflag;
        char textname[MXNAME]; /*% Name we're going to be looking up */
@@ -148,6 +148,7 @@ struct dig_lookup {
        int nsfound;
        int16_t udpsize;
        int16_t edns;
+       int16_t original_edns;
        int16_t padding;
        uint32_t ixfr_serial;
        isc_buffer_t rdatabuf;