Commit e560fbdf authored by Mark Andrews's avatar Mark Andrews
Browse files

3812. [func] Dig now supports sending arbitary EDNS options from

                        the command line (+ednsopt=code[:value]). [RT #35584]
parent b7fcdb0b
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]
......
......@@ -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
......
......@@ -29,8 +29,8 @@
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/string.h>
#include <isc/util.h>
#include <isc/task.h>
#include <isc/util.h>
#include <dns/byaddr.h>
#include <dns/fixedname.h>
......@@ -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;
break;
}
if (value == NULL) {
lookup->edns = 0;
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;
}
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");
......
......@@ -803,11 +803,23 @@
<term><option>+edns=#</option></term>
<listitem>
<para>
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. <option>+noedns</option>
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. <option>+noedns</option>
clears the remembered EDNS version. EDNS is set to
0 by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>+[no]ednsopt[=code[:value]]</option></term>
<listitem>
<para>
Specify EDNS option with code point <option>code</code>
and optionally payload of <option>value</value> as a
hexadecimal string. <option>+noednsopt</option>
clears the EDNS options to to be sent.
</para>
</listitem>
</varlistentry>
......
......@@ -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);
......
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment