From: Evan Hunt Date: Wed, 23 Mar 2016 16:29:57 +0000 (-0700) Subject: [master] more ECS handling fixes X-Git-Tag: v9.11.0a1~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05b7b63f17bad4ca8ca0de8f65f806f365e727d7;p=thirdparty%2Fbind9.git [master] more ECS handling fixes --- diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 71f657f9c72..839cd44cfef 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 a6ecf151148..08e9ff2d70b 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 9e2ab242d2b..7f4921a34ad 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 5436b0b4a0e..10773d3eafa 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 a580019dcfa..ddbf07a01c7 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); } }