From: Evan Hunt Date: Wed, 23 Mar 2016 22:00:30 +0000 (-0700) Subject: [master] ECS family 0 handling was still broken X-Git-Tag: v9.11.0a1^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7fa4c1845183b211f4e5aacc8071b4331e6c8b54;p=thirdparty%2Fbind9.git [master] ECS family 0 handling was still broken --- diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 08e9ff2d70b..2848f595699 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -1086,7 +1086,9 @@ 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) { + } + + if (strcmp(buf, "0") == 0) { parsed = ISC_TRUE; prefix_length = 0; } @@ -2510,7 +2512,7 @@ setup_lookup(dig_lookup_t *lookup) { } if (lookup->ecs_addr != NULL) { - isc_uint8_t addr[16], family; + isc_uint8_t addr[16], family, proto; isc_uint32_t plen; struct sockaddr *sa; struct sockaddr_in *sin; @@ -2528,7 +2530,13 @@ 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)); - switch (sa->sa_family) { + + /* If prefix length is zero, don't set family */ + proto = sa->sa_family; + if (plen == 0) + proto = AF_UNSPEC; + + switch (proto) { case AF_UNSPEC: INSIST(plen == 0); family = 0; diff --git a/bin/named/client.c b/bin/named/client.c index 159ee8b9be8..76cfcd385e3 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -1569,7 +1569,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message, } if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) && (client->ecs_addr.family == AF_INET || - client->ecs_addr.family == AF_INET6)) + client->ecs_addr.family == AF_INET6 || + client->ecs_addr.family == AF_UNSPEC)) { int i, addrbytes = (client->ecs_addrlen + 7) / 8; isc_uint8_t *paddr; @@ -1577,7 +1578,10 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message, /* Add client subnet option. */ isc_buffer_init(&buf, ecs, sizeof(ecs)); - if (client->ecs_addr.family == AF_INET) + if (client->ecs_addr.family == AF_UNSPEC || + client->ecs_addrlen == 0) + isc_buffer_putuint16(&buf, 0); + else if (client->ecs_addr.family == AF_INET) isc_buffer_putuint16(&buf, 1); else isc_buffer_putuint16(&buf, 2); @@ -1590,7 +1594,8 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message, uc = paddr[i]; if (i == addrbytes - 1 && ((client->ecs_addrlen % 8) != 0)) - uc &= (0xffU << (8 - (client->ecs_addrlen % 8))); + uc &= (0xffU << (8 - + (client->ecs_addrlen % 8))); isc_buffer_putuint8(&buf, uc); } @@ -1928,7 +1933,7 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) { return (DNS_R_OPTERR); } - if (addrlen == 0 && family != 0) { + if (addrlen == 0U && family != 0U) { ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), "EDNS client-subnet option: " diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 4c2d8e168fd..905e1232c03 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -263,7 +263,7 @@ if [ -x ${DIG} ] ; then 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 + grep "CLIENT-SUBNET: 0/0/0" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` @@ -271,7 +271,7 @@ if [ -x ${DIG} ] ; then 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 + grep "CLIENT-SUBNET: 0/0/0" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` @@ -279,7 +279,7 @@ if [ -x ${DIG} ] ; then 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 + grep "CLIENT-SUBNET: 0/0/0" < dig.out.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret`