From: Remi Gacogne Date: Tue, 29 Sep 2020 10:41:58 +0000 (+0200) Subject: dnsdist: Fix Cookie and ECS implementations for dnspython 2.0.0 X-Git-Tag: auth-4.4.0-alpha2~64^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a41603bfb402211c7ae131419d13f5dadbd13df9;p=thirdparty%2Fpdns.git dnsdist: Fix Cookie and ECS implementations for dnspython 2.0.0 --- diff --git a/regression-tests.dnsdist/clientsubnetoption.py b/regression-tests.dnsdist/clientsubnetoption.py index 79deb2c98d..5da748ab0b 100644 --- a/regression-tests.dnsdist/clientsubnetoption.py +++ b/regression-tests.dnsdist/clientsubnetoption.py @@ -35,6 +35,7 @@ Requirements: from __future__ import print_function from __future__ import division +import math import socket import struct import dns @@ -125,7 +126,7 @@ class ClientSubnetOption(dns.edns.Option): """" Determines whether this instance is using the draft option code """ return self.option == DRAFT_OPTION_CODE - def to_wire(self, file): + def to_wire(self, file=None): """Create EDNS packet as defined in draft-vandergaast-edns-client-subnet-01.""" ip = self.calculate_ip() @@ -142,7 +143,10 @@ class ClientSubnetOption(dns.edns.Option): format = "!HBB%ds" % (mask_bits // 8) data = struct.pack(format, self.family, self.mask, self.scope, test) - file.write(data) + if file: + file.write(data) + else: + return data def from_wire(cls, otype, wire, current, olen): """Read EDNS packet as defined in draft-vandergaast-edns-client-subnet-01. @@ -173,6 +177,23 @@ class ClientSubnetOption(dns.edns.Option): from_wire = classmethod(from_wire) + # needed in 2.0.0.. + @classmethod + def from_wire_parser(cls, otype, parser): + family, src, scope = parser.get_struct('!HBB') + addrlen = int(math.ceil(src / 8.0)) + prefix = parser.get_bytes(addrlen) + if family == 1: + pad = 4 - addrlen + addr = dns.ipv4.inet_ntoa(prefix + b'\x00' * pad) + elif family == 2: + pad = 16 - addrlen + addr = dns.ipv6.inet_ntoa(prefix + b'\x00' * pad) + else: + raise ValueError('unsupported family') + + return cls(addr, src, scope, otype) + def __repr__(self): if self.family == FAMILY_IPV4: ip = socket.inet_ntop(socket.AF_INET, struct.pack('!L', self.ip)) diff --git a/regression-tests.dnsdist/cookiesoption.py b/regression-tests.dnsdist/cookiesoption.py index 6b9204b3e5..d977e1030d 100644 --- a/regression-tests.dnsdist/cookiesoption.py +++ b/regression-tests.dnsdist/cookiesoption.py @@ -22,12 +22,18 @@ class CookiesOption(dns.edns.Option): self.client = client self.server = server - def to_wire(self, file): + def to_wire(self, file=None): """Create EDNS packet as defined in draft-ietf-dnsop-cookies-09.""" - file.write(self.client) if self.server and len(self.server) > 0: - file.write(self.server) + data = self.client + self.server + else: + data = self.client + + if file: + file.write(data) + else: + return data def from_wire(cls, otype, wire, current, olen): """Read EDNS packet as defined in draft-ietf-dnsop-cookies-09. @@ -50,6 +56,22 @@ class CookiesOption(dns.edns.Option): from_wire = classmethod(from_wire) + # needed in 2.0.0 + @classmethod + def from_wire_parser(cls, otype, parser): + data = parser.get_remaining() + + if len(data) != 8 and (len(data) < 16 or len(data) > 40): + raise Exception('Invalid EDNS Cookies option') + + client = data[:8] + if len(data) > 8: + server = data[8:] + else: + server = None + + return cls(client, server) + def __repr__(self): return '%s(%s, %s)' % ( self.__class__.__name__, @@ -74,4 +96,3 @@ class CookiesOption(dns.edns.Option): dns.edns._type_to_class[0x000A] = CookiesOption -