From: Remi Gacogne Date: Thu, 9 Feb 2017 13:50:11 +0000 (+0100) Subject: Correctly parse ECS with a source prefix-length value of 0 X-Git-Tag: rec-4.1.0-alpha1~255^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53221eafae3fe410586daf98cca0df3d81ea344c;p=thirdparty%2Fpdns.git Correctly parse ECS with a source prefix-length value of 0 It means there is no address there, but the family and source prefix-length values are still relevant. rfc7871 explicitly says that the family SHOULD be set to the transport over which the query is sent if source prefix-length is 0. It also states that a source prefix-length means the client is asking that no ECS value be sent. --- diff --git a/pdns/ednssubnet.cc b/pdns/ednssubnet.cc index d87f26c9e2..d6b9f8e006 100644 --- a/pdns/ednssubnet.cc +++ b/pdns/ednssubnet.cc @@ -37,20 +37,20 @@ namespace { bool getEDNSSubnetOptsFromString(const string& options, EDNSSubnetOpts* eso) { + //cerr<<"options.size:"<> 3)+1; + unsigned int octetsin = esow.sourceMask > 0 ? (((esow.sourceMask - 1)>> 3)+1) : 0; //cerr<<"octetsin:"< 0) + memcpy(&address.sin4.sin_addr.s_addr, options+sizeof(esow), octetsin); } else if(esow.family == 2) { if(len != sizeof(esow)+octetsin) return false; @@ -67,11 +68,12 @@ bool getEDNSSubnetOptsFromString(const char* options, unsigned int len, EDNSSubn return false; memset(&address, 0, sizeof(address)); address.sin4.sin_family = AF_INET6; - memcpy(&address.sin6.sin6_addr.s6_addr, options+sizeof(esow), octetsin); + if(octetsin > 0) + memcpy(&address.sin6.sin6_addr.s6_addr, options+sizeof(esow), octetsin); } else return false; - // cerr<<"Source address: "<source = Netmask(address, esow.sourceMask); /* 'address' has more bits set (potentially) than scopeMask. This leads to odd looking netmasks that promise more precision than they have. For this reason we truncate the address to scopeMask bits */