From f5df40956ab8c380370b66363149908e2aaa1d6d Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Fri, 3 May 2019 08:17:54 -0700 Subject: [PATCH] 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. --- dns/edns.py | 3 ++- tests/test_edns.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) 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() -- 2.47.3