]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Add EDNS NSID option.
authorBob Halley <halley@dnspython.org>
Wed, 7 Feb 2024 00:08:01 +0000 (16:08 -0800)
committerBob Halley <halley@dnspython.org>
Wed, 7 Feb 2024 00:08:01 +0000 (16:08 -0800)
dns/edns.py
doc/whatsnew.rst
tests/test_edns.py

index c80e04825e5919094680eb42f352aec06020fd8e..b29afaa3bc0029436f13667cce4d6d54f2a18ffa 100644 (file)
@@ -17,6 +17,7 @@
 
 """EDNS Options"""
 
+import binascii
 import math
 import socket
 import struct
@@ -393,9 +394,37 @@ class EDEOption(Option):  # lgtm[py/missing-equals]
         return cls(code, btext)
 
 
+class NSIDOption(Option):
+    def __init__(self, nsid: bytes):
+        super().__init__(OptionType.NSID)
+        self.nsid = nsid
+
+    def to_wire(self, file: Any = None) -> Optional[bytes]:
+        if file:
+            file.write(self.nsid)
+            return None
+        else:
+            return self.nsid
+
+    def to_text(self) -> str:
+        if all(c >= 0x20 and c <= 0x7E for c in self.nsid):
+            # All ASCII printable, so it's probably a string.
+            value = self.nsid.decode()
+        else:
+            value = binascii.hexlify(self.nsid).decode()
+        return f"NSID {value}"
+
+    @classmethod
+    def from_wire_parser(
+        cls, otype: Union[OptionType, str], parser: dns.wire.Parser
+    ) -> Option:
+        return cls(parser.get_remaining())
+
+
 _type_to_class: Dict[OptionType, Any] = {
     OptionType.ECS: ECSOption,
     OptionType.EDE: EDEOption,
+    OptionType.NSID: NSIDOption,
 }
 
 
index a4619e515b150d7463c3bd89351a8521676451bc..ada72d59f38db4b8ab2b565b4486a5b7f64c6978 100644 (file)
@@ -6,7 +6,7 @@ What's New in dnspython
 2.6.0 (in development)
 ----------------------
 
-* TBD
+* Added support for the NSID EDNS option.
 
 2.5.0
 -----
index 37bd9709f98850754bfd9eec14d428d5be858294..98e468ba125cc7cee5f63f58797984f3c28d6cc4 100644 (file)
@@ -19,7 +19,6 @@
 import operator
 import struct
 import unittest
-
 from io import BytesIO
 
 import dns.edns
@@ -201,6 +200,22 @@ class OptionTestCase(unittest.TestCase):
         self.assertFalse(o1 == 123)
         self.assertTrue(o1 != 123)
 
+    def testNSIDOption(self):
+        opt = dns.edns.NSIDOption(b"testing")
+        io = BytesIO()
+        opt.to_wire(io)
+        data = io.getvalue()
+        self.assertEqual(data, b"testing")
+        self.assertEqual(str(opt), "NSID testing")
+        opt = dns.edns.NSIDOption(b"\xfe\xff")
+        io = BytesIO()
+        opt.to_wire(io)
+        data = io.getvalue()
+        self.assertEqual(data, b"\xfe\xff")
+        self.assertEqual(str(opt), "NSID feff")
+        o = dns.edns.option_from_wire(dns.edns.OptionType.NSID, data, 0, len(data))
+        self.assertEqual(o.nsid, b"\xfe\xff")
+
     def test_option_registration(self):
         U32OptionType = 9999