diff --git a/bin/dig/dig.c b/bin/dig/dig.c index d31a0b664a..1e724c6185 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" @@ -1285,6 +1288,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/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index f15884a183..b4c2c8ee9c 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -97,7 +97,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 63c07abecb..9fdc2db30e 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -3513,9 +3513,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: "); @@ -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);