3951. [func] Add the ability to set yet-to-be-defined EDNS flags

to dig (+ednsflags=#). [RT #37142]

(cherry picked from commit 3867312e4c)
This commit is contained in:
Mark Andrews 2014-09-13 19:13:59 +10:00
parent 8a089c3007
commit 449b5bdc99
10 changed files with 253 additions and 17 deletions

View file

@ -161,6 +161,9 @@
during operation. If the read failed, named
could segfault. [RT #38559]
3951. [func] Add the ability to set yet-to-be-defined EDNS flags
to dig (+ednsflags=#). [RT #37142]
3937. [func] Added some debug logging to better indicate the
conditions causing SERVFAILs when resolving.
[RT #35538]

View file

@ -194,6 +194,7 @@ help(void) {
" +ndots=### (Set NDOTS value)\n"
" +subnet=addr (Set edns-client-subnet option)\n"
" +[no]edns[=###] (Set EDNS version) [0]\n"
" +ednsflags=### (Set EDNS flag bits)\n"
" +ednsopt=###[:value] (Send specified EDNS option)\n"
" +noednsopt (Clear list of +ednsopt options)\n"
" +[no]search (Set whether to use searchlist)\n"
@ -947,6 +948,25 @@ plus_option(char *option, isc_boolean_t is_batchfile,
"edns");
lookup->edns = num;
break;
case 'f':
FULLCHECK("ednsflags");
if (!state) {
lookup->ednsflags = 0;
break;
}
if (value == NULL) {
lookup->ednsflags = 0;
break;
}
result = parse_xint(&num,
value,
0xffff,
"ednsflags");
if (result != ISC_R_SUCCESS)
fatal("Couldn't parse "
"ednsflags");
lookup->ednsflags = num;
break;
case 'o':
FULLCHECK("ednsopt");
if (!state) {

View file

@ -646,6 +646,18 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>+[no]ednsflags[=#]</option></term>
<listitem>
<para>
Set 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) will silently be
ignored. By default, no Z bits are set.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>+[no]ednsopt[=code[:value]]</option></term>
<listitem>

View file

@ -788,6 +788,7 @@ make_empty_lookup(void) {
looknew->servfail_stops = ISC_TRUE;
looknew->besteffort = ISC_TRUE;
looknew->dnssec = ISC_FALSE;
looknew->ednsflags = 0;
looknew->opcode = dns_opcode_query;
looknew->expire = ISC_FALSE;
looknew->nsid = ISC_FALSE;
@ -882,6 +883,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
looknew->servfail_stops = lookold->servfail_stops;
looknew->besteffort = lookold->besteffort;
looknew->dnssec = lookold->dnssec;
looknew->ednsflags = lookold->ednsflags;
looknew->opcode = lookold->opcode;
looknew->expire = lookold->expire;
looknew->nsid = lookold->nsid;
@ -1020,11 +1022,11 @@ setup_text_key(void) {
isc_buffer_free(&namebuf);
}
isc_result_t
parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc) {
static isc_result_t
parse_uint_helper(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc, int base) {
isc_uint32_t n;
isc_result_t result = isc_parse_uint32(&n, value, 10);
isc_result_t result = isc_parse_uint32(&n, value, base);
if (result == ISC_R_SUCCESS && n > max)
result = ISC_R_RANGE;
if (result != ISC_R_SUCCESS) {
@ -1036,6 +1038,18 @@ parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
return (ISC_R_SUCCESS);
}
isc_result_t
parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc) {
return (parse_uint_helper(uip, value, max, desc, 10));
}
isc_result_t
parse_xint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc) {
return (parse_uint_helper(uip, value, max, desc, 0));
}
static isc_uint32_t
parse_bits(char *arg, const char *desc, isc_uint32_t max) {
isc_result_t result;
@ -1544,15 +1558,12 @@ save_opt(dig_lookup_t *lookup, char *code, char *value) {
*/
static void
add_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_uint16_t edns,
isc_boolean_t dnssec, dns_ednsopt_t *opts, size_t count)
unsigned int flags, dns_ednsopt_t *opts, size_t count)
{
dns_rdataset_t *rdataset = NULL;
isc_result_t result;
unsigned int flags = 0;
debug("add_opt()");
if (dnssec)
flags |= DNS_MESSAGEEXTFLAG_DO;
result = dns_message_buildopt(msg, &rdataset, edns, udpsize, flags,
opts, count);
check_result(result, "dns_message_buildopt");
@ -2442,6 +2453,7 @@ setup_lookup(dig_lookup_t *lookup) {
lookup->edns > -1 || lookup->ecs_addr != NULL)
{
dns_ednsopt_t opts[EDNSOPTS + DNS_EDNSOPTIONS];
unsigned int flags;
int i = 0;
if (lookup->udpsize == 0)
@ -2531,8 +2543,12 @@ setup_lookup(dig_lookup_t *lookup) {
i += lookup->ednsoptscnt;
}
flags = lookup->ednsflags;
flags &= ~DNS_MESSAGEEXTFLAG_DO;
if (lookup->dnssec)
flags |= DNS_MESSAGEEXTFLAG_DO;
add_opt(lookup->sendmsg, lookup->udpsize,
lookup->edns, lookup->dnssec, opts, i);
lookup->edns, flags, opts, i);
}
result = dns_message_rendersection(lookup->sendmsg,

View file

@ -193,6 +193,7 @@ isc_boolean_t sigchase;
#endif
dns_ednsopt_t *ednsopts;
unsigned int ednsoptscnt;
unsigned int ednsflags;
dns_opcode_t opcode;
};
@ -347,6 +348,10 @@ isc_result_t
parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc);
isc_result_t
parse_xint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
const char *desc);
isc_result_t
parse_netprefix(isc_sockaddr_t **sap, const char *value);

View file

@ -67,14 +67,15 @@ RANDFILE=$TOP/bin/tests/system/random.data
SUBDIRS="acl additional allow_query addzone autosign builtin
cacheclean case checkconf @CHECKDS@ checknames checkzone
@COVERAGE@ database delv dlv dlvauto dlz dlzexternal
dlzredir dname dns64 dnssec dsdigest dscp ecdsa emptyzones
filter-aaaa formerr forward geoip glue gost ixfr inline
legacy limits logfileconfig lwresd masterfile masterformat
metadata notify nslookup nsupdate pending @PKCS11_TEST@
reclimit redirect resolver rndc rpz rpzrecurse rrl rrchecker
rrsetorder rsabigexponent sit smartsign sortlist spf staticstub
statistics stub tkey tsig tsiggss unknown upforwd verify
views wildcard xfer xferquota zero zonechecks"
dlzredir dname dns64 dnssec dsdigest dscp ecdsa ednscompliance
emptyzones filter-aaaa formerr forward geoip glue gost
ixfr inline legacy limits logfileconfig lwresd masterfile
masterformat metadata notify nslookup nsupdate pending
@PKCS11_TEST@ reclimit redirect resolver rndc rpz rpzrecurse
rrl rrchecker rrsetorder rsabigexponent sit smartsign
sortlist spf staticstub statistics stub tkey tsig tsiggss
unknown upforwd verify views wildcard xfer xferquota zero
zonechecks"
# Use the CONFIG_SHELL detected by configure for tests
SHELL=@SHELL@

View file

@ -0,0 +1,17 @@
#!/bin/sh
#
# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
rm -f dig.out*

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
};
zone "." {
type master;
file "root.db";
};

View file

@ -0,0 +1,24 @@
; Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
$TTL 300
. IN SOA marka.isc.org. a.root.servers.nil. (
2010 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.6

View file

@ -0,0 +1,104 @@
#!/bin/sh
#
# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
n=0
zone=.
n=`expr $n + 1`
echo "I:check +edns=100 sets version 100 ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +qr +norec +edns=100 soa $zone > dig.out$n
grep "EDNS: version: 100," dig.out$n > /dev/null || { ret=1; reason="version"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
ret=0 reason=
echo "I:check +ednsopt=100 adds option 100 ($n)"
$DIG -p 5300 @10.53.0.1 +qr +norec +ednsopt=100 soa $zone > dig.out$n
grep "; OPT=100" dig.out$n > /dev/null || { ret=1; reason="option"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:check +ednsflags=0x80 sets flags to 0080 ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +qr +norec +ednsflags=0x80 soa $zone > dig.out$n
grep "MBZ: 0080" dig.out$n > /dev/null || { ret=1; reason="flags"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:Unknown EDNS version ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +norec +edns=100 soa $zone > dig.out$n
grep "status: BADVERS," dig.out$n > /dev/null || { ret=1; reason="status"; }
grep "EDNS: version: 0," dig.out$n > /dev/null || { ret=1; reason="version"; }
grep "IN.SOA." dig.out$n > /dev/null && { ret=1; reaons="soa"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:Unknown EDNS option ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +norec +ednsopt=100 soa $zone > dig.out$n
grep "status: NOERROR," dig.out$n > /dev/null || { ret=1; reason="status"; }
grep "EDNS: version: 0," dig.out$n > /dev/null || { ret=1; reason="version"; }
grep "; OPT=100" dig.out$n > /dev/null && { ret=1; reason="option"; }
grep "IN.SOA." dig.out$n > /dev/null || { ret=1; reason="nosoa"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:Unknown EDNS version + option ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +norec +edns=100 +ednsopt=100 soa $zone > dig.out$n
grep "status: BADVERS," dig.out$n > /dev/null || { ret=1; reason="status"; }
grep "EDNS: version: 0," dig.out$n > /dev/null || { ret=1; reason="version"; }
grep "; OPT=100" dig.out$n > /dev/null && { ret=1; reason="option"; }
grep "IN.SOA." dig.out$n > /dev/null && { ret=1; reason="soa"; }
if [ $ret != 0 ]; then echo "I:failed: $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:Unknown EDNS flag ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +norec +ednsflags=0x80 soa $zone > dig.out$n
grep "status: NOERROR," dig.out$n > /dev/null || { ret=1; reason="status"; }
grep "EDNS: version: 0," dig.out$n > /dev/null || { ret=1; reason="version"; }
grep "EDNS:.*MBZ" dig.out$n > /dev/null > /dev/null && { ret=1; reason="mbz"; }
grep ".IN.SOA." dig.out$n > /dev/null || { ret=1; reason="nosoa"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:Unknown EDNS version + flag ($n)"
ret=0 reason=
$DIG -p 5300 @10.53.0.1 +norec +edns=100 +ednsflags=0x80 soa $zone > dig.out$n
grep "status: BADVERS," dig.out$n > /dev/null || { ret=1; reason="status"; }
grep "EDNS: version: 0," dig.out$n > /dev/null || { ret=1; reason="version"; }
grep "EDNS:.*MBZ" dig.out$n > /dev/null > /dev/null && { ret=1; reason="mbz"; }
grep "IN.SOA." dig.out$n > /dev/null && { ret=1; reason="soa"; }
if [ $ret != 0 ]; then echo "I:failed $reason"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:exit status: $status"
exit $status