return cls(parser.get_remaining())
+class CookieOption(Option):
+ def __init__(self, client: bytes, server: bytes):
+ super().__init__(dns.edns.OptionType.COOKIE)
+ self.client = client
+ self.server = server
+ if len(client) != 8:
+ raise ValueError("client cookie must be 8 bytes")
+ if len(server) != 0 and (len(server) < 8 or len(server) > 32):
+ raise ValueError("server cookie must be empty or between 8 and 32 bytes")
+
+ def to_wire(self, file: Any = None) -> Optional[bytes]:
+ if file:
+ file.write(self.client)
+ if len(self.server) > 0:
+ file.write(self.server)
+ return None
+ else:
+ return self.client + self.server
+
+ def to_text(self) -> str:
+ client = binascii.hexlify(self.client).decode()
+ if len(self.server) > 0:
+ server = binascii.hexlify(self.server).decode()
+ else:
+ server = ""
+ return f"COOKIE {client}:{server}"
+
+ @classmethod
+ def from_wire_parser(
+ cls, otype: Union[OptionType, str], parser: dns.wire.Parser
+ ) -> Option:
+ return cls(parser.get_bytes(8), parser.get_remaining())
+
+
_type_to_class: Dict[OptionType, Any] = {
OptionType.ECS: ECSOption,
OptionType.EDE: EDEOption,
OptionType.NSID: NSIDOption,
+ OptionType.COOKIE: CookieOption,
}
`RFC 4343 <https://tools.ietf.org/html/rfc4343>`_
Case-sensitivity clarification.
+`RFC 7873 <https://tools.ietf.org/html/rfc7873>`_
+ Domain Name System (DNS) Cookies
+
`RFC 8499 <https://tools.ietf.org/html/rfc8499>`_
DNS Terminology.
o = dns.edns.option_from_wire(dns.edns.OptionType.NSID, data, 0, len(data))
self.assertEqual(o.nsid, b"\xfe\xff")
+ def testCookieOption(self):
+ opt = dns.edns.CookieOption(b"12345678", b"")
+ io = BytesIO()
+ opt.to_wire(io)
+ data = io.getvalue()
+ self.assertEqual(data, b"12345678")
+ self.assertEqual(str(opt), "COOKIE 3132333435363738:")
+ opt = dns.edns.CookieOption(b"12345678", b"abcdefgh")
+ data = opt.to_wire()
+ self.assertEqual(data, b"12345678abcdefgh")
+ self.assertEqual(str(opt), "COOKIE 3132333435363738:6162636465666768")
+ # maximal server
+ opt = dns.edns.CookieOption(b"12345678", b"abcdefghabcdefghabcdefghabcdefgh")
+ io = BytesIO()
+ opt.to_wire(io)
+ data = io.getvalue()
+ self.assertEqual(data, b"12345678abcdefghabcdefghabcdefghabcdefgh")
+ # from wire
+ opt2 = dns.edns.option_from_wire(dns.edns.OptionType.COOKIE, data, 0, len(data))
+ self.assertEqual(opt.client, opt2.client)
+ self.assertEqual(opt.server, opt2.server)
+ # client too short
+ with self.assertRaises(ValueError):
+ opt = dns.edns.CookieOption(b"1234567", b"")
+ # client too long
+ with self.assertRaises(ValueError):
+ opt = dns.edns.CookieOption(b"123456789", b"")
+ # server too short
+ with self.assertRaises(ValueError):
+ opt = dns.edns.CookieOption(b"12345678", b"a")
+ # server too long
+ with self.assertRaises(ValueError):
+ opt = dns.edns.CookieOption(
+ b"12345678", b"abcdefghabcdefghabcdefghabcdefghi"
+ )
+
def test_option_registration(self):
U32OptionType = 9999