diff --git a/bin/dig/dig.c b/bin/dig/dig.c index d31a0b664a..db73a74d9f 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -196,6 +196,9 @@ help(void) { " +[no]cmd (Control display of " "command line -\n" " global option)\n" + " +[no]coflag (Set compact denial of " + "existence ok flag)\n" + " in query)\n" " +[no]comments (Control display of " "packet " "header\n" @@ -213,7 +216,8 @@ help(void) { " +[no]dnssec (Request DNSSEC records)\n" " +domain=### (Set default domainname)\n" " +[no]edns[=###] (Set EDNS version) [0]\n" - " +ednsflags=### (Set EDNS flag bits)\n" + " +ednsflags=### (Set undefined EDNS flag " + "bits)\n" " +[no]ednsnegotiation (Set EDNS version " "negotiation)\n" " +ednsopt=###[:value] (Send specified EDNS " @@ -229,12 +233,14 @@ help(void) { " +[no]https[=###] (DNS-over-HTTPS mode) " "[/]\n" " +[no]https-get (Use GET instead of " - "default POST method while using HTTPS)\n" - " +[no]http-plain[=###] (DNS over plain HTTP " - "mode) " - "[/]\n" - " +[no]http-plain-get (Use GET instead of " - "default POST method while using plain HTTP)\n" + "default POST method\n" + " while using HTTPS)\n" + " +[no]http-plain[=###] (DNS over plain HTTP " + "mode) [/]\n" + " +[no]http-plain-get (Use GET instead of " + "default POST " + "method\n" + " while using plain HTTP)\n" " +[no]identify (ID responders in short " "answers)\n" #ifdef HAVE_LIBIDN2 @@ -263,7 +269,8 @@ help(void) { " +padding=### (Set padding block size " "[0])\n" " +qid=### (Specify the query ID to " - "use when sending queries)\n" + "use when sending\n" + " queries)\n" " +[no]qr (Print question before " "sending)\n" " +[no]question (Control display of " @@ -300,16 +307,19 @@ help(void) { " +timeout=### (Set query timeout) [5]\n" " +[no]tls (DNS-over-TLS mode)\n" " +[no]tls-ca[=file] (Enable remote server's " - "TLS certificate validation)\n" + "TLS certificate\n" + " validation)\n" " +[no]tls-hostname=hostname (Explicitly set " - "the expected TLS hostname)\n" + "the expected TLS\n" + " hostname)\n" " +[no]tls-certfile=file (Load client TLS " - "certificate chain from file)\n" + "certificate chain from\n" + " file)\n" " +[no]tls-keyfile=file (Load client TLS " "private key from file)\n" " +[no]trace (Trace delegation down " - "from root " - "[+dnssec])\n" + "from root [implies\n" + " +dnssec])\n" " +tries=### (Set number of UDP " "attempts) [3]\n" " +[no]ttlid (Control display of ttls " @@ -1285,6 +1295,11 @@ plus_option(char *option, bool is_batchfile, bool *need_clone, break; case 'o': /* comments */ switch (cmd[2]) { + case 'f': + case '\0': /* +co is a synonym for +coflag */ + FULLCHECK("coflag"); + lookup->coflag = state; + break; case 'm': FULLCHECK("comments"); lookup->comments = state; diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst index 59ac9f15dd..88b0a40307 100644 --- a/bin/dig/dig.rst +++ b/bin/dig/dig.rst @@ -298,6 +298,13 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to always has a global effect; it cannot be set globally and then overridden on a per-lookup basis. The default is to print this comment. +.. option:: +coflag, +co, +nocoflag, +noco + + This option sets [or does not set] the CO (Compact denial of + existence Ok) EDNS bit in the query. If set, it tells servers + that Compact Denial of Existence responses are acceptable when + replying to queries. The default is ``+nocoflag``. + .. option:: +comments, +nocomments This option toggles the display of some comment lines in the output, with @@ -363,7 +370,7 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to This option sets the must-be-zero EDNS flags bits (Z bits) to the specified value. Decimal, hex, and octal encodings are accepted. Setting a named flag - (e.g., DO) is silently ignored. By default, no Z bits are set. + (e.g. DO, CO) is silently ignored. By default, no Z bits are set. .. option:: +ednsnegotiation, +noednsnegotiation diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 87fbb41e1c..0f8ac1335c 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -789,6 +789,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) { looknew->aaonly = lookold->aaonly; looknew->adflag = lookold->adflag; looknew->cdflag = lookold->cdflag; + looknew->coflag = lookold->coflag; looknew->raflag = lookold->raflag; looknew->tcflag = lookold->tcflag; looknew->print_unknown_format = lookold->print_unknown_format; @@ -2655,10 +2656,13 @@ setup_lookup(dig_lookup_t *lookup) { } flags = lookup->ednsflags; - flags &= ~DNS_MESSAGEEXTFLAG_DO; + flags &= ~(DNS_MESSAGEEXTFLAG_DO | DNS_MESSAGEEXTFLAG_CO); if (lookup->dnssec) { flags |= DNS_MESSAGEEXTFLAG_DO; } + if (lookup->coflag) { + flags |= DNS_MESSAGEEXTFLAG_CO; + } add_opt(lookup->sendmsg, lookup->udpsize, lookup->edns, flags, opts, i); } diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 227c315f51..09d136363d 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -105,11 +105,10 @@ typedef struct dig_searchlist dig_searchlist_t; struct dig_lookup { unsigned int magic; isc_refcount_t references; - bool aaonly, adflag, badcookie, besteffort, cdflag, cleared, comments, - dns64prefix, dnssec, doing_xfr, done_as_is, ednsneg, expandaaaa, - expire, fuzzing, header_only, identify, /*%< Append an "on - server " message - */ + bool aaonly, adflag, badcookie, besteffort, cdflag, cleared, coflag, + comments, dns64prefix, dnssec, doing_xfr, done_as_is, ednsneg, + expandaaaa, expire, fuzzing, header_only, + identify, /*%< Append an "on server " message */ identify_previous_line, /*% Prepend a "Nameserver :" message, with newline and tab */ idnin, idnout, ignore, multiline, need_search, new_search, diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 252884c4f7..aa9525df37 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -284,6 +284,27 @@ if [ -x "$DIG" ]; then if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) + n=$((n + 1)) + echo_i "checking dig +coflag works ($n)" + ret=0 + dig_with_opts +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1 + grep "^; EDNS: version: 0, flags: co;" /dev/null || ret=1 + check_ttl_range dig.out.test$n "SOA" 300 || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + + if [ $HAS_PYYAML -ne 0 ]; then + n=$((n + 1)) + echo_i "checking dig +coflag +yaml works ($n)" + ret=0 + dig_with_opts +yaml +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1 + $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS flags >yamlget.out.test$n 2>&1 || ret=1 + read -r value ttl & DNS_MESSAGEEXTFLAG_DO) != 0) { ADD_STRING(target, " do"); } + if ((ps->ttl & DNS_MESSAGEEXTFLAG_CO) != 0) { + ADD_STRING(target, " co"); + } ADD_STRING(target, "\n"); mbz = ps->ttl & 0xffff; - mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */ + /* Exclude Known Flags. */ + mbz &= ~(DNS_MESSAGEEXTFLAG_DO | DNS_MESSAGEEXTFLAG_CO); if (mbz != 0) { INDENT(style); ADD_STRING(target, "MBZ: "); @@ -3871,8 +3875,12 @@ dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section, if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0) { ADD_STRING(target, " do"); } + if ((ps->ttl & DNS_MESSAGEEXTFLAG_CO) != 0) { + ADD_STRING(target, " co"); + } mbz = ps->ttl & 0xffff; - mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */ + /* Exclude Known Flags. */ + mbz &= ~(DNS_MESSAGEEXTFLAG_DO | DNS_MESSAGEEXTFLAG_CO); if (mbz != 0) { ADD_STRING(target, "; MBZ: "); snprintf(buf, sizeof(buf), "0x%.4x", mbz);