diff --git a/bin/dig/dig.c b/bin/dig/dig.c index bb2abf880e..29b19080b1 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -193,6 +193,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" @@ -210,7 +213,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 " @@ -226,12 +230,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 @@ -258,15 +264,23 @@ help(void) { " +padding=### (Set padding block size " "[0])\n" " " - "+[no]proxy[=src_addr[#src_port]-dst_addr[#dst_port]] " - "(Add PROXYv2 headers to the queries. If addresses are omitted, " - "LOCAL PROXYv2 headers are added)\n" + "+[no]proxy[=src_addr[#src_port]-dst_addr[#dst_port]]\n" + " (Add PROXYv2 headers to " + "the queries. If\n" + " addresses are omitted, " + "LOCAL PROXYv2\n" + " headers are added)\n" " " - "+[no]proxy-plain[=src_addr[#src_port]-dst_addr[#dst_port]] " - "(The same as '+[no]proxy', but send PROXYv2 headers ahead of " - "any encryption if an encrypted transport is used)\n" + "+[no]proxy-plain[=src_addr[#src_port]-dst_addr[#dst_port]]\n" + " (The same as'+[no]proxy', " + "but send PROXYv2\n" + " headers ahead of any " + "encryption if an\n" + " encrypted transport is " + "used)\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 " @@ -299,22 +313,29 @@ help(void) { " +subnet=addr (Set edns-client-subnet " "option)\n" " +[no]svcparamkeycompat (Display backward-" - "compatible SvcParamKey names (keyN) for non-initial entries)\n" + "compatible\n" + " SvcParamKey names (keyN) " + "for non-initial\n" + " entries)\n" " +[no]tcflag (Set TC flag in query " "(+[no]tcflag))\n" " +[no]tcp (TCP mode (+[no]vc))\n" " +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 [implies +dnssec])\n" + "from root [implies\n" + " +dnssec])\n" " +tries=### (Set number of UDP " "attempts) [3]\n" " +[no]ttlid (Control display of ttls " @@ -1618,6 +1639,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 dfb6893a68..a99b6b873e 100644 --- a/bin/dig/dig.rst +++ b/bin/dig/dig.rst @@ -302,6 +302,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 @@ -362,7 +369,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 533dc79d2e..7756855b8a 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -760,6 +760,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; @@ -2576,10 +2577,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 3e446177e0..8bb059ec94 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -102,9 +102,9 @@ 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, - svcparamkeycompat, expire, fuzzing, header_only, + bool aaonly, adflag, badcookie, besteffort, cdflag, cleared, coflag, + comments, dns64prefix, dnssec, doing_xfr, done_as_is, ednsneg, + expandaaaa, svcparamkeycompat, expire, fuzzing, header_only, identify, /*%< Append an "on server " message */ identify_previous_line, /*% Prepend a "Nameserver :" message, with newline and tab */ diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 591c0a3d54..190561e610 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: "); @@ -4124,8 +4128,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);