From 46dc1c34f9a4ef533e8202086b427a73c20a3cc7 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 29 Jul 2020 12:34:54 +1000 Subject: [PATCH] dig +bufsize=0 failed to disable EDNS as a side effect. (cherry picked from commit 0dc04cb901197d10a7ce90fd4bc0ef228a7b3171) Conflict: delete CHANGES Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/46dc1c34f9a4ef533e8202086b427a73c20a3cc7 --- CHANGES | 3 +++ bin/dig/dig.c | 39 ++++++++++++++++++++----------- bin/dig/dig.docbook | 14 ++++++----- bin/dig/dighost.c | 12 ++++++---- bin/dig/include/dig/dig.h | 6 ++++- bin/dig/nslookup.c | 1 - bin/tests/system/digdelv/tests.sh | 28 +++++++++++++++++++++- 7 files changed, 75 insertions(+), 28 deletions(-) diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 996cbb9495..32e5c67063 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -173,7 +173,7 @@ help(void) { " +[no]authority (Control display of authority section)\n" " +[no]badcookie (Retry BADCOOKIE responses)\n" " +[no]besteffort (Try to parse even illegal messages)\n" -" +bufsize=### (Set EDNS0 Max UDP packet size)\n" +" +bufsize[=###] (Set EDNS0 Max UDP packet size)\n" " +[no]cdflag (Set checking disabled flag in query)\n" " +[no]class (Control display of class in records)\n" " +[no]cmd (Control display of command line -\n" @@ -895,15 +895,21 @@ plus_option(const char *option, bool is_batchfile, break; case 'u':/* bufsize */ FULLCHECK("bufsize"); - if (value == NULL) - goto need_value; - if (!state) + if (!state) { goto invalid_option; + } + if (value == NULL) { + lookup->udpsize = DEFAULT_EDNS_BUFSIZE; + break; + } result = parse_uint(&num, value, COMMSIZE, "buffer size"); if (result != ISC_R_SUCCESS) fatal("Couldn't parse buffer size"); lookup->udpsize = num; + if (lookup->udpsize == 0) { + lookup->edns = -1; + } break; default: goto invalid_option; @@ -941,8 +947,9 @@ plus_option(const char *option, bool is_batchfile, break; case 'o': /* cookie */ FULLCHECK("cookie"); - if (state && lookup->edns == -1) - lookup->edns = 0; + if (state && lookup->edns == -1) { + lookup->edns = DEFAULT_EDNS_VERSION; + } lookup->sendcookie = state; if (value != NULL) { n = strlcpy(hexcookie, value, @@ -975,8 +982,9 @@ plus_option(const char *option, bool is_batchfile, break; case 'n': /* dnssec */ FULLCHECK("dnssec"); - if (state && lookup->edns == -1) - lookup->edns = 0; + if (state && lookup->edns == -1) { + lookup->edns = DEFAULT_EDNS_VERSION; + } lookup->dnssec = state; break; case 'o': /* domain */ @@ -1019,7 +1027,8 @@ plus_option(const char *option, bool is_batchfile, break; } if (value == NULL) { - lookup->edns = 0; + lookup->edns = + DEFAULT_EDNS_VERSION; break; } result = parse_uint(&num, @@ -1180,8 +1189,9 @@ plus_option(const char *option, bool is_batchfile, switch (cmd[2]) { case 'i': /* nsid */ FULLCHECK("nsid"); - if (state && lookup->edns == -1) - lookup->edns = 0; + if (state && lookup->edns == -1) { + lookup->edns = DEFAULT_EDNS_VERSION; + } lookup->nsid = state; break; case 's': /* nssearch */ @@ -1385,8 +1395,9 @@ plus_option(const char *option, bool is_batchfile, } break; } - if (lookup->edns == -1) - lookup->edns = 0; + if (lookup->edns == -1) { + lookup->edns = DEFAULT_EDNS_VERSION; + } if (lookup->ecs_addr != NULL) { isc_mem_free(mctx, lookup->ecs_addr); lookup->ecs_addr = NULL; @@ -1926,7 +1937,7 @@ parse_args(bool is_batchfile, bool config_only, debug("making new lookup"); default_lookup = make_empty_lookup(); default_lookup->adflag = true; - default_lookup->edns = 0; + default_lookup->edns = DEFAULT_EDNS_VERSION; default_lookup->sendcookie = true; #ifndef NOPOSIX diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 57ff556d49..456d1a88fe 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -570,12 +570,14 @@ - Set the UDP message buffer size advertised using EDNS0 - to B bytes. The maximum and - minimum sizes of this buffer are 65535 and 0 respectively. - Values outside this range are rounded up or down - appropriately. Values other than zero will cause a - EDNS query to be sent. + This option sets the UDP message buffer size advertised + using EDNS0 to B bytes. The + maximum and minimum sizes of this buffer are 65535 + and 0, respectively. +bufsize=0 + disables EDNS (use +bufsize=0 +edns + to send a EDNS messages with a advertised size of 0 + bytes). +bufsize restores the + default buffer size. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 8551459078..e82f176d98 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -846,7 +846,7 @@ make_empty_lookup(void) { looknew->rdclass_sigchaseset = false; #endif #endif - looknew->udpsize = 0; + looknew->udpsize = -1; looknew->edns = -1; looknew->recurse = true; looknew->aaonly = false; @@ -2641,10 +2641,12 @@ setup_lookup(dig_lookup_t *lookup) { unsigned int flags; unsigned int i = 0; - if (lookup->udpsize == 0) - lookup->udpsize = 4096; - if (lookup->edns < 0) - lookup->edns = 0; + if (lookup->udpsize < 0) { + lookup->udpsize = DEFAULT_EDNS_BUFSIZE; + } + if (lookup->edns < 0) { + lookup->edns = DEFAULT_EDNS_VERSION; + } if (lookup->nsid) { INSIST(i < MAXOPTS); diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index cc37c55db5..1ced573a50 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -63,6 +63,10 @@ #define SERVER_TIMEOUT 1 #define LOOKUP_LIMIT 64 + +#define DEFAULT_EDNS_VERSION 0 +#define DEFAULT_EDNS_BUFSIZE 4096 + /*% * Lookup_limit is just a limiter, keeping too many lookups from being * created. It's job is mainly to prevent the program from running away @@ -180,7 +184,7 @@ bool sigchase; dig_query_t *xfr_q; uint32_t retries; int nsfound; - uint16_t udpsize; + int16_t udpsize; int16_t edns; uint32_t ixfr_serial; isc_buffer_t rdatabuf; diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index d8c3b38080..8a3a84244b 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -808,7 +808,6 @@ addlookup(char *opt) { lookup->recurse = recurse; lookup->aaonly = aaonly; lookup->retries = tries; - lookup->udpsize = 0; lookup->comments = comments; if (lookup->rdtype == dns_rdatatype_any && !tcpmode_set) lookup->tcp_mode = true; diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 3d1010e1b7..31107f89c8 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -649,8 +649,34 @@ ret=0 pat='^;-m\..*IN.*A$' tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1 grep "Dump of all outstanding memory allocations" dig.out.test$n > /dev/null && ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + + n=$((n+1)) + echo_i "check that dig +bufsize=0 disables EDNS ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.3 a.example +bufsize=0 +qr > dig.out.test$n 2>&1 || ret=1 + grep "EDNS:" dig.out.test$n > /dev/null && ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + + n=$((n+1)) + echo_i "check that dig +bufsize=0 +edns sends EDNS with bufsize of 0 ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.3 a.example +bufsize=0 +edns +qr > dig.out.test$n 2>&1 || ret=1 + grep -E 'EDNS:.* udp: 0\r{0,1}$' dig.out.test$n > /dev/null|| ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` + + n=$((n+1)) + echo_i "check that dig +bufsize restores default bufsize ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.3 a.example +bufsize=0 +bufsize +qr > dig.out.test$n 2>&1 || ret=1 + lines=`grep "EDNS:.* udp: 4096" dig.out.test$n | wc -l` + test $lines -eq 2 || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + else echo_i "$DIG is needed, so skipping these dig tests" fi -- 2.23.0