From: Bob Halley Date: Fri, 3 May 2019 15:17:54 +0000 (-0700) Subject: The EDNS0 client-subnet code didn't work correctly for addresses that X-Git-Tag: v2.0.0rc1~365 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5df40956ab8c380370b66363149908e2aaa1d6d;p=thirdparty%2Fdnspython.git The EDNS0 client-subnet code didn't work correctly for addresses that were not a multiple of 8 bits. Instead of preserving the required number of high-order bits, it cleared that number of low-order bits. Thanks to Brian Wellington for discovering this and providing the correct code. --- diff --git a/dns/edns.py b/dns/edns.py index 5660f7bb..57dd256a 100644 --- a/dns/edns.py +++ b/dns/edns.py @@ -195,7 +195,8 @@ class ECSOption(Option): self.addrdata = addrdata[:nbytes] nbits = srclen % 8 if nbits != 0: - last = struct.pack('B', ord(self.addrdata[-1:]) & (0xff << nbits)) + last = struct.pack('B', + ord(self.addrdata[-1:]) & (0xff << (8 - nbits))) self.addrdata = self.addrdata[:-1] + last def to_text(self): diff --git a/tests/test_edns.py b/tests/test_edns.py index 0b4dad44..e84d83b4 100644 --- a/tests/test_edns.py +++ b/tests/test_edns.py @@ -54,6 +54,13 @@ class OptionTestCase(unittest.TestCase): data = io.getvalue() self.assertEqual(data, b'\x00\x01\x18\x00\x01\x02\x03') + def testECSOption25(self): + opt = dns.edns.ECSOption('1.2.3.255', 25) + io = BytesIO() + opt.to_wire(io) + data = io.getvalue() + self.assertEqual(data, b'\x00\x01\x19\x00\x01\x02\x03\x80') + def testECSOption_v6(self): opt = dns.edns.ECSOption('2001:4b98::1') io = BytesIO()