Commit 8ede7a97 authored by Evan Hunt's avatar Evan Hunt

[master] fix dig=+subnet zero-length prefix

4303.	[bug]		"dig +subnet" was unable to send a prefix length of
			zero, as it was incorrectly changed to 32 for v4
			prefixes or 128 for v6 prefixes. In addition to
			fixing this, "dig +subnet=0" has been added as a
			short form for 0.0.0.0/0. The same changes have
			also been made in "mdig". [RT #41553]
parent 30370d90
4303. [bug] "dig +subnet" was unable to send a prefix length of
zero, as it was incorrectly changed to 32 for v4
prefixes or 128 for v6 prefixes. In addition to
fixing this, "dig +subnet=0" has been added as a
short form for 0.0.0.0/0. The same changes have
also been made in "mdig". [RT #41553]
4302. [port] win32: fixed a build error in VS 2015. [RT #41426]
4301. [bug] dnssec-settime -p [DP]sync was not working. [RT #41534]
......
......@@ -1299,6 +1299,7 @@ plus_option(const char *option, isc_boolean_t is_batchfile,
}
if (lookup->edns == -1)
lookup->edns = 0;
result = parse_netprefix(&lookup->ecs_addr, value);
if (result != ISC_R_SUCCESS)
fatal("Couldn't parse client");
......
......@@ -1021,11 +1021,19 @@
</varlistentry>
<varlistentry>
<term><option>+[no]subnet=addr/prefix</option></term>
<term><option>+[no]subnet=addr[/netmask]</option></term>
<listitem>
<para>
Send an EDNS Client Subnet option with the specified
IP address or network prefix.
Send (don't send) an EDNS Client Subnet option with the
specified IP address or network prefix.
</para>
<para>
<command>dig +subnet=0.0.0.0/0</command>, or simply
<command>dig +subnet=0</command> for short, sends a
Client Subnet option with an empty address and a
source prefix length of zero, which signals a resolver
that the EDNS Client Subnet option should not be used
when resolving this query.
</para>
</listitem>
</varlistentry>
......
......@@ -1068,7 +1068,7 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
isc_sockaddr_t *sa = NULL;
struct in_addr in4;
struct in6_addr in6;
isc_uint32_t netmask = 0;
isc_uint32_t netmask = 0xffffffff;
char *slash = NULL;
isc_boolean_t parsed = ISC_FALSE;
char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX/128")];
......@@ -1084,6 +1084,8 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
fatal("invalid prefix length in '%s': %s\n",
value, isc_result_totext(result));
}
} else if (strcmp(value, "0") == 0) {
netmask = 0;
}
sa = isc_mem_allocate(mctx, sizeof(*sa));
......@@ -1092,14 +1094,14 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
if (inet_pton(AF_INET6, buf, &in6) == 1) {
parsed = ISC_TRUE;
isc_sockaddr_fromin6(sa, &in6, 0);
if (netmask == 0 || netmask > 128)
if (netmask > 128)
netmask = 128;
} else if (inet_pton(AF_INET, buf, &in4) == 1) {
parsed = ISC_TRUE;
isc_sockaddr_fromin(sa, &in4, 0);
if (netmask == 0 || netmask > 32)
if (netmask > 32)
netmask = 32;
} else if (netmask != 0) {
} else if (netmask != 0xffffffff) {
int i;
for (i = 0; i < 3; i++) {
......@@ -1110,6 +1112,9 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
break;
}
}
if (netmask > 32)
netmask = 32;
}
if (!parsed)
......
......@@ -250,6 +250,30 @@ if [ -x ${DIG} ] ; then
grep "CLIENT-SUBNET: 127.0.0.1/32/0" < dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:checking dig +subnet=0/0 ($n)"
ret=0
$DIG $DIGOPTS +tcp @10.53.0.2 +subnet=0/0 A a.example > dig.out.test$n 2>&1 || ret=1
grep "CLIENT-SUBNET: 0.0.0.0/0/0" < dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:checking dig +subnet=0 ($n)"
ret=0
$DIG $DIGOPTS +tcp @10.53.0.2 +subnet=0 A a.example > dig.out.test$n 2>&1 || ret=1
grep "CLIENT-SUBNET: 0.0.0.0/0/0" < dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:checking dig +subnet=::/0 ($n)"
ret=0
$DIG $DIGOPTS +tcp @10.53.0.2 +subnet=::/0 A a.example > dig.out.test$n 2>&1 || ret=1
grep "CLIENT-SUBNET: ::/0/0" < dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:checking dig +sp works as an abbriviated form of split ($n)"
......
......@@ -903,7 +903,7 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
isc_sockaddr_t *sa = NULL;
struct in_addr in4;
struct in6_addr in6;
isc_uint32_t netmask = 0;
isc_uint32_t netmask = 0xffffffff;
char *slash = NULL;
isc_boolean_t parsed = ISC_FALSE;
char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX/128")];
......@@ -918,6 +918,8 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
fatal("invalid prefix length in '%s': %s\n",
value, isc_result_totext(result));
}
} else if (strcmp(value, "0") == 0) {
netmask = 0;
}
sa = isc_mem_allocate(mctx, sizeof(*sa));
......@@ -926,14 +928,14 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
if (inet_pton(AF_INET6, buf, &in6) == 1) {
parsed = ISC_TRUE;
isc_sockaddr_fromin6(sa, &in6, 0);
if (netmask == 0 || netmask > 128)
if (netmask > 128)
netmask = 128;
} else if (inet_pton(AF_INET, buf, &in4) == 1) {
parsed = ISC_TRUE;
isc_sockaddr_fromin(sa, &in4, 0);
if (netmask == 0 || netmask > 32)
if (netmask > 32)
netmask = 32;
} else if (netmask != 0) {
} else if (netmask != 0xffffffff) {
int i;
for (i = 0; i < 3; i++) {
......@@ -945,6 +947,8 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
}
}
if (netmask > 32)
netmask = 32;
}
if (!parsed)
......
......@@ -592,12 +592,20 @@
</varlistentry>
<varlistentry>
<term><option>+[no]subnet=addr/prefix</option></term>
<term><option>+[no]subnet=addr[/netmask]</option></term>
<listitem>
<para>
Send an EDNS Client Subnet option with the specified
IP address or network prefix.
</para>
<para>
Send (don't send) an EDNS Client Subnet option with the
specified IP address or network prefix.
</para>
<para>
<command>mdig +subnet=0.0.0.0/0</command>, or simply
<command>mdig +subnet=0</command> for short, sends a
Client Subnet option with an empty address and a
source prefix length of zero, which signals a resolver
that the EDNS Client Subnet option should not be used
when resolving this query.
</para>
</listitem>
</varlistentry>
......
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