diff --git a/bin/dig/dig.c b/bin/dig/dig.c index bb2abf880e..ff67a661d8 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" @@ -1618,6 +1621,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/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index fa9f2db954..557a745bbc 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -99,7 +99,8 @@ #define DNS_MESSAGEFLAG_CD 0x0010U /*%< EDNS0 extended message flags */ -#define DNS_MESSAGEEXTFLAG_DO 0x8000U +#define DNS_MESSAGEEXTFLAG_DO 0x8000U /* DNSSEC OK */ +#define DNS_MESSAGEEXTFLAG_CO 0x4000U /* Compact denial of existence OK */ /*%< EDNS0 extended OPT codes */ #define DNS_OPT_LLQ 1 /*%< LLQ opt code */ diff --git a/lib/dns/message.c b/lib/dns/message.c index 3e92dcd03b..76558fdf37 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -3685,9 +3685,13 @@ dns_message_pseudosectiontoyaml(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"); + } 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);