From 311044fbf964e76f8f6d748826f4dfccba48648c Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 12 Mar 2025 10:02:05 +1100 Subject: [PATCH] Add "+showbadvers" to dig and reset EDNS version 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. (cherry picked from commit 6c271f63281ca2263ebbd7ad7f6788bc4449d279) --- bin/dig/dig.c | 18 ++++++++++++++++-- bin/dig/dig.rst | 6 ++++++ bin/dig/dighost.c | 12 +++++++++++- bin/dig/dighost.h | 7 ++++--- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 2b46471d8a..921b092bd4 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -284,6 +284,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 " @@ -1761,6 +1762,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) { @@ -1777,6 +1780,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"); @@ -2295,8 +2299,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"); diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst index 83c0ab7acf..ef492a34cf 100644 --- a/bin/dig/dig.rst +++ b/bin/dig/dig.rst @@ -610,6 +610,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. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 3e1aa5a8ea..87dbd5b80d 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -608,6 +608,7 @@ make_empty_lookup(void) { .idnout = idnout, .udpsize = -1, .edns = -1, + .original_edns = -1, .recurse = true, .retries = tries, .comments = true, @@ -741,6 +742,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; @@ -766,6 +768,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; @@ -1945,6 +1948,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); @@ -2470,7 +2474,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) { @@ -4314,6 +4319,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. */ diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 99c0c3c864..86ccfe0321 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -121,9 +121,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 */ @@ -154,6 +154,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;