diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook
index 71f657f9c7..839cd44cfe 100644
--- a/bin/dig/dig.docbook
+++ b/bin/dig/dig.docbook
@@ -1022,19 +1022,20 @@
-
+
Send (don't send) an EDNS Client Subnet option with the
- specified IP address or network prefix.
+ specified IP address or network prefix.
dig +subnet=0.0.0.0/0, or simply
- dig +subnet=0 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.
+ dig +subnet=0 for short, sends an EDNS
+ client-subnet option with an empty address and a source
+ prefix-length of zero, which signals a resolver that
+ the client's address information must
+ not be used when resolving
+ this query.
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index a6ecf15114..08e9ff2d70 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -1070,7 +1070,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 = 0xffffffff;
+ isc_uint32_t prefix_length = 0xffffffff;
char *slash = NULL;
isc_boolean_t parsed = ISC_FALSE;
char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX/128")];
@@ -1081,13 +1081,14 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
slash = strchr(buf, '/');
if (slash != NULL) {
*slash = '\0';
- result = isc_parse_uint32(&netmask, slash + 1, 10);
+ result = isc_parse_uint32(&prefix_length, slash + 1, 10);
if (result != ISC_R_SUCCESS) {
fatal("invalid prefix length in '%s': %s\n",
value, isc_result_totext(result));
}
} else if (strcmp(value, "0") == 0) {
- netmask = 0;
+ parsed = ISC_TRUE;
+ prefix_length = 0;
}
sa = isc_mem_allocate(mctx, sizeof(*sa));
@@ -1096,14 +1097,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 > 128)
- netmask = 128;
+ if (prefix_length > 128)
+ prefix_length = 128;
} else if (inet_pton(AF_INET, buf, &in4) == 1) {
parsed = ISC_TRUE;
isc_sockaddr_fromin(sa, &in4, 0);
- if (netmask > 32)
- netmask = 32;
- } else if (netmask != 0xffffffff) {
+ if (prefix_length > 32)
+ prefix_length = 32;
+ } else if (prefix_length != 0xffffffff && prefix_length != 0) {
int i;
for (i = 0; i < 3 && strlen(buf) < sizeof(buf) - 2; i++) {
@@ -1115,14 +1116,17 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
}
}
- if (netmask > 32)
- netmask = 32;
+ if (prefix_length > 32)
+ prefix_length = 32;
}
if (!parsed)
fatal("invalid address '%s'", value);
- sa->length = netmask;
+ sa->length = prefix_length;
+ if (prefix_length == 0)
+ sa->type.sa.sa_family = AF_UNSPEC;
+
*sap = sa;
return (ISC_R_SUCCESS);
@@ -2524,17 +2528,23 @@ setup_lookup(dig_lookup_t *lookup) {
opts[i].length = (isc_uint16_t) addrl + 4;
check_result(result, "isc_buffer_allocate");
isc_buffer_init(&b, ecsbuf, sizeof(ecsbuf));
- if (sa->sa_family == AF_INET) {
+ switch (sa->sa_family) {
+ case AF_UNSPEC:
+ INSIST(plen == 0);
+ family = 0;
+ break;
+ case AF_INET:
family = 1;
sin = (struct sockaddr_in *) sa;
memmove(addr, &sin->sin_addr, 4);
- if ((plen % 8) != 0)
- addr[addrl-1] &=
- ~0 << (8 - (plen % 8));
- } else {
+ break;
+ case AF_INET6:
family = 2;
sin6 = (struct sockaddr_in6 *) sa;
memmove(addr, &sin6->sin6_addr, 16);
+ break;
+ default:
+ INSIST(0);
}
/* Mask off last address byte */
diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
index 9e2ab242d2..7f4921a34a 100644
--- a/bin/named/include/named/client.h
+++ b/bin/named/include/named/client.h
@@ -195,7 +195,7 @@ typedef ISC_LIST(ns_client_t) client_list_t;
#define NS_CLIENTATTR_WANTEXPIRE 0x0800 /*%< return seconds to expire */
#define NS_CLIENTATTR_HAVEEXPIRE 0x1000 /*%< return seconds to expire */
#define NS_CLIENTATTR_WANTOPT 0x2000 /*%< add opt to reply */
-#define NS_CLIENTATTR_HAVEECS 0x4000 /*%< sent an ECS option */
+#define NS_CLIENTATTR_HAVEECS 0x4000 /*%< received an ECS option */
#define NS_CLIENTATTR_NOSETFC 0x8000 /*%< don't set servfail cache */
diff --git a/bin/tools/mdig.docbook b/bin/tools/mdig.docbook
index 5436b0b4a0..10773d3eaf 100644
--- a/bin/tools/mdig.docbook
+++ b/bin/tools/mdig.docbook
@@ -593,7 +593,7 @@
-
+
Send (don't send) an EDNS Client Subnet option with the
@@ -601,11 +601,12 @@
mdig +subnet=0.0.0.0/0, or simply
- mdig +subnet=0 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.
+ mdig +subnet=0 for short, sends an EDNS
+ client-subnet option with an empty address and a source
+ prefix-length of zero, which signals a resolver that
+ the client's address information must
+ not be used when resolving
+ this query.
diff --git a/lib/dns/tests/rdata_test.c b/lib/dns/tests/rdata_test.c
index a580019dcf..ddbf07a01c 100644
--- a/lib/dns/tests/rdata_test.c
+++ b/lib/dns/tests/rdata_test.c
@@ -97,7 +97,7 @@ ATF_TC_BODY(edns_client_subnet, tc) {
0x00, 0x08, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00
},
- 8, ISC_FALSE
+ 8, ISC_TRUE
},
{
/* Option code family 1 (ipv4), source 0, scope 0 */
@@ -105,7 +105,7 @@ ATF_TC_BODY(edns_client_subnet, tc) {
0x00, 0x08, 0x00, 0x04,
0x00, 0x01, 0x00, 0x00
},
- 8, ISC_TRUE
+ 8, ISC_FALSE
},
{
/* Option code family 2 (ipv6) , source 0, scope 0 */
@@ -113,7 +113,7 @@ ATF_TC_BODY(edns_client_subnet, tc) {
0x00, 0x08, 0x00, 0x04,
0x00, 0x02, 0x00, 0x00
},
- 8, ISC_TRUE
+ 8, ISC_FALSE
},
{
/* extra octet */
@@ -222,9 +222,9 @@ ATF_TC_BODY(edns_client_subnet, tc) {
&dctx, 0, &target1);
dns_decompress_invalidate(&dctx);
if (test_data[i].ok)
- ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
else
- ATF_REQUIRE(result != ISC_R_SUCCESS);
+ ATF_CHECK(result != ISC_R_SUCCESS);
}
}