]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix Cookie and ECS implementations for dnspython 2.0.0
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 29 Sep 2020 10:41:58 +0000 (12:41 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 29 Sep 2020 12:32:49 +0000 (14:32 +0200)
regression-tests.dnsdist/clientsubnetoption.py
regression-tests.dnsdist/cookiesoption.py

index 79deb2c98d3dbea195a5ea4cb94d26611ee1a656..5da748ab0b0901758a0a5bb4349f75955599d229 100644 (file)
@@ -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))
index 6b9204b3e5487e2e32f5738d550322500ef5c8c6..d977e1030db6f83991dcd200c33bd68d0df0c2a6 100644 (file)
@@ -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
-