diff --git a/CHANGES b/CHANGES index f99a130b56..94ea37ccb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3812. [func] Dig now supports sending arbitary EDNS options from + the command line (+ednsopt=code[:value]). [RT #35584] + 3811. [func] "serial-update-method date;" sets serial number on dynamic update to today's date in YYYYMMDDNN format. (Thanks to Bradley Forschinger.) [RT #24903] diff --git a/README b/README index aed2f7fd20..1bb96e117f 100644 --- a/README +++ b/README @@ -51,6 +51,14 @@ BIND 9 For up-to-date release notes and errata, see http://www.isc.org/software/bind9/releasenotes +BIND 9.11.0 + + BIND 9.11.0 includes a number of changes from BIND 9.10 and earlier + releases. New features include: + + - Dig now supports sending of arbitary EDNS options by specifying + them on the command line. + BIND 9.10.0 BIND 9.10.0 includes a number of changes from BIND 9.9 and earlier diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 007bcdd767..e9a537b5a2 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -29,8 +29,8 @@ #include #include #include -#include #include +#include #include #include @@ -755,7 +755,7 @@ plus_option(char *option, isc_boolean_t is_batchfile, { isc_result_t result; char option_store[256]; - char *cmd, *value, *ptr; + char *cmd, *value, *ptr, *code; isc_uint32_t num; isc_boolean_t state = ISC_TRUE; #ifdef DIG_SIGCHASE @@ -922,19 +922,54 @@ plus_option(char *option, isc_boolean_t is_batchfile, case 'e': switch (cmd[1]) { case 'd': - FULLCHECK("edns"); - if (!state) { - lookup->edns = -1; + switch(cmd[2]) { + case 'n': + switch (cmd[3]) { + case 's': + switch (cmd[4]) { + case 0: + FULLCHECK("edns"); + if (!state) { + lookup->edns = -1; + break; + } + if (value == NULL) { + lookup->edns = 0; + break; + } + result = parse_uint(&num, + value, + 255, + "edns"); + if (result != ISC_R_SUCCESS) + fatal("Couldn't parse " + "edns"); + lookup->edns = num; + break; + case 'o': + FULLCHECK("ednsopt"); + if (!state) { + lookup->ednsoptscnt = 0; + break; + } + if (value == NULL) + fatal("ednsopt no " + "code point " + "specified"); + code = next_token(&value, ":"); + save_opt(lookup, code, value); + break; + default: + goto invalid_option; + } + break; + default: + goto invalid_option; + } break; + default: + goto invalid_option; } - if (value == NULL) { - lookup->edns = 0; - break; - } - result = parse_uint(&num, value, 255, "edns"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse edns"); - lookup->edns = num; break; case 'x': FULLCHECK("expire"); diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 999a5609a4..7a4afed666 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -803,11 +803,23 @@ - Specify the EDNS version to query with. Valid values - are 0 to 255. Setting the EDNS version will cause - a EDNS query to be sent. - clears the remembered EDNS version. EDNS is set to - 0 by default. + Specify the EDNS version to query with. Valid values + are 0 to 255. Setting the EDNS version will cause + a EDNS query to be sent. + clears the remembered EDNS version. EDNS is set to + 0 by default. + + + + + + + + + Specify EDNS option with code point + clears the EDNS options to to be sent. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 3bc81aff45..cfc7961644 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -811,6 +811,8 @@ make_empty_lookup(void) { #ifdef ISC_PLATFORM_USESIT looknew->sitvalue = NULL; #endif + looknew->ednsopts = NULL; + looknew->ednsoptscnt = 0; dns_fixedname_init(&looknew->fdomain); ISC_LINK_INIT(looknew, link); ISC_LIST_INIT(looknew->q); @@ -863,6 +865,8 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { looknew->sit = lookold->sit; looknew->sitvalue = lookold->sitvalue; #endif + looknew->ednsopts = lookold->ednsopts; + looknew->ednsoptscnt = lookold->ednsoptscnt; #ifdef DIG_SIGCHASE looknew->sigchase = lookold->sigchase; #if DIG_SIGCHASE_TD @@ -1463,6 +1467,45 @@ setup_libs(void) { dns_result_register(); } +#define EDNSOPTS 100U +static dns_ednsopt_t ednsopts[EDNSOPTS]; +static unsigned char ednsoptscnt = 0; + +void +save_opt(dig_lookup_t *lookup, char *code, char *value) { + isc_uint32_t num; + isc_buffer_t b; + isc_result_t result; + + if (ednsoptscnt == EDNSOPTS) + fatal("too many ednsopts"); + + result = parse_uint(&num, code, 65535, "ednsopt"); + if (result != ISC_R_SUCCESS) + fatal("bad edns code point: %s", code); + + ednsopts[ednsoptscnt].code = num; + ednsopts[ednsoptscnt].length = 0; + ednsopts[ednsoptscnt].value = NULL; + + if (value != NULL) { + char *buf; + buf = isc_mem_allocate(mctx, strlen(value)/2 + 1); + if (buf == NULL) + fatal("out of memory"); + isc_buffer_init(&b, buf, strlen(value)/2 + 1); + result = isc_hex_decodestring(value, &b); + check_result(result, "isc_hex_decodestring"); + ednsopts[ednsoptscnt].value = isc_buffer_base(&b); + ednsopts[ednsoptscnt].length = isc_buffer_usedlength(&b); + } + + if (lookup->ednsoptscnt == 0) + lookup->ednsopts = &ednsopts[ednsoptscnt]; + lookup->ednsoptscnt++; + ednsoptscnt++; +} + /*% * Add EDNS0 option record to a message. Currently, the only supported * options are UDP buffer size, the DO bit, and EDNS options @@ -2354,7 +2397,7 @@ setup_lookup(dig_lookup_t *lookup) { if (lookup->udpsize > 0 || lookup->dnssec || lookup->edns > -1 || lookup->ecs_addr != NULL) { - dns_ednsopt_t opts[DNS_EDNSOPTIONS]; + dns_ednsopt_t opts[EDNSOPTS + DNS_EDNSOPTIONS]; int i = 0; if (lookup->udpsize == 0) @@ -2441,6 +2484,12 @@ setup_lookup(dig_lookup_t *lookup) { i++; } + if (lookup->ednsoptscnt != 0) { + memmove(&opts[i], lookup->ednsopts, + sizeof(dns_ednsopt_t) * lookup->ednsoptscnt); + i += lookup->ednsoptscnt; + } + add_opt(lookup->sendmsg, lookup->udpsize, lookup->edns, lookup->dnssec, opts, i); } @@ -4143,6 +4192,12 @@ destroy_libs(void) { debug("Removing log context"); isc_log_destroy(&lctx); + while (ednsoptscnt > 0U) { + ednsoptscnt--; + if (ednsopts[ednsoptscnt].value != NULL) + isc_mem_free(mctx, ednsopts[ednsoptscnt].value); + } + debug("Destroy memory"); if (memdebugging != 0) isc_mem_stats(mctx, stderr); diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 205e6cd2ae..e5effffe56 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -192,6 +192,8 @@ isc_boolean_t sigchase; #ifdef ISC_PLATFORM_USESIT char *sitvalue; #endif + dns_ednsopt_t *ednsopts; + unsigned int ednsoptscnt; }; /*% The dig_query structure */ @@ -427,6 +429,8 @@ void chase_sig(dns_message_t *msg); #endif +void save_opt(dig_lookup_t *lookup, char *code, char *value); + ISC_LANG_ENDDECLS #endif