aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/dns/rdtypes
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/dns/rdtypes')
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AFSDB.py45
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AMTRELAY.py91
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AVC.py26
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CAA.py71
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDNSKEY.py33
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDS.py29
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CERT.py116
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CNAME.py28
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CSYNC.py68
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DLV.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNAME.py27
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNSKEY.py33
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DS.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI48.py30
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI64.py30
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/GPOS.py126
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HINFO.py64
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HIP.py85
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ISDN.py78
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L32.py41
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L64.py47
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LOC.py353
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LP.py42
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/MX.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NID.py47
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NINFO.py26
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NS.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC.py67
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3.py126
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py69
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py53
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPT.py77
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/PTR.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RESINFO.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RP.py58
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RRSIG.py157
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RT.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SMIMEA.py9
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SOA.py86
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SPF.py26
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SSHFP.py68
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TKEY.py142
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TLSA.py9
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TSIG.py160
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TXT.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/URI.py79
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/WALLET.py9
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/X25.py57
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ZONEMD.py66
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/__init__.py70
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/CH/A.py59
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/CH/__init__.py22
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/A.py51
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/AAAA.py51
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/APL.py150
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/DHCID.py54
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/HTTPS.py9
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/IPSECKEY.py91
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/KX.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NAPTR.py110
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP.py60
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP_PTR.py24
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/PX.py73
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SRV.py75
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SVCB.py9
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/WKS.py100
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/IN/__init__.py35
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/__init__.py33
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/dnskeybase.py87
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/dsbase.py85
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/euibase.py70
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/mxbase.py87
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/nsbase.py63
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/svcbbase.py585
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/tlsabase.py71
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/txtbase.py106
-rw-r--r--.venv/lib/python3.12/site-packages/dns/rdtypes/util.py257
77 files changed, 5557 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AFSDB.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AFSDB.py
new file mode 100644
index 00000000..06a3b970
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AFSDB.py
@@ -0,0 +1,45 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.mxbase
+
+
+@dns.immutable.immutable
+class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX):
+ """AFSDB record"""
+
+ # Use the property mechanism to make "subtype" an alias for the
+ # "preference" attribute, and "hostname" an alias for the "exchange"
+ # attribute.
+ #
+ # This lets us inherit the UncompressedMX implementation but lets
+ # the caller use appropriate attribute names for the rdata type.
+ #
+ # We probably lose some performance vs. a cut-and-paste
+ # implementation, but this way we don't copy code, and that's
+ # good.
+
+ @property
+ def subtype(self):
+ "the AFSDB subtype"
+ return self.preference
+
+ @property
+ def hostname(self):
+ "the AFSDB hostname"
+ return self.exchange
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AMTRELAY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AMTRELAY.py
new file mode 100644
index 00000000..ed2b072b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AMTRELAY.py
@@ -0,0 +1,91 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdtypes.util
+
+
+class Relay(dns.rdtypes.util.Gateway):
+ name = "AMTRELAY relay"
+
+ @property
+ def relay(self):
+ return self.gateway
+
+
+@dns.immutable.immutable
+class AMTRELAY(dns.rdata.Rdata):
+ """AMTRELAY record"""
+
+ # see: RFC 8777
+
+ __slots__ = ["precedence", "discovery_optional", "relay_type", "relay"]
+
+ def __init__(
+ self, rdclass, rdtype, precedence, discovery_optional, relay_type, relay
+ ):
+ super().__init__(rdclass, rdtype)
+ relay = Relay(relay_type, relay)
+ self.precedence = self._as_uint8(precedence)
+ self.discovery_optional = self._as_bool(discovery_optional)
+ self.relay_type = relay.type
+ self.relay = relay.relay
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ relay = Relay(self.relay_type, self.relay).to_text(origin, relativize)
+ return "%d %d %d %s" % (
+ self.precedence,
+ self.discovery_optional,
+ self.relay_type,
+ relay,
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ precedence = tok.get_uint8()
+ discovery_optional = tok.get_uint8()
+ if discovery_optional > 1:
+ raise dns.exception.SyntaxError("expecting 0 or 1")
+ discovery_optional = bool(discovery_optional)
+ relay_type = tok.get_uint8()
+ if relay_type > 0x7F:
+ raise dns.exception.SyntaxError("expecting an integer <= 127")
+ relay = Relay.from_text(relay_type, tok, origin, relativize, relativize_to)
+ return cls(
+ rdclass, rdtype, precedence, discovery_optional, relay_type, relay.relay
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ relay_type = self.relay_type | (self.discovery_optional << 7)
+ header = struct.pack("!BB", self.precedence, relay_type)
+ file.write(header)
+ Relay(self.relay_type, self.relay).to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (precedence, relay_type) = parser.get_struct("!BB")
+ discovery_optional = bool(relay_type >> 7)
+ relay_type &= 0x7F
+ relay = Relay.from_wire_parser(relay_type, parser, origin)
+ return cls(
+ rdclass, rdtype, precedence, discovery_optional, relay_type, relay.relay
+ )
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AVC.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AVC.py
new file mode 100644
index 00000000..a27ae2d6
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/AVC.py
@@ -0,0 +1,26 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2016 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class AVC(dns.rdtypes.txtbase.TXTBase):
+ """AVC record"""
+
+ # See: IANA dns parameters for AVC
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CAA.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CAA.py
new file mode 100644
index 00000000..2e6a7e7e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CAA.py
@@ -0,0 +1,71 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class CAA(dns.rdata.Rdata):
+ """CAA (Certification Authority Authorization) record"""
+
+ # see: RFC 6844
+
+ __slots__ = ["flags", "tag", "value"]
+
+ def __init__(self, rdclass, rdtype, flags, tag, value):
+ super().__init__(rdclass, rdtype)
+ self.flags = self._as_uint8(flags)
+ self.tag = self._as_bytes(tag, True, 255)
+ if not tag.isalnum():
+ raise ValueError("tag is not alphanumeric")
+ self.value = self._as_bytes(value)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return '%u %s "%s"' % (
+ self.flags,
+ dns.rdata._escapify(self.tag),
+ dns.rdata._escapify(self.value),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ flags = tok.get_uint8()
+ tag = tok.get_string().encode()
+ value = tok.get_string().encode()
+ return cls(rdclass, rdtype, flags, tag, value)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!B", self.flags))
+ l = len(self.tag)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.tag)
+ file.write(self.value)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ flags = parser.get_uint8()
+ tag = parser.get_counted_bytes()
+ value = parser.get_remaining()
+ return cls(rdclass, rdtype, flags, tag, value)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDNSKEY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDNSKEY.py
new file mode 100644
index 00000000..b613409f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDNSKEY.py
@@ -0,0 +1,33 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.dnskeybase # lgtm[py/import-and-import-from]
+
+# pylint: disable=unused-import
+from dns.rdtypes.dnskeybase import ( # noqa: F401 lgtm[py/unused-import]
+ REVOKE,
+ SEP,
+ ZONE,
+)
+
+# pylint: enable=unused-import
+
+
+@dns.immutable.immutable
+class CDNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase):
+ """CDNSKEY record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDS.py
new file mode 100644
index 00000000..8312b972
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CDS.py
@@ -0,0 +1,29 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.dsbase
+
+
+@dns.immutable.immutable
+class CDS(dns.rdtypes.dsbase.DSBase):
+ """CDS record"""
+
+ _digest_length_by_type = {
+ **dns.rdtypes.dsbase.DSBase._digest_length_by_type,
+ 0: 1, # delete, RFC 8078 Sec. 4 (including Errata ID 5049)
+ }
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CERT.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CERT.py
new file mode 100644
index 00000000..f369cc85
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CERT.py
@@ -0,0 +1,116 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import struct
+
+import dns.dnssectypes
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+_ctype_by_value = {
+ 1: "PKIX",
+ 2: "SPKI",
+ 3: "PGP",
+ 4: "IPKIX",
+ 5: "ISPKI",
+ 6: "IPGP",
+ 7: "ACPKIX",
+ 8: "IACPKIX",
+ 253: "URI",
+ 254: "OID",
+}
+
+_ctype_by_name = {
+ "PKIX": 1,
+ "SPKI": 2,
+ "PGP": 3,
+ "IPKIX": 4,
+ "ISPKI": 5,
+ "IPGP": 6,
+ "ACPKIX": 7,
+ "IACPKIX": 8,
+ "URI": 253,
+ "OID": 254,
+}
+
+
+def _ctype_from_text(what):
+ v = _ctype_by_name.get(what)
+ if v is not None:
+ return v
+ return int(what)
+
+
+def _ctype_to_text(what):
+ v = _ctype_by_value.get(what)
+ if v is not None:
+ return v
+ return str(what)
+
+
+@dns.immutable.immutable
+class CERT(dns.rdata.Rdata):
+ """CERT record"""
+
+ # see RFC 4398
+
+ __slots__ = ["certificate_type", "key_tag", "algorithm", "certificate"]
+
+ def __init__(
+ self, rdclass, rdtype, certificate_type, key_tag, algorithm, certificate
+ ):
+ super().__init__(rdclass, rdtype)
+ self.certificate_type = self._as_uint16(certificate_type)
+ self.key_tag = self._as_uint16(key_tag)
+ self.algorithm = self._as_uint8(algorithm)
+ self.certificate = self._as_bytes(certificate)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ certificate_type = _ctype_to_text(self.certificate_type)
+ return "%s %d %s %s" % (
+ certificate_type,
+ self.key_tag,
+ dns.dnssectypes.Algorithm.to_text(self.algorithm),
+ dns.rdata._base64ify(self.certificate, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ certificate_type = _ctype_from_text(tok.get_string())
+ key_tag = tok.get_uint16()
+ algorithm = dns.dnssectypes.Algorithm.from_text(tok.get_string())
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ certificate = base64.b64decode(b64)
+ return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, certificate)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ prefix = struct.pack(
+ "!HHB", self.certificate_type, self.key_tag, self.algorithm
+ )
+ file.write(prefix)
+ file.write(self.certificate)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (certificate_type, key_tag, algorithm) = parser.get_struct("!HHB")
+ certificate = parser.get_remaining()
+ return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, certificate)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CNAME.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CNAME.py
new file mode 100644
index 00000000..665e407c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CNAME.py
@@ -0,0 +1,28 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.nsbase
+
+
+@dns.immutable.immutable
+class CNAME(dns.rdtypes.nsbase.NSBase):
+ """CNAME record
+
+ Note: although CNAME is officially a singleton type, dnspython allows
+ non-singleton CNAME rdatasets because such sets have been commonly
+ used by BIND and other nameservers for load balancing."""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CSYNC.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CSYNC.py
new file mode 100644
index 00000000..2f972f6e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/CSYNC.py
@@ -0,0 +1,68 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011, 2016 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdatatype
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class Bitmap(dns.rdtypes.util.Bitmap):
+ type_name = "CSYNC"
+
+
+@dns.immutable.immutable
+class CSYNC(dns.rdata.Rdata):
+ """CSYNC record"""
+
+ __slots__ = ["serial", "flags", "windows"]
+
+ def __init__(self, rdclass, rdtype, serial, flags, windows):
+ super().__init__(rdclass, rdtype)
+ self.serial = self._as_uint32(serial)
+ self.flags = self._as_uint16(flags)
+ if not isinstance(windows, Bitmap):
+ windows = Bitmap(windows)
+ self.windows = tuple(windows.windows)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ text = Bitmap(self.windows).to_text()
+ return "%d %d%s" % (self.serial, self.flags, text)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ serial = tok.get_uint32()
+ flags = tok.get_uint16()
+ bitmap = Bitmap.from_text(tok)
+ return cls(rdclass, rdtype, serial, flags, bitmap)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!IH", self.serial, self.flags))
+ Bitmap(self.windows).to_wire(file)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (serial, flags) = parser.get_struct("!IH")
+ bitmap = Bitmap.from_wire_parser(parser)
+ return cls(rdclass, rdtype, serial, flags, bitmap)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DLV.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DLV.py
new file mode 100644
index 00000000..6c134f18
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DLV.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.dsbase
+
+
+@dns.immutable.immutable
+class DLV(dns.rdtypes.dsbase.DSBase):
+ """DLV record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNAME.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNAME.py
new file mode 100644
index 00000000..bbf9186c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNAME.py
@@ -0,0 +1,27 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.nsbase
+
+
+@dns.immutable.immutable
+class DNAME(dns.rdtypes.nsbase.UncompressedNS):
+ """DNAME record"""
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.target.to_wire(file, None, origin, canonicalize)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNSKEY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNSKEY.py
new file mode 100644
index 00000000..6d961a9f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DNSKEY.py
@@ -0,0 +1,33 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.dnskeybase # lgtm[py/import-and-import-from]
+
+# pylint: disable=unused-import
+from dns.rdtypes.dnskeybase import ( # noqa: F401 lgtm[py/unused-import]
+ REVOKE,
+ SEP,
+ ZONE,
+)
+
+# pylint: enable=unused-import
+
+
+@dns.immutable.immutable
+class DNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase):
+ """DNSKEY record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DS.py
new file mode 100644
index 00000000..58b3108d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/DS.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.dsbase
+
+
+@dns.immutable.immutable
+class DS(dns.rdtypes.dsbase.DSBase):
+ """DS record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI48.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI48.py
new file mode 100644
index 00000000..c843be50
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI48.py
@@ -0,0 +1,30 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2015 Red Hat, Inc.
+# Author: Petr Spacek <pspacek@redhat.com>
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.euibase
+
+
+@dns.immutable.immutable
+class EUI48(dns.rdtypes.euibase.EUIBase):
+ """EUI48 record"""
+
+ # see: rfc7043.txt
+
+ byte_len = 6 # 0123456789ab (in hex)
+ text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI64.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI64.py
new file mode 100644
index 00000000..f6d7e257
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/EUI64.py
@@ -0,0 +1,30 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2015 Red Hat, Inc.
+# Author: Petr Spacek <pspacek@redhat.com>
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.euibase
+
+
+@dns.immutable.immutable
+class EUI64(dns.rdtypes.euibase.EUIBase):
+ """EUI64 record"""
+
+ # see: rfc7043.txt
+
+ byte_len = 8 # 0123456789abcdef (in hex)
+ text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab-cd-ef
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/GPOS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/GPOS.py
new file mode 100644
index 00000000..d79f4a06
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/GPOS.py
@@ -0,0 +1,126 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+def _validate_float_string(what):
+ if len(what) == 0:
+ raise dns.exception.FormError
+ if what[0] == b"-"[0] or what[0] == b"+"[0]:
+ what = what[1:]
+ if what.isdigit():
+ return
+ try:
+ (left, right) = what.split(b".")
+ except ValueError:
+ raise dns.exception.FormError
+ if left == b"" and right == b"":
+ raise dns.exception.FormError
+ if not left == b"" and not left.decode().isdigit():
+ raise dns.exception.FormError
+ if not right == b"" and not right.decode().isdigit():
+ raise dns.exception.FormError
+
+
+@dns.immutable.immutable
+class GPOS(dns.rdata.Rdata):
+ """GPOS record"""
+
+ # see: RFC 1712
+
+ __slots__ = ["latitude", "longitude", "altitude"]
+
+ def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
+ super().__init__(rdclass, rdtype)
+ if isinstance(latitude, float) or isinstance(latitude, int):
+ latitude = str(latitude)
+ if isinstance(longitude, float) or isinstance(longitude, int):
+ longitude = str(longitude)
+ if isinstance(altitude, float) or isinstance(altitude, int):
+ altitude = str(altitude)
+ latitude = self._as_bytes(latitude, True, 255)
+ longitude = self._as_bytes(longitude, True, 255)
+ altitude = self._as_bytes(altitude, True, 255)
+ _validate_float_string(latitude)
+ _validate_float_string(longitude)
+ _validate_float_string(altitude)
+ self.latitude = latitude
+ self.longitude = longitude
+ self.altitude = altitude
+ flat = self.float_latitude
+ if flat < -90.0 or flat > 90.0:
+ raise dns.exception.FormError("bad latitude")
+ flong = self.float_longitude
+ if flong < -180.0 or flong > 180.0:
+ raise dns.exception.FormError("bad longitude")
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return (
+ f"{self.latitude.decode()} {self.longitude.decode()} "
+ f"{self.altitude.decode()}"
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ latitude = tok.get_string()
+ longitude = tok.get_string()
+ altitude = tok.get_string()
+ return cls(rdclass, rdtype, latitude, longitude, altitude)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.latitude)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.latitude)
+ l = len(self.longitude)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.longitude)
+ l = len(self.altitude)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.altitude)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ latitude = parser.get_counted_bytes()
+ longitude = parser.get_counted_bytes()
+ altitude = parser.get_counted_bytes()
+ return cls(rdclass, rdtype, latitude, longitude, altitude)
+
+ @property
+ def float_latitude(self):
+ "latitude as a floating point value"
+ return float(self.latitude)
+
+ @property
+ def float_longitude(self):
+ "longitude as a floating point value"
+ return float(self.longitude)
+
+ @property
+ def float_altitude(self):
+ "altitude as a floating point value"
+ return float(self.altitude)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HINFO.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HINFO.py
new file mode 100644
index 00000000..06ad3487
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HINFO.py
@@ -0,0 +1,64 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class HINFO(dns.rdata.Rdata):
+ """HINFO record"""
+
+ # see: RFC 1035
+
+ __slots__ = ["cpu", "os"]
+
+ def __init__(self, rdclass, rdtype, cpu, os):
+ super().__init__(rdclass, rdtype)
+ self.cpu = self._as_bytes(cpu, True, 255)
+ self.os = self._as_bytes(os, True, 255)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f'"{dns.rdata._escapify(self.cpu)}" "{dns.rdata._escapify(self.os)}"'
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ cpu = tok.get_string(max_length=255)
+ os = tok.get_string(max_length=255)
+ return cls(rdclass, rdtype, cpu, os)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.cpu)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.cpu)
+ l = len(self.os)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.os)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ cpu = parser.get_counted_bytes()
+ os = parser.get_counted_bytes()
+ return cls(rdclass, rdtype, cpu, os)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HIP.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HIP.py
new file mode 100644
index 00000000..f3157da7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/HIP.py
@@ -0,0 +1,85 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2010, 2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import binascii
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+
+
+@dns.immutable.immutable
+class HIP(dns.rdata.Rdata):
+ """HIP record"""
+
+ # see: RFC 5205
+
+ __slots__ = ["hit", "algorithm", "key", "servers"]
+
+ def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
+ super().__init__(rdclass, rdtype)
+ self.hit = self._as_bytes(hit, True, 255)
+ self.algorithm = self._as_uint8(algorithm)
+ self.key = self._as_bytes(key, True)
+ self.servers = self._as_tuple(servers, self._as_name)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ hit = binascii.hexlify(self.hit).decode()
+ key = base64.b64encode(self.key).replace(b"\n", b"").decode()
+ text = ""
+ servers = []
+ for server in self.servers:
+ servers.append(server.choose_relativity(origin, relativize))
+ if len(servers) > 0:
+ text += " " + " ".join(x.to_unicode() for x in servers)
+ return "%u %s %s%s" % (self.algorithm, hit, key, text)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_uint8()
+ hit = binascii.unhexlify(tok.get_string().encode())
+ key = base64.b64decode(tok.get_string().encode())
+ servers = []
+ for token in tok.get_remaining():
+ server = tok.as_name(token, origin, relativize, relativize_to)
+ servers.append(server)
+ return cls(rdclass, rdtype, hit, algorithm, key, servers)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ lh = len(self.hit)
+ lk = len(self.key)
+ file.write(struct.pack("!BBH", lh, self.algorithm, lk))
+ file.write(self.hit)
+ file.write(self.key)
+ for server in self.servers:
+ server.to_wire(file, None, origin, False)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (lh, algorithm, lk) = parser.get_struct("!BBH")
+ hit = parser.get_bytes(lh)
+ key = parser.get_bytes(lk)
+ servers = []
+ while parser.remaining() > 0:
+ server = parser.get_name(origin)
+ servers.append(server)
+ return cls(rdclass, rdtype, hit, algorithm, key, servers)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ISDN.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ISDN.py
new file mode 100644
index 00000000..6428a0a8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ISDN.py
@@ -0,0 +1,78 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class ISDN(dns.rdata.Rdata):
+ """ISDN record"""
+
+ # see: RFC 1183
+
+ __slots__ = ["address", "subaddress"]
+
+ def __init__(self, rdclass, rdtype, address, subaddress):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_bytes(address, True, 255)
+ self.subaddress = self._as_bytes(subaddress, True, 255)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ if self.subaddress:
+ return (
+ f'"{dns.rdata._escapify(self.address)}" '
+ f'"{dns.rdata._escapify(self.subaddress)}"'
+ )
+ else:
+ return f'"{dns.rdata._escapify(self.address)}"'
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_string()
+ tokens = tok.get_remaining(max_tokens=1)
+ if len(tokens) >= 1:
+ subaddress = tokens[0].unescape().value
+ else:
+ subaddress = ""
+ return cls(rdclass, rdtype, address, subaddress)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.address)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.address)
+ l = len(self.subaddress)
+ if l > 0:
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.subaddress)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_counted_bytes()
+ if parser.remaining() > 0:
+ subaddress = parser.get_counted_bytes()
+ else:
+ subaddress = b""
+ return cls(rdclass, rdtype, address, subaddress)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L32.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L32.py
new file mode 100644
index 00000000..09804c2d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L32.py
@@ -0,0 +1,41 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import struct
+
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class L32(dns.rdata.Rdata):
+ """L32 record"""
+
+ # see: rfc6742.txt
+
+ __slots__ = ["preference", "locator32"]
+
+ def __init__(self, rdclass, rdtype, preference, locator32):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ self.locator32 = self._as_ipv4_address(locator32)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f"{self.preference} {self.locator32}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ nodeid = tok.get_identifier()
+ return cls(rdclass, rdtype, preference, nodeid)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!H", self.preference))
+ file.write(dns.ipv4.inet_aton(self.locator32))
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ locator32 = parser.get_remaining()
+ return cls(rdclass, rdtype, preference, locator32)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L64.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L64.py
new file mode 100644
index 00000000..fb76808e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/L64.py
@@ -0,0 +1,47 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import struct
+
+import dns.immutable
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class L64(dns.rdata.Rdata):
+ """L64 record"""
+
+ # see: rfc6742.txt
+
+ __slots__ = ["preference", "locator64"]
+
+ def __init__(self, rdclass, rdtype, preference, locator64):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ if isinstance(locator64, bytes):
+ if len(locator64) != 8:
+ raise ValueError("invalid locator64")
+ self.locator64 = dns.rdata._hexify(locator64, 4, b":")
+ else:
+ dns.rdtypes.util.parse_formatted_hex(locator64, 4, 4, ":")
+ self.locator64 = locator64
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f"{self.preference} {self.locator64}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ locator64 = tok.get_identifier()
+ return cls(rdclass, rdtype, preference, locator64)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!H", self.preference))
+ file.write(dns.rdtypes.util.parse_formatted_hex(self.locator64, 4, 4, ":"))
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ locator64 = parser.get_remaining()
+ return cls(rdclass, rdtype, preference, locator64)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LOC.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LOC.py
new file mode 100644
index 00000000..1153cf03
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LOC.py
@@ -0,0 +1,353 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+_pows = tuple(10**i for i in range(0, 11))
+
+# default values are in centimeters
+_default_size = 100.0
+_default_hprec = 1000000.0
+_default_vprec = 1000.0
+
+# for use by from_wire()
+_MAX_LATITUDE = 0x80000000 + 90 * 3600000
+_MIN_LATITUDE = 0x80000000 - 90 * 3600000
+_MAX_LONGITUDE = 0x80000000 + 180 * 3600000
+_MIN_LONGITUDE = 0x80000000 - 180 * 3600000
+
+
+def _exponent_of(what, desc):
+ if what == 0:
+ return 0
+ exp = None
+ for i, pow in enumerate(_pows):
+ if what < pow:
+ exp = i - 1
+ break
+ if exp is None or exp < 0:
+ raise dns.exception.SyntaxError(f"{desc} value out of bounds")
+ return exp
+
+
+def _float_to_tuple(what):
+ if what < 0:
+ sign = -1
+ what *= -1
+ else:
+ sign = 1
+ what = round(what * 3600000)
+ degrees = int(what // 3600000)
+ what -= degrees * 3600000
+ minutes = int(what // 60000)
+ what -= minutes * 60000
+ seconds = int(what // 1000)
+ what -= int(seconds * 1000)
+ what = int(what)
+ return (degrees, minutes, seconds, what, sign)
+
+
+def _tuple_to_float(what):
+ value = float(what[0])
+ value += float(what[1]) / 60.0
+ value += float(what[2]) / 3600.0
+ value += float(what[3]) / 3600000.0
+ return float(what[4]) * value
+
+
+def _encode_size(what, desc):
+ what = int(what)
+ exponent = _exponent_of(what, desc) & 0xF
+ base = what // pow(10, exponent) & 0xF
+ return base * 16 + exponent
+
+
+def _decode_size(what, desc):
+ exponent = what & 0x0F
+ if exponent > 9:
+ raise dns.exception.FormError(f"bad {desc} exponent")
+ base = (what & 0xF0) >> 4
+ if base > 9:
+ raise dns.exception.FormError(f"bad {desc} base")
+ return base * pow(10, exponent)
+
+
+def _check_coordinate_list(value, low, high):
+ if value[0] < low or value[0] > high:
+ raise ValueError(f"not in range [{low}, {high}]")
+ if value[1] < 0 or value[1] > 59:
+ raise ValueError("bad minutes value")
+ if value[2] < 0 or value[2] > 59:
+ raise ValueError("bad seconds value")
+ if value[3] < 0 or value[3] > 999:
+ raise ValueError("bad milliseconds value")
+ if value[4] != 1 and value[4] != -1:
+ raise ValueError("bad hemisphere value")
+
+
+@dns.immutable.immutable
+class LOC(dns.rdata.Rdata):
+ """LOC record"""
+
+ # see: RFC 1876
+
+ __slots__ = [
+ "latitude",
+ "longitude",
+ "altitude",
+ "size",
+ "horizontal_precision",
+ "vertical_precision",
+ ]
+
+ def __init__(
+ self,
+ rdclass,
+ rdtype,
+ latitude,
+ longitude,
+ altitude,
+ size=_default_size,
+ hprec=_default_hprec,
+ vprec=_default_vprec,
+ ):
+ """Initialize a LOC record instance.
+
+ The parameters I{latitude} and I{longitude} may be either a 4-tuple
+ of integers specifying (degrees, minutes, seconds, milliseconds),
+ or they may be floating point values specifying the number of
+ degrees. The other parameters are floats. Size, horizontal precision,
+ and vertical precision are specified in centimeters."""
+
+ super().__init__(rdclass, rdtype)
+ if isinstance(latitude, int):
+ latitude = float(latitude)
+ if isinstance(latitude, float):
+ latitude = _float_to_tuple(latitude)
+ _check_coordinate_list(latitude, -90, 90)
+ self.latitude = tuple(latitude)
+ if isinstance(longitude, int):
+ longitude = float(longitude)
+ if isinstance(longitude, float):
+ longitude = _float_to_tuple(longitude)
+ _check_coordinate_list(longitude, -180, 180)
+ self.longitude = tuple(longitude)
+ self.altitude = float(altitude)
+ self.size = float(size)
+ self.horizontal_precision = float(hprec)
+ self.vertical_precision = float(vprec)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ if self.latitude[4] > 0:
+ lat_hemisphere = "N"
+ else:
+ lat_hemisphere = "S"
+ if self.longitude[4] > 0:
+ long_hemisphere = "E"
+ else:
+ long_hemisphere = "W"
+ text = "%d %d %d.%03d %s %d %d %d.%03d %s %0.2fm" % (
+ self.latitude[0],
+ self.latitude[1],
+ self.latitude[2],
+ self.latitude[3],
+ lat_hemisphere,
+ self.longitude[0],
+ self.longitude[1],
+ self.longitude[2],
+ self.longitude[3],
+ long_hemisphere,
+ self.altitude / 100.0,
+ )
+
+ # do not print default values
+ if (
+ self.size != _default_size
+ or self.horizontal_precision != _default_hprec
+ or self.vertical_precision != _default_vprec
+ ):
+ text += (
+ f" {self.size / 100.0:0.2f}m {self.horizontal_precision / 100.0:0.2f}m"
+ f" {self.vertical_precision / 100.0:0.2f}m"
+ )
+ return text
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ latitude = [0, 0, 0, 0, 1]
+ longitude = [0, 0, 0, 0, 1]
+ size = _default_size
+ hprec = _default_hprec
+ vprec = _default_vprec
+
+ latitude[0] = tok.get_int()
+ t = tok.get_string()
+ if t.isdigit():
+ latitude[1] = int(t)
+ t = tok.get_string()
+ if "." in t:
+ (seconds, milliseconds) = t.split(".")
+ if not seconds.isdigit():
+ raise dns.exception.SyntaxError("bad latitude seconds value")
+ latitude[2] = int(seconds)
+ l = len(milliseconds)
+ if l == 0 or l > 3 or not milliseconds.isdigit():
+ raise dns.exception.SyntaxError("bad latitude milliseconds value")
+ if l == 1:
+ m = 100
+ elif l == 2:
+ m = 10
+ else:
+ m = 1
+ latitude[3] = m * int(milliseconds)
+ t = tok.get_string()
+ elif t.isdigit():
+ latitude[2] = int(t)
+ t = tok.get_string()
+ if t == "S":
+ latitude[4] = -1
+ elif t != "N":
+ raise dns.exception.SyntaxError("bad latitude hemisphere value")
+
+ longitude[0] = tok.get_int()
+ t = tok.get_string()
+ if t.isdigit():
+ longitude[1] = int(t)
+ t = tok.get_string()
+ if "." in t:
+ (seconds, milliseconds) = t.split(".")
+ if not seconds.isdigit():
+ raise dns.exception.SyntaxError("bad longitude seconds value")
+ longitude[2] = int(seconds)
+ l = len(milliseconds)
+ if l == 0 or l > 3 or not milliseconds.isdigit():
+ raise dns.exception.SyntaxError("bad longitude milliseconds value")
+ if l == 1:
+ m = 100
+ elif l == 2:
+ m = 10
+ else:
+ m = 1
+ longitude[3] = m * int(milliseconds)
+ t = tok.get_string()
+ elif t.isdigit():
+ longitude[2] = int(t)
+ t = tok.get_string()
+ if t == "W":
+ longitude[4] = -1
+ elif t != "E":
+ raise dns.exception.SyntaxError("bad longitude hemisphere value")
+
+ t = tok.get_string()
+ if t[-1] == "m":
+ t = t[0:-1]
+ altitude = float(t) * 100.0 # m -> cm
+
+ tokens = tok.get_remaining(max_tokens=3)
+ if len(tokens) >= 1:
+ value = tokens[0].unescape().value
+ if value[-1] == "m":
+ value = value[0:-1]
+ size = float(value) * 100.0 # m -> cm
+ if len(tokens) >= 2:
+ value = tokens[1].unescape().value
+ if value[-1] == "m":
+ value = value[0:-1]
+ hprec = float(value) * 100.0 # m -> cm
+ if len(tokens) >= 3:
+ value = tokens[2].unescape().value
+ if value[-1] == "m":
+ value = value[0:-1]
+ vprec = float(value) * 100.0 # m -> cm
+
+ # Try encoding these now so we raise if they are bad
+ _encode_size(size, "size")
+ _encode_size(hprec, "horizontal precision")
+ _encode_size(vprec, "vertical precision")
+
+ return cls(rdclass, rdtype, latitude, longitude, altitude, size, hprec, vprec)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ milliseconds = (
+ self.latitude[0] * 3600000
+ + self.latitude[1] * 60000
+ + self.latitude[2] * 1000
+ + self.latitude[3]
+ ) * self.latitude[4]
+ latitude = 0x80000000 + milliseconds
+ milliseconds = (
+ self.longitude[0] * 3600000
+ + self.longitude[1] * 60000
+ + self.longitude[2] * 1000
+ + self.longitude[3]
+ ) * self.longitude[4]
+ longitude = 0x80000000 + milliseconds
+ altitude = int(self.altitude) + 10000000
+ size = _encode_size(self.size, "size")
+ hprec = _encode_size(self.horizontal_precision, "horizontal precision")
+ vprec = _encode_size(self.vertical_precision, "vertical precision")
+ wire = struct.pack(
+ "!BBBBIII", 0, size, hprec, vprec, latitude, longitude, altitude
+ )
+ file.write(wire)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (
+ version,
+ size,
+ hprec,
+ vprec,
+ latitude,
+ longitude,
+ altitude,
+ ) = parser.get_struct("!BBBBIII")
+ if version != 0:
+ raise dns.exception.FormError("LOC version not zero")
+ if latitude < _MIN_LATITUDE or latitude > _MAX_LATITUDE:
+ raise dns.exception.FormError("bad latitude")
+ if latitude > 0x80000000:
+ latitude = (latitude - 0x80000000) / 3600000
+ else:
+ latitude = -1 * (0x80000000 - latitude) / 3600000
+ if longitude < _MIN_LONGITUDE or longitude > _MAX_LONGITUDE:
+ raise dns.exception.FormError("bad longitude")
+ if longitude > 0x80000000:
+ longitude = (longitude - 0x80000000) / 3600000
+ else:
+ longitude = -1 * (0x80000000 - longitude) / 3600000
+ altitude = float(altitude) - 10000000.0
+ size = _decode_size(size, "size")
+ hprec = _decode_size(hprec, "horizontal precision")
+ vprec = _decode_size(vprec, "vertical precision")
+ return cls(rdclass, rdtype, latitude, longitude, altitude, size, hprec, vprec)
+
+ @property
+ def float_latitude(self):
+ "latitude as a floating point value"
+ return _tuple_to_float(self.latitude)
+
+ @property
+ def float_longitude(self):
+ "longitude as a floating point value"
+ return _tuple_to_float(self.longitude)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LP.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LP.py
new file mode 100644
index 00000000..312663f1
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/LP.py
@@ -0,0 +1,42 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import struct
+
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class LP(dns.rdata.Rdata):
+ """LP record"""
+
+ # see: rfc6742.txt
+
+ __slots__ = ["preference", "fqdn"]
+
+ def __init__(self, rdclass, rdtype, preference, fqdn):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ self.fqdn = self._as_name(fqdn)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ fqdn = self.fqdn.choose_relativity(origin, relativize)
+ return "%d %s" % (self.preference, fqdn)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ fqdn = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, preference, fqdn)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!H", self.preference))
+ self.fqdn.to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ fqdn = parser.get_name(origin)
+ return cls(rdclass, rdtype, preference, fqdn)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/MX.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/MX.py
new file mode 100644
index 00000000..0c300c5a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/MX.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.mxbase
+
+
+@dns.immutable.immutable
+class MX(dns.rdtypes.mxbase.MXBase):
+ """MX record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NID.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NID.py
new file mode 100644
index 00000000..2f649178
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NID.py
@@ -0,0 +1,47 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import struct
+
+import dns.immutable
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class NID(dns.rdata.Rdata):
+ """NID record"""
+
+ # see: rfc6742.txt
+
+ __slots__ = ["preference", "nodeid"]
+
+ def __init__(self, rdclass, rdtype, preference, nodeid):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ if isinstance(nodeid, bytes):
+ if len(nodeid) != 8:
+ raise ValueError("invalid nodeid")
+ self.nodeid = dns.rdata._hexify(nodeid, 4, b":")
+ else:
+ dns.rdtypes.util.parse_formatted_hex(nodeid, 4, 4, ":")
+ self.nodeid = nodeid
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f"{self.preference} {self.nodeid}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ nodeid = tok.get_identifier()
+ return cls(rdclass, rdtype, preference, nodeid)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!H", self.preference))
+ file.write(dns.rdtypes.util.parse_formatted_hex(self.nodeid, 4, 4, ":"))
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ nodeid = parser.get_remaining()
+ return cls(rdclass, rdtype, preference, nodeid)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NINFO.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NINFO.py
new file mode 100644
index 00000000..b177bddb
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NINFO.py
@@ -0,0 +1,26 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class NINFO(dns.rdtypes.txtbase.TXTBase):
+ """NINFO record"""
+
+ # see: draft-reid-dnsext-zs-01
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NS.py
new file mode 100644
index 00000000..c3f34ce9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NS.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.nsbase
+
+
+@dns.immutable.immutable
+class NS(dns.rdtypes.nsbase.NSBase):
+ """NS record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC.py
new file mode 100644
index 00000000..3c78b722
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC.py
@@ -0,0 +1,67 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdatatype
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class Bitmap(dns.rdtypes.util.Bitmap):
+ type_name = "NSEC"
+
+
+@dns.immutable.immutable
+class NSEC(dns.rdata.Rdata):
+ """NSEC record"""
+
+ __slots__ = ["next", "windows"]
+
+ def __init__(self, rdclass, rdtype, next, windows):
+ super().__init__(rdclass, rdtype)
+ self.next = self._as_name(next)
+ if not isinstance(windows, Bitmap):
+ windows = Bitmap(windows)
+ self.windows = tuple(windows.windows)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ next = self.next.choose_relativity(origin, relativize)
+ text = Bitmap(self.windows).to_text()
+ return f"{next}{text}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ next = tok.get_name(origin, relativize, relativize_to)
+ windows = Bitmap.from_text(tok)
+ return cls(rdclass, rdtype, next, windows)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ # Note that NSEC downcasing, originally mandated by RFC 4034
+ # section 6.2 was removed by RFC 6840 section 5.1.
+ self.next.to_wire(file, None, origin, False)
+ Bitmap(self.windows).to_wire(file)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ next = parser.get_name(origin)
+ bitmap = Bitmap.from_wire_parser(parser)
+ return cls(rdclass, rdtype, next, bitmap)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3.py
new file mode 100644
index 00000000..d71302b7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3.py
@@ -0,0 +1,126 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import binascii
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+import dns.rdtypes.util
+
+b32_hex_to_normal = bytes.maketrans(
+ b"0123456789ABCDEFGHIJKLMNOPQRSTUV", b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
+)
+b32_normal_to_hex = bytes.maketrans(
+ b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", b"0123456789ABCDEFGHIJKLMNOPQRSTUV"
+)
+
+# hash algorithm constants
+SHA1 = 1
+
+# flag constants
+OPTOUT = 1
+
+
+@dns.immutable.immutable
+class Bitmap(dns.rdtypes.util.Bitmap):
+ type_name = "NSEC3"
+
+
+@dns.immutable.immutable
+class NSEC3(dns.rdata.Rdata):
+ """NSEC3 record"""
+
+ __slots__ = ["algorithm", "flags", "iterations", "salt", "next", "windows"]
+
+ def __init__(
+ self, rdclass, rdtype, algorithm, flags, iterations, salt, next, windows
+ ):
+ super().__init__(rdclass, rdtype)
+ self.algorithm = self._as_uint8(algorithm)
+ self.flags = self._as_uint8(flags)
+ self.iterations = self._as_uint16(iterations)
+ self.salt = self._as_bytes(salt, True, 255)
+ self.next = self._as_bytes(next, True, 255)
+ if not isinstance(windows, Bitmap):
+ windows = Bitmap(windows)
+ self.windows = tuple(windows.windows)
+
+ def _next_text(self):
+ next = base64.b32encode(self.next).translate(b32_normal_to_hex).lower().decode()
+ next = next.rstrip("=")
+ return next
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ next = self._next_text()
+ if self.salt == b"":
+ salt = "-"
+ else:
+ salt = binascii.hexlify(self.salt).decode()
+ text = Bitmap(self.windows).to_text()
+ return "%u %u %u %s %s%s" % (
+ self.algorithm,
+ self.flags,
+ self.iterations,
+ salt,
+ next,
+ text,
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_uint8()
+ flags = tok.get_uint8()
+ iterations = tok.get_uint16()
+ salt = tok.get_string()
+ if salt == "-":
+ salt = b""
+ else:
+ salt = binascii.unhexlify(salt.encode("ascii"))
+ next = tok.get_string().encode("ascii").upper().translate(b32_hex_to_normal)
+ if next.endswith(b"="):
+ raise binascii.Error("Incorrect padding")
+ if len(next) % 8 != 0:
+ next += b"=" * (8 - len(next) % 8)
+ next = base64.b32decode(next)
+ bitmap = Bitmap.from_text(tok)
+ return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, bitmap)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.salt)
+ file.write(struct.pack("!BBHB", self.algorithm, self.flags, self.iterations, l))
+ file.write(self.salt)
+ l = len(self.next)
+ file.write(struct.pack("!B", l))
+ file.write(self.next)
+ Bitmap(self.windows).to_wire(file)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (algorithm, flags, iterations) = parser.get_struct("!BBH")
+ salt = parser.get_counted_bytes()
+ next = parser.get_counted_bytes()
+ bitmap = Bitmap.from_wire_parser(parser)
+ return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, bitmap)
+
+ def next_name(self, origin=None):
+ return dns.name.from_text(self._next_text(), origin)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py
new file mode 100644
index 00000000..d1e62ebc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py
@@ -0,0 +1,69 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class NSEC3PARAM(dns.rdata.Rdata):
+ """NSEC3PARAM record"""
+
+ __slots__ = ["algorithm", "flags", "iterations", "salt"]
+
+ def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt):
+ super().__init__(rdclass, rdtype)
+ self.algorithm = self._as_uint8(algorithm)
+ self.flags = self._as_uint8(flags)
+ self.iterations = self._as_uint16(iterations)
+ self.salt = self._as_bytes(salt, True, 255)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ if self.salt == b"":
+ salt = "-"
+ else:
+ salt = binascii.hexlify(self.salt).decode()
+ return "%u %u %u %s" % (self.algorithm, self.flags, self.iterations, salt)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_uint8()
+ flags = tok.get_uint8()
+ iterations = tok.get_uint16()
+ salt = tok.get_string()
+ if salt == "-":
+ salt = ""
+ else:
+ salt = binascii.unhexlify(salt.encode())
+ return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.salt)
+ file.write(struct.pack("!BBHB", self.algorithm, self.flags, self.iterations, l))
+ file.write(self.salt)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (algorithm, flags, iterations) = parser.get_struct("!BBH")
+ salt = parser.get_counted_bytes()
+ return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py
new file mode 100644
index 00000000..4d7a4b6c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py
@@ -0,0 +1,53 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2016 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class OPENPGPKEY(dns.rdata.Rdata):
+ """OPENPGPKEY record"""
+
+ # see: RFC 7929
+
+ def __init__(self, rdclass, rdtype, key):
+ super().__init__(rdclass, rdtype)
+ self.key = self._as_bytes(key)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return dns.rdata._base64ify(self.key, chunksize=None, **kw)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ key = base64.b64decode(b64)
+ return cls(rdclass, rdtype, key)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(self.key)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ key = parser.get_remaining()
+ return cls(rdclass, rdtype, key)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPT.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPT.py
new file mode 100644
index 00000000..d343dfa5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/OPT.py
@@ -0,0 +1,77 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2001-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.edns
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+# We don't implement from_text, and that's ok.
+# pylint: disable=abstract-method
+
+
+@dns.immutable.immutable
+class OPT(dns.rdata.Rdata):
+ """OPT record"""
+
+ __slots__ = ["options"]
+
+ def __init__(self, rdclass, rdtype, options):
+ """Initialize an OPT rdata.
+
+ *rdclass*, an ``int`` is the rdataclass of the Rdata,
+ which is also the payload size.
+
+ *rdtype*, an ``int`` is the rdatatype of the Rdata.
+
+ *options*, a tuple of ``bytes``
+ """
+
+ super().__init__(rdclass, rdtype)
+
+ def as_option(option):
+ if not isinstance(option, dns.edns.Option):
+ raise ValueError("option is not a dns.edns.option")
+ return option
+
+ self.options = self._as_tuple(options, as_option)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ for opt in self.options:
+ owire = opt.to_wire()
+ file.write(struct.pack("!HH", opt.otype, len(owire)))
+ file.write(owire)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return " ".join(opt.to_text() for opt in self.options)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ options = []
+ while parser.remaining() > 0:
+ (otype, olen) = parser.get_struct("!HH")
+ with parser.restrict_to(olen):
+ opt = dns.edns.option_from_wire_parser(otype, parser)
+ options.append(opt)
+ return cls(rdclass, rdtype, options)
+
+ @property
+ def payload(self):
+ "payload size"
+ return self.rdclass
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/PTR.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/PTR.py
new file mode 100644
index 00000000..98c36167
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/PTR.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.nsbase
+
+
+@dns.immutable.immutable
+class PTR(dns.rdtypes.nsbase.NSBase):
+ """PTR record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RESINFO.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RESINFO.py
new file mode 100644
index 00000000..76c8ea2a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RESINFO.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class RESINFO(dns.rdtypes.txtbase.TXTBase):
+ """RESINFO record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RP.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RP.py
new file mode 100644
index 00000000..a66cfc50
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RP.py
@@ -0,0 +1,58 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+
+
+@dns.immutable.immutable
+class RP(dns.rdata.Rdata):
+ """RP record"""
+
+ # see: RFC 1183
+
+ __slots__ = ["mbox", "txt"]
+
+ def __init__(self, rdclass, rdtype, mbox, txt):
+ super().__init__(rdclass, rdtype)
+ self.mbox = self._as_name(mbox)
+ self.txt = self._as_name(txt)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ mbox = self.mbox.choose_relativity(origin, relativize)
+ txt = self.txt.choose_relativity(origin, relativize)
+ return f"{str(mbox)} {str(txt)}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ mbox = tok.get_name(origin, relativize, relativize_to)
+ txt = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, mbox, txt)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.mbox.to_wire(file, None, origin, canonicalize)
+ self.txt.to_wire(file, None, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ mbox = parser.get_name(origin)
+ txt = parser.get_name(origin)
+ return cls(rdclass, rdtype, mbox, txt)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RRSIG.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RRSIG.py
new file mode 100644
index 00000000..8beb4237
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RRSIG.py
@@ -0,0 +1,157 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import calendar
+import struct
+import time
+
+import dns.dnssectypes
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+
+
+class BadSigTime(dns.exception.DNSException):
+ """Time in DNS SIG or RRSIG resource record cannot be parsed."""
+
+
+def sigtime_to_posixtime(what):
+ if len(what) <= 10 and what.isdigit():
+ return int(what)
+ if len(what) != 14:
+ raise BadSigTime
+ year = int(what[0:4])
+ month = int(what[4:6])
+ day = int(what[6:8])
+ hour = int(what[8:10])
+ minute = int(what[10:12])
+ second = int(what[12:14])
+ return calendar.timegm((year, month, day, hour, minute, second, 0, 0, 0))
+
+
+def posixtime_to_sigtime(what):
+ return time.strftime("%Y%m%d%H%M%S", time.gmtime(what))
+
+
+@dns.immutable.immutable
+class RRSIG(dns.rdata.Rdata):
+ """RRSIG record"""
+
+ __slots__ = [
+ "type_covered",
+ "algorithm",
+ "labels",
+ "original_ttl",
+ "expiration",
+ "inception",
+ "key_tag",
+ "signer",
+ "signature",
+ ]
+
+ def __init__(
+ self,
+ rdclass,
+ rdtype,
+ type_covered,
+ algorithm,
+ labels,
+ original_ttl,
+ expiration,
+ inception,
+ key_tag,
+ signer,
+ signature,
+ ):
+ super().__init__(rdclass, rdtype)
+ self.type_covered = self._as_rdatatype(type_covered)
+ self.algorithm = dns.dnssectypes.Algorithm.make(algorithm)
+ self.labels = self._as_uint8(labels)
+ self.original_ttl = self._as_ttl(original_ttl)
+ self.expiration = self._as_uint32(expiration)
+ self.inception = self._as_uint32(inception)
+ self.key_tag = self._as_uint16(key_tag)
+ self.signer = self._as_name(signer)
+ self.signature = self._as_bytes(signature)
+
+ def covers(self):
+ return self.type_covered
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return "%s %d %d %d %s %s %d %s %s" % (
+ dns.rdatatype.to_text(self.type_covered),
+ self.algorithm,
+ self.labels,
+ self.original_ttl,
+ posixtime_to_sigtime(self.expiration),
+ posixtime_to_sigtime(self.inception),
+ self.key_tag,
+ self.signer.choose_relativity(origin, relativize),
+ dns.rdata._base64ify(self.signature, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ type_covered = dns.rdatatype.from_text(tok.get_string())
+ algorithm = dns.dnssectypes.Algorithm.from_text(tok.get_string())
+ labels = tok.get_int()
+ original_ttl = tok.get_ttl()
+ expiration = sigtime_to_posixtime(tok.get_string())
+ inception = sigtime_to_posixtime(tok.get_string())
+ key_tag = tok.get_int()
+ signer = tok.get_name(origin, relativize, relativize_to)
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ signature = base64.b64decode(b64)
+ return cls(
+ rdclass,
+ rdtype,
+ type_covered,
+ algorithm,
+ labels,
+ original_ttl,
+ expiration,
+ inception,
+ key_tag,
+ signer,
+ signature,
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack(
+ "!HBBIIIH",
+ self.type_covered,
+ self.algorithm,
+ self.labels,
+ self.original_ttl,
+ self.expiration,
+ self.inception,
+ self.key_tag,
+ )
+ file.write(header)
+ self.signer.to_wire(file, None, origin, canonicalize)
+ file.write(self.signature)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("!HBBIIIH")
+ signer = parser.get_name(origin)
+ signature = parser.get_remaining()
+ return cls(rdclass, rdtype, *header, signer, signature)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RT.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RT.py
new file mode 100644
index 00000000..5a4d45cf
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/RT.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.mxbase
+
+
+@dns.immutable.immutable
+class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX):
+ """RT record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SMIMEA.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SMIMEA.py
new file mode 100644
index 00000000..55d87bf8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SMIMEA.py
@@ -0,0 +1,9 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import dns.immutable
+import dns.rdtypes.tlsabase
+
+
+@dns.immutable.immutable
+class SMIMEA(dns.rdtypes.tlsabase.TLSABase):
+ """SMIMEA record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SOA.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SOA.py
new file mode 100644
index 00000000..09aa8321
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SOA.py
@@ -0,0 +1,86 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+
+
+@dns.immutable.immutable
+class SOA(dns.rdata.Rdata):
+ """SOA record"""
+
+ # see: RFC 1035
+
+ __slots__ = ["mname", "rname", "serial", "refresh", "retry", "expire", "minimum"]
+
+ def __init__(
+ self, rdclass, rdtype, mname, rname, serial, refresh, retry, expire, minimum
+ ):
+ super().__init__(rdclass, rdtype)
+ self.mname = self._as_name(mname)
+ self.rname = self._as_name(rname)
+ self.serial = self._as_uint32(serial)
+ self.refresh = self._as_ttl(refresh)
+ self.retry = self._as_ttl(retry)
+ self.expire = self._as_ttl(expire)
+ self.minimum = self._as_ttl(minimum)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ mname = self.mname.choose_relativity(origin, relativize)
+ rname = self.rname.choose_relativity(origin, relativize)
+ return "%s %s %d %d %d %d %d" % (
+ mname,
+ rname,
+ self.serial,
+ self.refresh,
+ self.retry,
+ self.expire,
+ self.minimum,
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ mname = tok.get_name(origin, relativize, relativize_to)
+ rname = tok.get_name(origin, relativize, relativize_to)
+ serial = tok.get_uint32()
+ refresh = tok.get_ttl()
+ retry = tok.get_ttl()
+ expire = tok.get_ttl()
+ minimum = tok.get_ttl()
+ return cls(
+ rdclass, rdtype, mname, rname, serial, refresh, retry, expire, minimum
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.mname.to_wire(file, compress, origin, canonicalize)
+ self.rname.to_wire(file, compress, origin, canonicalize)
+ five_ints = struct.pack(
+ "!IIIII", self.serial, self.refresh, self.retry, self.expire, self.minimum
+ )
+ file.write(five_ints)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ mname = parser.get_name(origin)
+ rname = parser.get_name(origin)
+ return cls(rdclass, rdtype, mname, rname, *parser.get_struct("!IIIII"))
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SPF.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SPF.py
new file mode 100644
index 00000000..1df3b705
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SPF.py
@@ -0,0 +1,26 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class SPF(dns.rdtypes.txtbase.TXTBase):
+ """SPF record"""
+
+ # see: RFC 4408
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SSHFP.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SSHFP.py
new file mode 100644
index 00000000..d2c4b073
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/SSHFP.py
@@ -0,0 +1,68 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+import struct
+
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+
+
+@dns.immutable.immutable
+class SSHFP(dns.rdata.Rdata):
+ """SSHFP record"""
+
+ # See RFC 4255
+
+ __slots__ = ["algorithm", "fp_type", "fingerprint"]
+
+ def __init__(self, rdclass, rdtype, algorithm, fp_type, fingerprint):
+ super().__init__(rdclass, rdtype)
+ self.algorithm = self._as_uint8(algorithm)
+ self.fp_type = self._as_uint8(fp_type)
+ self.fingerprint = self._as_bytes(fingerprint, True)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop("chunksize", 128)
+ return "%d %d %s" % (
+ self.algorithm,
+ self.fp_type,
+ dns.rdata._hexify(self.fingerprint, chunksize=chunksize, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_uint8()
+ fp_type = tok.get_uint8()
+ fingerprint = tok.concatenate_remaining_identifiers().encode()
+ fingerprint = binascii.unhexlify(fingerprint)
+ return cls(rdclass, rdtype, algorithm, fp_type, fingerprint)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!BB", self.algorithm, self.fp_type)
+ file.write(header)
+ file.write(self.fingerprint)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("BB")
+ fingerprint = parser.get_remaining()
+ return cls(rdclass, rdtype, header[0], header[1], fingerprint)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TKEY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TKEY.py
new file mode 100644
index 00000000..75f62249
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TKEY.py
@@ -0,0 +1,142 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class TKEY(dns.rdata.Rdata):
+ """TKEY Record"""
+
+ __slots__ = [
+ "algorithm",
+ "inception",
+ "expiration",
+ "mode",
+ "error",
+ "key",
+ "other",
+ ]
+
+ def __init__(
+ self,
+ rdclass,
+ rdtype,
+ algorithm,
+ inception,
+ expiration,
+ mode,
+ error,
+ key,
+ other=b"",
+ ):
+ super().__init__(rdclass, rdtype)
+ self.algorithm = self._as_name(algorithm)
+ self.inception = self._as_uint32(inception)
+ self.expiration = self._as_uint32(expiration)
+ self.mode = self._as_uint16(mode)
+ self.error = self._as_uint16(error)
+ self.key = self._as_bytes(key)
+ self.other = self._as_bytes(other)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ _algorithm = self.algorithm.choose_relativity(origin, relativize)
+ text = "%s %u %u %u %u %s" % (
+ str(_algorithm),
+ self.inception,
+ self.expiration,
+ self.mode,
+ self.error,
+ dns.rdata._base64ify(self.key, 0),
+ )
+ if len(self.other) > 0:
+ text += f" {dns.rdata._base64ify(self.other, 0)}"
+
+ return text
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_name(relativize=False)
+ inception = tok.get_uint32()
+ expiration = tok.get_uint32()
+ mode = tok.get_uint16()
+ error = tok.get_uint16()
+ key_b64 = tok.get_string().encode()
+ key = base64.b64decode(key_b64)
+ other_b64 = tok.concatenate_remaining_identifiers(True).encode()
+ other = base64.b64decode(other_b64)
+
+ return cls(
+ rdclass, rdtype, algorithm, inception, expiration, mode, error, key, other
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.algorithm.to_wire(file, compress, origin)
+ file.write(
+ struct.pack("!IIHH", self.inception, self.expiration, self.mode, self.error)
+ )
+ file.write(struct.pack("!H", len(self.key)))
+ file.write(self.key)
+ file.write(struct.pack("!H", len(self.other)))
+ if len(self.other) > 0:
+ file.write(self.other)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ algorithm = parser.get_name(origin)
+ inception, expiration, mode, error = parser.get_struct("!IIHH")
+ key = parser.get_counted_bytes(2)
+ other = parser.get_counted_bytes(2)
+
+ return cls(
+ rdclass, rdtype, algorithm, inception, expiration, mode, error, key, other
+ )
+
+ # Constants for the mode field - from RFC 2930:
+ # 2.5 The Mode Field
+ #
+ # The mode field specifies the general scheme for key agreement or
+ # the purpose of the TKEY DNS message. Servers and resolvers
+ # supporting this specification MUST implement the Diffie-Hellman key
+ # agreement mode and the key deletion mode for queries. All other
+ # modes are OPTIONAL. A server supporting TKEY that receives a TKEY
+ # request with a mode it does not support returns the BADMODE error.
+ # The following values of the Mode octet are defined, available, or
+ # reserved:
+ #
+ # Value Description
+ # ----- -----------
+ # 0 - reserved, see section 7
+ # 1 server assignment
+ # 2 Diffie-Hellman exchange
+ # 3 GSS-API negotiation
+ # 4 resolver assignment
+ # 5 key deletion
+ # 6-65534 - available, see section 7
+ # 65535 - reserved, see section 7
+ SERVER_ASSIGNMENT = 1
+ DIFFIE_HELLMAN_EXCHANGE = 2
+ GSSAPI_NEGOTIATION = 3
+ RESOLVER_ASSIGNMENT = 4
+ KEY_DELETION = 5
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TLSA.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TLSA.py
new file mode 100644
index 00000000..4dffc553
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TLSA.py
@@ -0,0 +1,9 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import dns.immutable
+import dns.rdtypes.tlsabase
+
+
+@dns.immutable.immutable
+class TLSA(dns.rdtypes.tlsabase.TLSABase):
+ """TLSA record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TSIG.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TSIG.py
new file mode 100644
index 00000000..79423826
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TSIG.py
@@ -0,0 +1,160 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2001-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rcode
+import dns.rdata
+
+
+@dns.immutable.immutable
+class TSIG(dns.rdata.Rdata):
+ """TSIG record"""
+
+ __slots__ = [
+ "algorithm",
+ "time_signed",
+ "fudge",
+ "mac",
+ "original_id",
+ "error",
+ "other",
+ ]
+
+ def __init__(
+ self,
+ rdclass,
+ rdtype,
+ algorithm,
+ time_signed,
+ fudge,
+ mac,
+ original_id,
+ error,
+ other,
+ ):
+ """Initialize a TSIG rdata.
+
+ *rdclass*, an ``int`` is the rdataclass of the Rdata.
+
+ *rdtype*, an ``int`` is the rdatatype of the Rdata.
+
+ *algorithm*, a ``dns.name.Name``.
+
+ *time_signed*, an ``int``.
+
+ *fudge*, an ``int`.
+
+ *mac*, a ``bytes``
+
+ *original_id*, an ``int``
+
+ *error*, an ``int``
+
+ *other*, a ``bytes``
+ """
+
+ super().__init__(rdclass, rdtype)
+ self.algorithm = self._as_name(algorithm)
+ self.time_signed = self._as_uint48(time_signed)
+ self.fudge = self._as_uint16(fudge)
+ self.mac = self._as_bytes(mac)
+ self.original_id = self._as_uint16(original_id)
+ self.error = dns.rcode.Rcode.make(error)
+ self.other = self._as_bytes(other)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ algorithm = self.algorithm.choose_relativity(origin, relativize)
+ error = dns.rcode.to_text(self.error, True)
+ text = (
+ f"{algorithm} {self.time_signed} {self.fudge} "
+ + f"{len(self.mac)} {dns.rdata._base64ify(self.mac, 0)} "
+ + f"{self.original_id} {error} {len(self.other)}"
+ )
+ if self.other:
+ text += f" {dns.rdata._base64ify(self.other, 0)}"
+ return text
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ algorithm = tok.get_name(relativize=False)
+ time_signed = tok.get_uint48()
+ fudge = tok.get_uint16()
+ mac_len = tok.get_uint16()
+ mac = base64.b64decode(tok.get_string())
+ if len(mac) != mac_len:
+ raise SyntaxError("invalid MAC")
+ original_id = tok.get_uint16()
+ error = dns.rcode.from_text(tok.get_string())
+ other_len = tok.get_uint16()
+ if other_len > 0:
+ other = base64.b64decode(tok.get_string())
+ if len(other) != other_len:
+ raise SyntaxError("invalid other data")
+ else:
+ other = b""
+ return cls(
+ rdclass,
+ rdtype,
+ algorithm,
+ time_signed,
+ fudge,
+ mac,
+ original_id,
+ error,
+ other,
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.algorithm.to_wire(file, None, origin, False)
+ file.write(
+ struct.pack(
+ "!HIHH",
+ (self.time_signed >> 32) & 0xFFFF,
+ self.time_signed & 0xFFFFFFFF,
+ self.fudge,
+ len(self.mac),
+ )
+ )
+ file.write(self.mac)
+ file.write(struct.pack("!HHH", self.original_id, self.error, len(self.other)))
+ file.write(self.other)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ algorithm = parser.get_name()
+ time_signed = parser.get_uint48()
+ fudge = parser.get_uint16()
+ mac = parser.get_counted_bytes(2)
+ (original_id, error) = parser.get_struct("!HH")
+ other = parser.get_counted_bytes(2)
+ return cls(
+ rdclass,
+ rdtype,
+ algorithm,
+ time_signed,
+ fudge,
+ mac,
+ original_id,
+ error,
+ other,
+ )
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TXT.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TXT.py
new file mode 100644
index 00000000..6d4dae27
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/TXT.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class TXT(dns.rdtypes.txtbase.TXTBase):
+ """TXT record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/URI.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/URI.py
new file mode 100644
index 00000000..2efbb305
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/URI.py
@@ -0,0 +1,79 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class URI(dns.rdata.Rdata):
+ """URI record"""
+
+ # see RFC 7553
+
+ __slots__ = ["priority", "weight", "target"]
+
+ def __init__(self, rdclass, rdtype, priority, weight, target):
+ super().__init__(rdclass, rdtype)
+ self.priority = self._as_uint16(priority)
+ self.weight = self._as_uint16(weight)
+ self.target = self._as_bytes(target, True)
+ if len(self.target) == 0:
+ raise dns.exception.SyntaxError("URI target cannot be empty")
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return '%d %d "%s"' % (self.priority, self.weight, self.target.decode())
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ priority = tok.get_uint16()
+ weight = tok.get_uint16()
+ target = tok.get().unescape()
+ if not (target.is_quoted_string() or target.is_identifier()):
+ raise dns.exception.SyntaxError("URI target must be a string")
+ return cls(rdclass, rdtype, priority, weight, target.value)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ two_ints = struct.pack("!HH", self.priority, self.weight)
+ file.write(two_ints)
+ file.write(self.target)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (priority, weight) = parser.get_struct("!HH")
+ target = parser.get_remaining()
+ if len(target) == 0:
+ raise dns.exception.FormError("URI target may not be empty")
+ return cls(rdclass, rdtype, priority, weight, target)
+
+ def _processing_priority(self):
+ return self.priority
+
+ def _processing_weight(self):
+ return self.weight
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.weighted_processing_order(iterable)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/WALLET.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/WALLET.py
new file mode 100644
index 00000000..ff464763
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/WALLET.py
@@ -0,0 +1,9 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import dns.immutable
+import dns.rdtypes.txtbase
+
+
+@dns.immutable.immutable
+class WALLET(dns.rdtypes.txtbase.TXTBase):
+ """WALLET record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/X25.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/X25.py
new file mode 100644
index 00000000..2436ddb6
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/X25.py
@@ -0,0 +1,57 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class X25(dns.rdata.Rdata):
+ """X25 record"""
+
+ # see RFC 1183
+
+ __slots__ = ["address"]
+
+ def __init__(self, rdclass, rdtype, address):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_bytes(address, True, 255)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f'"{dns.rdata._escapify(self.address)}"'
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_string()
+ return cls(rdclass, rdtype, address)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ l = len(self.address)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(self.address)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_counted_bytes()
+ return cls(rdclass, rdtype, address)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ZONEMD.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ZONEMD.py
new file mode 100644
index 00000000..c90e3ee1
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/ZONEMD.py
@@ -0,0 +1,66 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import binascii
+import struct
+
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+import dns.zonetypes
+
+
+@dns.immutable.immutable
+class ZONEMD(dns.rdata.Rdata):
+ """ZONEMD record"""
+
+ # See RFC 8976
+
+ __slots__ = ["serial", "scheme", "hash_algorithm", "digest"]
+
+ def __init__(self, rdclass, rdtype, serial, scheme, hash_algorithm, digest):
+ super().__init__(rdclass, rdtype)
+ self.serial = self._as_uint32(serial)
+ self.scheme = dns.zonetypes.DigestScheme.make(scheme)
+ self.hash_algorithm = dns.zonetypes.DigestHashAlgorithm.make(hash_algorithm)
+ self.digest = self._as_bytes(digest)
+
+ if self.scheme == 0: # reserved, RFC 8976 Sec. 5.2
+ raise ValueError("scheme 0 is reserved")
+ if self.hash_algorithm == 0: # reserved, RFC 8976 Sec. 5.3
+ raise ValueError("hash_algorithm 0 is reserved")
+
+ hasher = dns.zonetypes._digest_hashers.get(self.hash_algorithm)
+ if hasher and hasher().digest_size != len(self.digest):
+ raise ValueError("digest length inconsistent with hash algorithm")
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop("chunksize", 128)
+ return "%d %d %d %s" % (
+ self.serial,
+ self.scheme,
+ self.hash_algorithm,
+ dns.rdata._hexify(self.digest, chunksize=chunksize, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ serial = tok.get_uint32()
+ scheme = tok.get_uint8()
+ hash_algorithm = tok.get_uint8()
+ digest = tok.concatenate_remaining_identifiers().encode()
+ digest = binascii.unhexlify(digest)
+ return cls(rdclass, rdtype, serial, scheme, hash_algorithm, digest)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!IBB", self.serial, self.scheme, self.hash_algorithm)
+ file.write(header)
+ file.write(self.digest)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("!IBB")
+ digest = parser.get_remaining()
+ return cls(rdclass, rdtype, header[0], header[1], header[2], digest)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/__init__.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/__init__.py
new file mode 100644
index 00000000..647b215b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/ANY/__init__.py
@@ -0,0 +1,70 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Class ANY (generic) rdata type classes."""
+
+__all__ = [
+ "AFSDB",
+ "AMTRELAY",
+ "AVC",
+ "CAA",
+ "CDNSKEY",
+ "CDS",
+ "CERT",
+ "CNAME",
+ "CSYNC",
+ "DLV",
+ "DNAME",
+ "DNSKEY",
+ "DS",
+ "EUI48",
+ "EUI64",
+ "GPOS",
+ "HINFO",
+ "HIP",
+ "ISDN",
+ "L32",
+ "L64",
+ "LOC",
+ "LP",
+ "MX",
+ "NID",
+ "NINFO",
+ "NS",
+ "NSEC",
+ "NSEC3",
+ "NSEC3PARAM",
+ "OPENPGPKEY",
+ "OPT",
+ "PTR",
+ "RESINFO",
+ "RP",
+ "RRSIG",
+ "RT",
+ "SMIMEA",
+ "SOA",
+ "SPF",
+ "SSHFP",
+ "TKEY",
+ "TLSA",
+ "TSIG",
+ "TXT",
+ "URI",
+ "WALLET",
+ "X25",
+ "ZONEMD",
+]
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/A.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/A.py
new file mode 100644
index 00000000..832e8d3a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/A.py
@@ -0,0 +1,59 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.immutable
+import dns.rdtypes.mxbase
+
+
+@dns.immutable.immutable
+class A(dns.rdata.Rdata):
+ """A record for Chaosnet"""
+
+ # domain: the domain of the address
+ # address: the 16-bit address
+
+ __slots__ = ["domain", "address"]
+
+ def __init__(self, rdclass, rdtype, domain, address):
+ super().__init__(rdclass, rdtype)
+ self.domain = self._as_name(domain)
+ self.address = self._as_uint16(address)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ domain = self.domain.choose_relativity(origin, relativize)
+ return f"{domain} {self.address:o}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ domain = tok.get_name(origin, relativize, relativize_to)
+ address = tok.get_uint16(base=8)
+ return cls(rdclass, rdtype, domain, address)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.domain.to_wire(file, compress, origin, canonicalize)
+ pref = struct.pack("!H", self.address)
+ file.write(pref)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ domain = parser.get_name(origin)
+ address = parser.get_uint16()
+ return cls(rdclass, rdtype, domain, address)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/__init__.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/__init__.py
new file mode 100644
index 00000000..0760c26c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/CH/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Class CH rdata type classes."""
+
+__all__ = [
+ "A",
+]
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/A.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/A.py
new file mode 100644
index 00000000..e09d6110
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/A.py
@@ -0,0 +1,51 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.exception
+import dns.immutable
+import dns.ipv4
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class A(dns.rdata.Rdata):
+ """A record."""
+
+ __slots__ = ["address"]
+
+ def __init__(self, rdclass, rdtype, address):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_ipv4_address(address)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return self.address
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_identifier()
+ return cls(rdclass, rdtype, address)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(dns.ipv4.inet_aton(self.address))
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_remaining()
+ return cls(rdclass, rdtype, address)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/AAAA.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/AAAA.py
new file mode 100644
index 00000000..0cd139e7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/AAAA.py
@@ -0,0 +1,51 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.exception
+import dns.immutable
+import dns.ipv6
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class AAAA(dns.rdata.Rdata):
+ """AAAA record."""
+
+ __slots__ = ["address"]
+
+ def __init__(self, rdclass, rdtype, address):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_ipv6_address(address)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return self.address
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_identifier()
+ return cls(rdclass, rdtype, address)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(dns.ipv6.inet_aton(self.address))
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_remaining()
+ return cls(rdclass, rdtype, address)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/APL.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/APL.py
new file mode 100644
index 00000000..44cb3fef
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/APL.py
@@ -0,0 +1,150 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+import codecs
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.ipv4
+import dns.ipv6
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class APLItem:
+ """An APL list item."""
+
+ __slots__ = ["family", "negation", "address", "prefix"]
+
+ def __init__(self, family, negation, address, prefix):
+ self.family = dns.rdata.Rdata._as_uint16(family)
+ self.negation = dns.rdata.Rdata._as_bool(negation)
+ if self.family == 1:
+ self.address = dns.rdata.Rdata._as_ipv4_address(address)
+ self.prefix = dns.rdata.Rdata._as_int(prefix, 0, 32)
+ elif self.family == 2:
+ self.address = dns.rdata.Rdata._as_ipv6_address(address)
+ self.prefix = dns.rdata.Rdata._as_int(prefix, 0, 128)
+ else:
+ self.address = dns.rdata.Rdata._as_bytes(address, max_length=127)
+ self.prefix = dns.rdata.Rdata._as_uint8(prefix)
+
+ def __str__(self):
+ if self.negation:
+ return "!%d:%s/%s" % (self.family, self.address, self.prefix)
+ else:
+ return "%d:%s/%s" % (self.family, self.address, self.prefix)
+
+ def to_wire(self, file):
+ if self.family == 1:
+ address = dns.ipv4.inet_aton(self.address)
+ elif self.family == 2:
+ address = dns.ipv6.inet_aton(self.address)
+ else:
+ address = binascii.unhexlify(self.address)
+ #
+ # Truncate least significant zero bytes.
+ #
+ last = 0
+ for i in range(len(address) - 1, -1, -1):
+ if address[i] != 0:
+ last = i + 1
+ break
+ address = address[0:last]
+ l = len(address)
+ assert l < 128
+ if self.negation:
+ l |= 0x80
+ header = struct.pack("!HBB", self.family, self.prefix, l)
+ file.write(header)
+ file.write(address)
+
+
+@dns.immutable.immutable
+class APL(dns.rdata.Rdata):
+ """APL record."""
+
+ # see: RFC 3123
+
+ __slots__ = ["items"]
+
+ def __init__(self, rdclass, rdtype, items):
+ super().__init__(rdclass, rdtype)
+ for item in items:
+ if not isinstance(item, APLItem):
+ raise ValueError("item not an APLItem")
+ self.items = tuple(items)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return " ".join(map(str, self.items))
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ items = []
+ for token in tok.get_remaining():
+ item = token.unescape().value
+ if item[0] == "!":
+ negation = True
+ item = item[1:]
+ else:
+ negation = False
+ (family, rest) = item.split(":", 1)
+ family = int(family)
+ (address, prefix) = rest.split("/", 1)
+ prefix = int(prefix)
+ item = APLItem(family, negation, address, prefix)
+ items.append(item)
+
+ return cls(rdclass, rdtype, items)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ for item in self.items:
+ item.to_wire(file)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ items = []
+ while parser.remaining() > 0:
+ header = parser.get_struct("!HBB")
+ afdlen = header[2]
+ if afdlen > 127:
+ negation = True
+ afdlen -= 128
+ else:
+ negation = False
+ address = parser.get_bytes(afdlen)
+ l = len(address)
+ if header[0] == 1:
+ if l < 4:
+ address += b"\x00" * (4 - l)
+ elif header[0] == 2:
+ if l < 16:
+ address += b"\x00" * (16 - l)
+ else:
+ #
+ # This isn't really right according to the RFC, but it
+ # seems better than throwing an exception
+ #
+ address = codecs.encode(address, "hex_codec")
+ item = APLItem(header[0], negation, address, header[1])
+ items.append(item)
+ return cls(rdclass, rdtype, items)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/DHCID.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/DHCID.py
new file mode 100644
index 00000000..723492fa
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/DHCID.py
@@ -0,0 +1,54 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class DHCID(dns.rdata.Rdata):
+ """DHCID record"""
+
+ # see: RFC 4701
+
+ __slots__ = ["data"]
+
+ def __init__(self, rdclass, rdtype, data):
+ super().__init__(rdclass, rdtype)
+ self.data = self._as_bytes(data)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return dns.rdata._base64ify(self.data, **kw)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ data = base64.b64decode(b64)
+ return cls(rdclass, rdtype, data)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(self.data)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ data = parser.get_remaining()
+ return cls(rdclass, rdtype, data)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/HTTPS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/HTTPS.py
new file mode 100644
index 00000000..15464cbd
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/HTTPS.py
@@ -0,0 +1,9 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import dns.immutable
+import dns.rdtypes.svcbbase
+
+
+@dns.immutable.immutable
+class HTTPS(dns.rdtypes.svcbbase.SVCBBase):
+ """HTTPS record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/IPSECKEY.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/IPSECKEY.py
new file mode 100644
index 00000000..e3a66157
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/IPSECKEY.py
@@ -0,0 +1,91 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.rdtypes.util
+
+
+class Gateway(dns.rdtypes.util.Gateway):
+ name = "IPSECKEY gateway"
+
+
+@dns.immutable.immutable
+class IPSECKEY(dns.rdata.Rdata):
+ """IPSECKEY record"""
+
+ # see: RFC 4025
+
+ __slots__ = ["precedence", "gateway_type", "algorithm", "gateway", "key"]
+
+ def __init__(
+ self, rdclass, rdtype, precedence, gateway_type, algorithm, gateway, key
+ ):
+ super().__init__(rdclass, rdtype)
+ gateway = Gateway(gateway_type, gateway)
+ self.precedence = self._as_uint8(precedence)
+ self.gateway_type = gateway.type
+ self.algorithm = self._as_uint8(algorithm)
+ self.gateway = gateway.gateway
+ self.key = self._as_bytes(key)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ gateway = Gateway(self.gateway_type, self.gateway).to_text(origin, relativize)
+ return "%d %d %d %s %s" % (
+ self.precedence,
+ self.gateway_type,
+ self.algorithm,
+ gateway,
+ dns.rdata._base64ify(self.key, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ precedence = tok.get_uint8()
+ gateway_type = tok.get_uint8()
+ algorithm = tok.get_uint8()
+ gateway = Gateway.from_text(
+ gateway_type, tok, origin, relativize, relativize_to
+ )
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ key = base64.b64decode(b64)
+ return cls(
+ rdclass, rdtype, precedence, gateway_type, algorithm, gateway.gateway, key
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!BBB", self.precedence, self.gateway_type, self.algorithm)
+ file.write(header)
+ Gateway(self.gateway_type, self.gateway).to_wire(
+ file, compress, origin, canonicalize
+ )
+ file.write(self.key)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("!BBB")
+ gateway_type = header[1]
+ gateway = Gateway.from_wire_parser(gateway_type, parser, origin)
+ key = parser.get_remaining()
+ return cls(
+ rdclass, rdtype, header[0], gateway_type, header[2], gateway.gateway, key
+ )
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/KX.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/KX.py
new file mode 100644
index 00000000..6073df47
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/KX.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.mxbase
+
+
+@dns.immutable.immutable
+class KX(dns.rdtypes.mxbase.UncompressedDowncasingMX):
+ """KX record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NAPTR.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NAPTR.py
new file mode 100644
index 00000000..195d1cba
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NAPTR.py
@@ -0,0 +1,110 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+
+
+def _write_string(file, s):
+ l = len(s)
+ assert l < 256
+ file.write(struct.pack("!B", l))
+ file.write(s)
+
+
+@dns.immutable.immutable
+class NAPTR(dns.rdata.Rdata):
+ """NAPTR record"""
+
+ # see: RFC 3403
+
+ __slots__ = ["order", "preference", "flags", "service", "regexp", "replacement"]
+
+ def __init__(
+ self, rdclass, rdtype, order, preference, flags, service, regexp, replacement
+ ):
+ super().__init__(rdclass, rdtype)
+ self.flags = self._as_bytes(flags, True, 255)
+ self.service = self._as_bytes(service, True, 255)
+ self.regexp = self._as_bytes(regexp, True, 255)
+ self.order = self._as_uint16(order)
+ self.preference = self._as_uint16(preference)
+ self.replacement = self._as_name(replacement)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ replacement = self.replacement.choose_relativity(origin, relativize)
+ return '%d %d "%s" "%s" "%s" %s' % (
+ self.order,
+ self.preference,
+ dns.rdata._escapify(self.flags),
+ dns.rdata._escapify(self.service),
+ dns.rdata._escapify(self.regexp),
+ replacement,
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ order = tok.get_uint16()
+ preference = tok.get_uint16()
+ flags = tok.get_string()
+ service = tok.get_string()
+ regexp = tok.get_string()
+ replacement = tok.get_name(origin, relativize, relativize_to)
+ return cls(
+ rdclass, rdtype, order, preference, flags, service, regexp, replacement
+ )
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ two_ints = struct.pack("!HH", self.order, self.preference)
+ file.write(two_ints)
+ _write_string(file, self.flags)
+ _write_string(file, self.service)
+ _write_string(file, self.regexp)
+ self.replacement.to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (order, preference) = parser.get_struct("!HH")
+ strings = []
+ for _ in range(3):
+ s = parser.get_counted_bytes()
+ strings.append(s)
+ replacement = parser.get_name(origin)
+ return cls(
+ rdclass,
+ rdtype,
+ order,
+ preference,
+ strings[0],
+ strings[1],
+ strings[2],
+ replacement,
+ )
+
+ def _processing_priority(self):
+ return (self.order, self.preference)
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.priority_processing_order(iterable)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP.py
new file mode 100644
index 00000000..d55edb73
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP.py
@@ -0,0 +1,60 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class NSAP(dns.rdata.Rdata):
+ """NSAP record."""
+
+ # see: RFC 1706
+
+ __slots__ = ["address"]
+
+ def __init__(self, rdclass, rdtype, address):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_bytes(address)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return f"0x{binascii.hexlify(self.address).decode()}"
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_string()
+ if address[0:2] != "0x":
+ raise dns.exception.SyntaxError("string does not start with 0x")
+ address = address[2:].replace(".", "")
+ if len(address) % 2 != 0:
+ raise dns.exception.SyntaxError("hexstring has odd length")
+ address = binascii.unhexlify(address.encode())
+ return cls(rdclass, rdtype, address)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(self.address)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_remaining()
+ return cls(rdclass, rdtype, address)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP_PTR.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP_PTR.py
new file mode 100644
index 00000000..ce1c6632
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/NSAP_PTR.py
@@ -0,0 +1,24 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import dns.immutable
+import dns.rdtypes.nsbase
+
+
+@dns.immutable.immutable
+class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS):
+ """NSAP-PTR record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/PX.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/PX.py
new file mode 100644
index 00000000..cdca1532
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/PX.py
@@ -0,0 +1,73 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class PX(dns.rdata.Rdata):
+ """PX record."""
+
+ # see: RFC 2163
+
+ __slots__ = ["preference", "map822", "mapx400"]
+
+ def __init__(self, rdclass, rdtype, preference, map822, mapx400):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ self.map822 = self._as_name(map822)
+ self.mapx400 = self._as_name(mapx400)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ map822 = self.map822.choose_relativity(origin, relativize)
+ mapx400 = self.mapx400.choose_relativity(origin, relativize)
+ return "%d %s %s" % (self.preference, map822, mapx400)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ map822 = tok.get_name(origin, relativize, relativize_to)
+ mapx400 = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, preference, map822, mapx400)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ pref = struct.pack("!H", self.preference)
+ file.write(pref)
+ self.map822.to_wire(file, None, origin, canonicalize)
+ self.mapx400.to_wire(file, None, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ map822 = parser.get_name(origin)
+ mapx400 = parser.get_name(origin)
+ return cls(rdclass, rdtype, preference, map822, mapx400)
+
+ def _processing_priority(self):
+ return self.preference
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.priority_processing_order(iterable)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SRV.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SRV.py
new file mode 100644
index 00000000..5adef98f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SRV.py
@@ -0,0 +1,75 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class SRV(dns.rdata.Rdata):
+ """SRV record"""
+
+ # see: RFC 2782
+
+ __slots__ = ["priority", "weight", "port", "target"]
+
+ def __init__(self, rdclass, rdtype, priority, weight, port, target):
+ super().__init__(rdclass, rdtype)
+ self.priority = self._as_uint16(priority)
+ self.weight = self._as_uint16(weight)
+ self.port = self._as_uint16(port)
+ self.target = self._as_name(target)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ target = self.target.choose_relativity(origin, relativize)
+ return "%d %d %d %s" % (self.priority, self.weight, self.port, target)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ priority = tok.get_uint16()
+ weight = tok.get_uint16()
+ port = tok.get_uint16()
+ target = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, priority, weight, port, target)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ three_ints = struct.pack("!HHH", self.priority, self.weight, self.port)
+ file.write(three_ints)
+ self.target.to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ (priority, weight, port) = parser.get_struct("!HHH")
+ target = parser.get_name(origin)
+ return cls(rdclass, rdtype, priority, weight, port, target)
+
+ def _processing_priority(self):
+ return self.priority
+
+ def _processing_weight(self):
+ return self.weight
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.weighted_processing_order(iterable)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SVCB.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SVCB.py
new file mode 100644
index 00000000..ff3e9327
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/SVCB.py
@@ -0,0 +1,9 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import dns.immutable
+import dns.rdtypes.svcbbase
+
+
+@dns.immutable.immutable
+class SVCB(dns.rdtypes.svcbbase.SVCBBase):
+ """SVCB record"""
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/WKS.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/WKS.py
new file mode 100644
index 00000000..881a7849
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/WKS.py
@@ -0,0 +1,100 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import socket
+import struct
+
+import dns.immutable
+import dns.ipv4
+import dns.rdata
+
+try:
+ _proto_tcp = socket.getprotobyname("tcp")
+ _proto_udp = socket.getprotobyname("udp")
+except OSError:
+ # Fall back to defaults in case /etc/protocols is unavailable.
+ _proto_tcp = 6
+ _proto_udp = 17
+
+
+@dns.immutable.immutable
+class WKS(dns.rdata.Rdata):
+ """WKS record"""
+
+ # see: RFC 1035
+
+ __slots__ = ["address", "protocol", "bitmap"]
+
+ def __init__(self, rdclass, rdtype, address, protocol, bitmap):
+ super().__init__(rdclass, rdtype)
+ self.address = self._as_ipv4_address(address)
+ self.protocol = self._as_uint8(protocol)
+ self.bitmap = self._as_bytes(bitmap)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ bits = []
+ for i, byte in enumerate(self.bitmap):
+ for j in range(0, 8):
+ if byte & (0x80 >> j):
+ bits.append(str(i * 8 + j))
+ text = " ".join(bits)
+ return "%s %d %s" % (self.address, self.protocol, text)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ address = tok.get_string()
+ protocol = tok.get_string()
+ if protocol.isdigit():
+ protocol = int(protocol)
+ else:
+ protocol = socket.getprotobyname(protocol)
+ bitmap = bytearray()
+ for token in tok.get_remaining():
+ value = token.unescape().value
+ if value.isdigit():
+ serv = int(value)
+ else:
+ if protocol != _proto_udp and protocol != _proto_tcp:
+ raise NotImplementedError("protocol must be TCP or UDP")
+ if protocol == _proto_udp:
+ protocol_text = "udp"
+ else:
+ protocol_text = "tcp"
+ serv = socket.getservbyname(value, protocol_text)
+ i = serv // 8
+ l = len(bitmap)
+ if l < i + 1:
+ for _ in range(l, i + 1):
+ bitmap.append(0)
+ bitmap[i] = bitmap[i] | (0x80 >> (serv % 8))
+ bitmap = dns.rdata._truncate_bitmap(bitmap)
+ return cls(rdclass, rdtype, address, protocol, bitmap)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(dns.ipv4.inet_aton(self.address))
+ protocol = struct.pack("!B", self.protocol)
+ file.write(protocol)
+ file.write(self.bitmap)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ address = parser.get_bytes(4)
+ protocol = parser.get_uint8()
+ bitmap = parser.get_remaining()
+ return cls(rdclass, rdtype, address, protocol, bitmap)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/__init__.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/__init__.py
new file mode 100644
index 00000000..dcec4dd2
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/IN/__init__.py
@@ -0,0 +1,35 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Class IN rdata type classes."""
+
+__all__ = [
+ "A",
+ "AAAA",
+ "APL",
+ "DHCID",
+ "HTTPS",
+ "IPSECKEY",
+ "KX",
+ "NAPTR",
+ "NSAP",
+ "NSAP_PTR",
+ "PX",
+ "SRV",
+ "SVCB",
+ "WKS",
+]
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/__init__.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/__init__.py
new file mode 100644
index 00000000..3997f84c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/__init__.py
@@ -0,0 +1,33 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""DNS rdata type classes"""
+
+__all__ = [
+ "ANY",
+ "IN",
+ "CH",
+ "dnskeybase",
+ "dsbase",
+ "euibase",
+ "mxbase",
+ "nsbase",
+ "svcbbase",
+ "tlsabase",
+ "txtbase",
+ "util",
+]
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/dnskeybase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/dnskeybase.py
new file mode 100644
index 00000000..db300f8b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/dnskeybase.py
@@ -0,0 +1,87 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import base64
+import enum
+import struct
+
+import dns.dnssectypes
+import dns.exception
+import dns.immutable
+import dns.rdata
+
+# wildcard import
+__all__ = ["SEP", "REVOKE", "ZONE"] # noqa: F822
+
+
+class Flag(enum.IntFlag):
+ SEP = 0x0001
+ REVOKE = 0x0080
+ ZONE = 0x0100
+
+
+@dns.immutable.immutable
+class DNSKEYBase(dns.rdata.Rdata):
+ """Base class for rdata that is like a DNSKEY record"""
+
+ __slots__ = ["flags", "protocol", "algorithm", "key"]
+
+ def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
+ super().__init__(rdclass, rdtype)
+ self.flags = Flag(self._as_uint16(flags))
+ self.protocol = self._as_uint8(protocol)
+ self.algorithm = dns.dnssectypes.Algorithm.make(algorithm)
+ self.key = self._as_bytes(key)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return "%d %d %d %s" % (
+ self.flags,
+ self.protocol,
+ self.algorithm,
+ dns.rdata._base64ify(self.key, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ flags = tok.get_uint16()
+ protocol = tok.get_uint8()
+ algorithm = tok.get_string()
+ b64 = tok.concatenate_remaining_identifiers().encode()
+ key = base64.b64decode(b64)
+ return cls(rdclass, rdtype, flags, protocol, algorithm, key)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm)
+ file.write(header)
+ file.write(self.key)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("!HBB")
+ key = parser.get_remaining()
+ return cls(rdclass, rdtype, header[0], header[1], header[2], key)
+
+
+### BEGIN generated Flag constants
+
+SEP = Flag.SEP
+REVOKE = Flag.REVOKE
+ZONE = Flag.ZONE
+
+### END generated Flag constants
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/dsbase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/dsbase.py
new file mode 100644
index 00000000..cd21f026
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/dsbase.py
@@ -0,0 +1,85 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2010, 2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+import struct
+
+import dns.dnssectypes
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+
+
+@dns.immutable.immutable
+class DSBase(dns.rdata.Rdata):
+ """Base class for rdata that is like a DS record"""
+
+ __slots__ = ["key_tag", "algorithm", "digest_type", "digest"]
+
+ # Digest types registry:
+ # https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml
+ _digest_length_by_type = {
+ 1: 20, # SHA-1, RFC 3658 Sec. 2.4
+ 2: 32, # SHA-256, RFC 4509 Sec. 2.2
+ 3: 32, # GOST R 34.11-94, RFC 5933 Sec. 4 in conjunction with RFC 4490 Sec. 2.1
+ 4: 48, # SHA-384, RFC 6605 Sec. 2
+ }
+
+ def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type, digest):
+ super().__init__(rdclass, rdtype)
+ self.key_tag = self._as_uint16(key_tag)
+ self.algorithm = dns.dnssectypes.Algorithm.make(algorithm)
+ self.digest_type = dns.dnssectypes.DSDigest.make(self._as_uint8(digest_type))
+ self.digest = self._as_bytes(digest)
+ try:
+ if len(self.digest) != self._digest_length_by_type[self.digest_type]:
+ raise ValueError("digest length inconsistent with digest type")
+ except KeyError:
+ if self.digest_type == 0: # reserved, RFC 3658 Sec. 2.4
+ raise ValueError("digest type 0 is reserved")
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop("chunksize", 128)
+ return "%d %d %d %s" % (
+ self.key_tag,
+ self.algorithm,
+ self.digest_type,
+ dns.rdata._hexify(self.digest, chunksize=chunksize, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ key_tag = tok.get_uint16()
+ algorithm = tok.get_string()
+ digest_type = tok.get_uint8()
+ digest = tok.concatenate_remaining_identifiers().encode()
+ digest = binascii.unhexlify(digest)
+ return cls(rdclass, rdtype, key_tag, algorithm, digest_type, digest)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!HBB", self.key_tag, self.algorithm, self.digest_type)
+ file.write(header)
+ file.write(self.digest)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("!HBB")
+ digest = parser.get_remaining()
+ return cls(rdclass, rdtype, header[0], header[1], header[2], digest)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/euibase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/euibase.py
new file mode 100644
index 00000000..a39c166b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/euibase.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2015 Red Hat, Inc.
+# Author: Petr Spacek <pspacek@redhat.com>
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+
+import dns.immutable
+import dns.rdata
+
+
+@dns.immutable.immutable
+class EUIBase(dns.rdata.Rdata):
+ """EUIxx record"""
+
+ # see: rfc7043.txt
+
+ __slots__ = ["eui"]
+ # define these in subclasses
+ # byte_len = 6 # 0123456789ab (in hex)
+ # text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab
+
+ def __init__(self, rdclass, rdtype, eui):
+ super().__init__(rdclass, rdtype)
+ self.eui = self._as_bytes(eui)
+ if len(self.eui) != self.byte_len:
+ raise dns.exception.FormError(
+ f"EUI{self.byte_len * 8} rdata has to have {self.byte_len} bytes"
+ )
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ return dns.rdata._hexify(self.eui, chunksize=2, separator=b"-", **kw)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ text = tok.get_string()
+ if len(text) != cls.text_len:
+ raise dns.exception.SyntaxError(
+ f"Input text must have {cls.text_len} characters"
+ )
+ for i in range(2, cls.byte_len * 3 - 1, 3):
+ if text[i] != "-":
+ raise dns.exception.SyntaxError(f"Dash expected at position {i}")
+ text = text.replace("-", "")
+ try:
+ data = binascii.unhexlify(text.encode())
+ except (ValueError, TypeError) as ex:
+ raise dns.exception.SyntaxError(f"Hex decoding error: {str(ex)}")
+ return cls(rdclass, rdtype, data)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(self.eui)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ eui = parser.get_bytes(cls.byte_len)
+ return cls(rdclass, rdtype, eui)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/mxbase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/mxbase.py
new file mode 100644
index 00000000..6d5e3d87
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/mxbase.py
@@ -0,0 +1,87 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""MX-like base classes."""
+
+import struct
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+
+
+@dns.immutable.immutable
+class MXBase(dns.rdata.Rdata):
+ """Base class for rdata that is like an MX record."""
+
+ __slots__ = ["preference", "exchange"]
+
+ def __init__(self, rdclass, rdtype, preference, exchange):
+ super().__init__(rdclass, rdtype)
+ self.preference = self._as_uint16(preference)
+ self.exchange = self._as_name(exchange)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ exchange = self.exchange.choose_relativity(origin, relativize)
+ return "%d %s" % (self.preference, exchange)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ preference = tok.get_uint16()
+ exchange = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, preference, exchange)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ pref = struct.pack("!H", self.preference)
+ file.write(pref)
+ self.exchange.to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ preference = parser.get_uint16()
+ exchange = parser.get_name(origin)
+ return cls(rdclass, rdtype, preference, exchange)
+
+ def _processing_priority(self):
+ return self.preference
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.priority_processing_order(iterable)
+
+
+@dns.immutable.immutable
+class UncompressedMX(MXBase):
+ """Base class for rdata that is like an MX record, but whose name
+ is not compressed when converted to DNS wire format, and whose
+ digestable form is not downcased."""
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ super()._to_wire(file, None, origin, False)
+
+
+@dns.immutable.immutable
+class UncompressedDowncasingMX(MXBase):
+ """Base class for rdata that is like an MX record, but whose name
+ is not compressed when convert to DNS wire format."""
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ super()._to_wire(file, None, origin, canonicalize)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/nsbase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/nsbase.py
new file mode 100644
index 00000000..904224f0
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/nsbase.py
@@ -0,0 +1,63 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""NS-like base classes."""
+
+import dns.exception
+import dns.immutable
+import dns.name
+import dns.rdata
+
+
+@dns.immutable.immutable
+class NSBase(dns.rdata.Rdata):
+ """Base class for rdata that is like an NS record."""
+
+ __slots__ = ["target"]
+
+ def __init__(self, rdclass, rdtype, target):
+ super().__init__(rdclass, rdtype)
+ self.target = self._as_name(target)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ target = self.target.choose_relativity(origin, relativize)
+ return str(target)
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ target = tok.get_name(origin, relativize, relativize_to)
+ return cls(rdclass, rdtype, target)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.target.to_wire(file, compress, origin, canonicalize)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ target = parser.get_name(origin)
+ return cls(rdclass, rdtype, target)
+
+
+@dns.immutable.immutable
+class UncompressedNS(NSBase):
+ """Base class for rdata that is like an NS record, but whose name
+ is not compressed when convert to DNS wire format, and whose
+ digestable form is not downcased."""
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ self.target.to_wire(file, None, origin, False)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/svcbbase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/svcbbase.py
new file mode 100644
index 00000000..a2b15b92
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/svcbbase.py
@@ -0,0 +1,585 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+import base64
+import enum
+import struct
+
+import dns.enum
+import dns.exception
+import dns.immutable
+import dns.ipv4
+import dns.ipv6
+import dns.name
+import dns.rdata
+import dns.rdtypes.util
+import dns.renderer
+import dns.tokenizer
+import dns.wire
+
+# Until there is an RFC, this module is experimental and may be changed in
+# incompatible ways.
+
+
+class UnknownParamKey(dns.exception.DNSException):
+ """Unknown SVCB ParamKey"""
+
+
+class ParamKey(dns.enum.IntEnum):
+ """SVCB ParamKey"""
+
+ MANDATORY = 0
+ ALPN = 1
+ NO_DEFAULT_ALPN = 2
+ PORT = 3
+ IPV4HINT = 4
+ ECH = 5
+ IPV6HINT = 6
+ DOHPATH = 7
+ OHTTP = 8
+
+ @classmethod
+ def _maximum(cls):
+ return 65535
+
+ @classmethod
+ def _short_name(cls):
+ return "SVCBParamKey"
+
+ @classmethod
+ def _prefix(cls):
+ return "KEY"
+
+ @classmethod
+ def _unknown_exception_class(cls):
+ return UnknownParamKey
+
+
+class Emptiness(enum.IntEnum):
+ NEVER = 0
+ ALWAYS = 1
+ ALLOWED = 2
+
+
+def _validate_key(key):
+ force_generic = False
+ if isinstance(key, bytes):
+ # We decode to latin-1 so we get 0-255 as valid and do NOT interpret
+ # UTF-8 sequences
+ key = key.decode("latin-1")
+ if isinstance(key, str):
+ if key.lower().startswith("key"):
+ force_generic = True
+ if key[3:].startswith("0") and len(key) != 4:
+ # key has leading zeros
+ raise ValueError("leading zeros in key")
+ key = key.replace("-", "_")
+ return (ParamKey.make(key), force_generic)
+
+
+def key_to_text(key):
+ return ParamKey.to_text(key).replace("_", "-").lower()
+
+
+# Like rdata escapify, but escapes ',' too.
+
+_escaped = b'",\\'
+
+
+def _escapify(qstring):
+ text = ""
+ for c in qstring:
+ if c in _escaped:
+ text += "\\" + chr(c)
+ elif c >= 0x20 and c < 0x7F:
+ text += chr(c)
+ else:
+ text += "\\%03d" % c
+ return text
+
+
+def _unescape(value):
+ if value == "":
+ return value
+ unescaped = b""
+ l = len(value)
+ i = 0
+ while i < l:
+ c = value[i]
+ i += 1
+ if c == "\\":
+ if i >= l: # pragma: no cover (can't happen via tokenizer get())
+ raise dns.exception.UnexpectedEnd
+ c = value[i]
+ i += 1
+ if c.isdigit():
+ if i >= l:
+ raise dns.exception.UnexpectedEnd
+ c2 = value[i]
+ i += 1
+ if i >= l:
+ raise dns.exception.UnexpectedEnd
+ c3 = value[i]
+ i += 1
+ if not (c2.isdigit() and c3.isdigit()):
+ raise dns.exception.SyntaxError
+ codepoint = int(c) * 100 + int(c2) * 10 + int(c3)
+ if codepoint > 255:
+ raise dns.exception.SyntaxError
+ unescaped += b"%c" % (codepoint)
+ continue
+ unescaped += c.encode()
+ return unescaped
+
+
+def _split(value):
+ l = len(value)
+ i = 0
+ items = []
+ unescaped = b""
+ while i < l:
+ c = value[i]
+ i += 1
+ if c == ord("\\"):
+ if i >= l: # pragma: no cover (can't happen via tokenizer get())
+ raise dns.exception.UnexpectedEnd
+ c = value[i]
+ i += 1
+ unescaped += b"%c" % (c)
+ elif c == ord(","):
+ items.append(unescaped)
+ unescaped = b""
+ else:
+ unescaped += b"%c" % (c)
+ items.append(unescaped)
+ return items
+
+
+@dns.immutable.immutable
+class Param:
+ """Abstract base class for SVCB parameters"""
+
+ @classmethod
+ def emptiness(cls):
+ return Emptiness.NEVER
+
+
+@dns.immutable.immutable
+class GenericParam(Param):
+ """Generic SVCB parameter"""
+
+ def __init__(self, value):
+ self.value = dns.rdata.Rdata._as_bytes(value, True)
+
+ @classmethod
+ def emptiness(cls):
+ return Emptiness.ALLOWED
+
+ @classmethod
+ def from_value(cls, value):
+ if value is None or len(value) == 0:
+ return None
+ else:
+ return cls(_unescape(value))
+
+ def to_text(self):
+ return '"' + dns.rdata._escapify(self.value) + '"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ value = parser.get_bytes(parser.remaining())
+ if len(value) == 0:
+ return None
+ else:
+ return cls(value)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ file.write(self.value)
+
+
+@dns.immutable.immutable
+class MandatoryParam(Param):
+ def __init__(self, keys):
+ # check for duplicates
+ keys = sorted([_validate_key(key)[0] for key in keys])
+ prior_k = None
+ for k in keys:
+ if k == prior_k:
+ raise ValueError(f"duplicate key {k:d}")
+ prior_k = k
+ if k == ParamKey.MANDATORY:
+ raise ValueError("listed the mandatory key as mandatory")
+ self.keys = tuple(keys)
+
+ @classmethod
+ def from_value(cls, value):
+ keys = [k.encode() for k in value.split(",")]
+ return cls(keys)
+
+ def to_text(self):
+ return '"' + ",".join([key_to_text(key) for key in self.keys]) + '"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ keys = []
+ last_key = -1
+ while parser.remaining() > 0:
+ key = parser.get_uint16()
+ if key < last_key:
+ raise dns.exception.FormError("manadatory keys not ascending")
+ last_key = key
+ keys.append(key)
+ return cls(keys)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ for key in self.keys:
+ file.write(struct.pack("!H", key))
+
+
+@dns.immutable.immutable
+class ALPNParam(Param):
+ def __init__(self, ids):
+ self.ids = dns.rdata.Rdata._as_tuple(
+ ids, lambda x: dns.rdata.Rdata._as_bytes(x, True, 255, False)
+ )
+
+ @classmethod
+ def from_value(cls, value):
+ return cls(_split(_unescape(value)))
+
+ def to_text(self):
+ value = ",".join([_escapify(id) for id in self.ids])
+ return '"' + dns.rdata._escapify(value.encode()) + '"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ ids = []
+ while parser.remaining() > 0:
+ id = parser.get_counted_bytes()
+ ids.append(id)
+ return cls(ids)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ for id in self.ids:
+ file.write(struct.pack("!B", len(id)))
+ file.write(id)
+
+
+@dns.immutable.immutable
+class NoDefaultALPNParam(Param):
+ # We don't ever expect to instantiate this class, but we need
+ # a from_value() and a from_wire_parser(), so we just return None
+ # from the class methods when things are OK.
+
+ @classmethod
+ def emptiness(cls):
+ return Emptiness.ALWAYS
+
+ @classmethod
+ def from_value(cls, value):
+ if value is None or value == "":
+ return None
+ else:
+ raise ValueError("no-default-alpn with non-empty value")
+
+ def to_text(self):
+ raise NotImplementedError # pragma: no cover
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ if parser.remaining() != 0:
+ raise dns.exception.FormError
+ return None
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ raise NotImplementedError # pragma: no cover
+
+
+@dns.immutable.immutable
+class PortParam(Param):
+ def __init__(self, port):
+ self.port = dns.rdata.Rdata._as_uint16(port)
+
+ @classmethod
+ def from_value(cls, value):
+ value = int(value)
+ return cls(value)
+
+ def to_text(self):
+ return f'"{self.port}"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ port = parser.get_uint16()
+ return cls(port)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ file.write(struct.pack("!H", self.port))
+
+
+@dns.immutable.immutable
+class IPv4HintParam(Param):
+ def __init__(self, addresses):
+ self.addresses = dns.rdata.Rdata._as_tuple(
+ addresses, dns.rdata.Rdata._as_ipv4_address
+ )
+
+ @classmethod
+ def from_value(cls, value):
+ addresses = value.split(",")
+ return cls(addresses)
+
+ def to_text(self):
+ return '"' + ",".join(self.addresses) + '"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ addresses = []
+ while parser.remaining() > 0:
+ ip = parser.get_bytes(4)
+ addresses.append(dns.ipv4.inet_ntoa(ip))
+ return cls(addresses)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ for address in self.addresses:
+ file.write(dns.ipv4.inet_aton(address))
+
+
+@dns.immutable.immutable
+class IPv6HintParam(Param):
+ def __init__(self, addresses):
+ self.addresses = dns.rdata.Rdata._as_tuple(
+ addresses, dns.rdata.Rdata._as_ipv6_address
+ )
+
+ @classmethod
+ def from_value(cls, value):
+ addresses = value.split(",")
+ return cls(addresses)
+
+ def to_text(self):
+ return '"' + ",".join(self.addresses) + '"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ addresses = []
+ while parser.remaining() > 0:
+ ip = parser.get_bytes(16)
+ addresses.append(dns.ipv6.inet_ntoa(ip))
+ return cls(addresses)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ for address in self.addresses:
+ file.write(dns.ipv6.inet_aton(address))
+
+
+@dns.immutable.immutable
+class ECHParam(Param):
+ def __init__(self, ech):
+ self.ech = dns.rdata.Rdata._as_bytes(ech, True)
+
+ @classmethod
+ def from_value(cls, value):
+ if "\\" in value:
+ raise ValueError("escape in ECH value")
+ value = base64.b64decode(value.encode())
+ return cls(value)
+
+ def to_text(self):
+ b64 = base64.b64encode(self.ech).decode("ascii")
+ return f'"{b64}"'
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ value = parser.get_bytes(parser.remaining())
+ return cls(value)
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ file.write(self.ech)
+
+
+@dns.immutable.immutable
+class OHTTPParam(Param):
+ # We don't ever expect to instantiate this class, but we need
+ # a from_value() and a from_wire_parser(), so we just return None
+ # from the class methods when things are OK.
+
+ @classmethod
+ def emptiness(cls):
+ return Emptiness.ALWAYS
+
+ @classmethod
+ def from_value(cls, value):
+ if value is None or value == "":
+ return None
+ else:
+ raise ValueError("ohttp with non-empty value")
+
+ def to_text(self):
+ raise NotImplementedError # pragma: no cover
+
+ @classmethod
+ def from_wire_parser(cls, parser, origin=None): # pylint: disable=W0613
+ if parser.remaining() != 0:
+ raise dns.exception.FormError
+ return None
+
+ def to_wire(self, file, origin=None): # pylint: disable=W0613
+ raise NotImplementedError # pragma: no cover
+
+
+_class_for_key = {
+ ParamKey.MANDATORY: MandatoryParam,
+ ParamKey.ALPN: ALPNParam,
+ ParamKey.NO_DEFAULT_ALPN: NoDefaultALPNParam,
+ ParamKey.PORT: PortParam,
+ ParamKey.IPV4HINT: IPv4HintParam,
+ ParamKey.ECH: ECHParam,
+ ParamKey.IPV6HINT: IPv6HintParam,
+ ParamKey.OHTTP: OHTTPParam,
+}
+
+
+def _validate_and_define(params, key, value):
+ (key, force_generic) = _validate_key(_unescape(key))
+ if key in params:
+ raise SyntaxError(f'duplicate key "{key:d}"')
+ cls = _class_for_key.get(key, GenericParam)
+ emptiness = cls.emptiness()
+ if value is None:
+ if emptiness == Emptiness.NEVER:
+ raise SyntaxError("value cannot be empty")
+ value = cls.from_value(value)
+ else:
+ if force_generic:
+ value = cls.from_wire_parser(dns.wire.Parser(_unescape(value)))
+ else:
+ value = cls.from_value(value)
+ params[key] = value
+
+
+@dns.immutable.immutable
+class SVCBBase(dns.rdata.Rdata):
+ """Base class for SVCB-like records"""
+
+ # see: draft-ietf-dnsop-svcb-https-11
+
+ __slots__ = ["priority", "target", "params"]
+
+ def __init__(self, rdclass, rdtype, priority, target, params):
+ super().__init__(rdclass, rdtype)
+ self.priority = self._as_uint16(priority)
+ self.target = self._as_name(target)
+ for k, v in params.items():
+ k = ParamKey.make(k)
+ if not isinstance(v, Param) and v is not None:
+ raise ValueError(f"{k:d} not a Param")
+ self.params = dns.immutable.Dict(params)
+ # Make sure any parameter listed as mandatory is present in the
+ # record.
+ mandatory = params.get(ParamKey.MANDATORY)
+ if mandatory:
+ for key in mandatory.keys:
+ # Note we have to say "not in" as we have None as a value
+ # so a get() and a not None test would be wrong.
+ if key not in params:
+ raise ValueError(f"key {key:d} declared mandatory but not present")
+ # The no-default-alpn parameter requires the alpn parameter.
+ if ParamKey.NO_DEFAULT_ALPN in params:
+ if ParamKey.ALPN not in params:
+ raise ValueError("no-default-alpn present, but alpn missing")
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ target = self.target.choose_relativity(origin, relativize)
+ params = []
+ for key in sorted(self.params.keys()):
+ value = self.params[key]
+ if value is None:
+ params.append(key_to_text(key))
+ else:
+ kv = key_to_text(key) + "=" + value.to_text()
+ params.append(kv)
+ if len(params) > 0:
+ space = " "
+ else:
+ space = ""
+ return "%d %s%s%s" % (self.priority, target, space, " ".join(params))
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ priority = tok.get_uint16()
+ target = tok.get_name(origin, relativize, relativize_to)
+ if priority == 0:
+ token = tok.get()
+ if not token.is_eol_or_eof():
+ raise SyntaxError("parameters in AliasMode")
+ tok.unget(token)
+ params = {}
+ while True:
+ token = tok.get()
+ if token.is_eol_or_eof():
+ tok.unget(token)
+ break
+ if token.ttype != dns.tokenizer.IDENTIFIER:
+ raise SyntaxError("parameter is not an identifier")
+ equals = token.value.find("=")
+ if equals == len(token.value) - 1:
+ # 'key=', so next token should be a quoted string without
+ # any intervening whitespace.
+ key = token.value[:-1]
+ token = tok.get(want_leading=True)
+ if token.ttype != dns.tokenizer.QUOTED_STRING:
+ raise SyntaxError("whitespace after =")
+ value = token.value
+ elif equals > 0:
+ # key=value
+ key = token.value[:equals]
+ value = token.value[equals + 1 :]
+ elif equals == 0:
+ # =key
+ raise SyntaxError('parameter cannot start with "="')
+ else:
+ # key
+ key = token.value
+ value = None
+ _validate_and_define(params, key, value)
+ return cls(rdclass, rdtype, priority, target, params)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ file.write(struct.pack("!H", self.priority))
+ self.target.to_wire(file, None, origin, False)
+ for key in sorted(self.params):
+ file.write(struct.pack("!H", key))
+ value = self.params[key]
+ with dns.renderer.prefixed_length(file, 2):
+ # Note that we're still writing a length of zero if the value is None
+ if value is not None:
+ value.to_wire(file, origin)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ priority = parser.get_uint16()
+ target = parser.get_name(origin)
+ if priority == 0 and parser.remaining() != 0:
+ raise dns.exception.FormError("parameters in AliasMode")
+ params = {}
+ prior_key = -1
+ while parser.remaining() > 0:
+ key = parser.get_uint16()
+ if key < prior_key:
+ raise dns.exception.FormError("keys not in order")
+ prior_key = key
+ vlen = parser.get_uint16()
+ pcls = _class_for_key.get(key, GenericParam)
+ with parser.restrict_to(vlen):
+ value = pcls.from_wire_parser(parser, origin)
+ params[key] = value
+ return cls(rdclass, rdtype, priority, target, params)
+
+ def _processing_priority(self):
+ return self.priority
+
+ @classmethod
+ def _processing_order(cls, iterable):
+ return dns.rdtypes.util.priority_processing_order(iterable)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/tlsabase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/tlsabase.py
new file mode 100644
index 00000000..a059d2c4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/tlsabase.py
@@ -0,0 +1,71 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import binascii
+import struct
+
+import dns.immutable
+import dns.rdata
+import dns.rdatatype
+
+
+@dns.immutable.immutable
+class TLSABase(dns.rdata.Rdata):
+ """Base class for TLSA and SMIMEA records"""
+
+ # see: RFC 6698
+
+ __slots__ = ["usage", "selector", "mtype", "cert"]
+
+ def __init__(self, rdclass, rdtype, usage, selector, mtype, cert):
+ super().__init__(rdclass, rdtype)
+ self.usage = self._as_uint8(usage)
+ self.selector = self._as_uint8(selector)
+ self.mtype = self._as_uint8(mtype)
+ self.cert = self._as_bytes(cert)
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop("chunksize", 128)
+ return "%d %d %d %s" % (
+ self.usage,
+ self.selector,
+ self.mtype,
+ dns.rdata._hexify(self.cert, chunksize=chunksize, **kw),
+ )
+
+ @classmethod
+ def from_text(
+ cls, rdclass, rdtype, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ usage = tok.get_uint8()
+ selector = tok.get_uint8()
+ mtype = tok.get_uint8()
+ cert = tok.concatenate_remaining_identifiers().encode()
+ cert = binascii.unhexlify(cert)
+ return cls(rdclass, rdtype, usage, selector, mtype, cert)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ header = struct.pack("!BBB", self.usage, self.selector, self.mtype)
+ file.write(header)
+ file.write(self.cert)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ header = parser.get_struct("BBB")
+ cert = parser.get_remaining()
+ return cls(rdclass, rdtype, header[0], header[1], header[2], cert)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/txtbase.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/txtbase.py
new file mode 100644
index 00000000..73db6d9e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/txtbase.py
@@ -0,0 +1,106 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""TXT-like base class."""
+
+from typing import Any, Dict, Iterable, Optional, Tuple, Union
+
+import dns.exception
+import dns.immutable
+import dns.rdata
+import dns.renderer
+import dns.tokenizer
+
+
+@dns.immutable.immutable
+class TXTBase(dns.rdata.Rdata):
+ """Base class for rdata that is like a TXT record (see RFC 1035)."""
+
+ __slots__ = ["strings"]
+
+ def __init__(
+ self,
+ rdclass: dns.rdataclass.RdataClass,
+ rdtype: dns.rdatatype.RdataType,
+ strings: Iterable[Union[bytes, str]],
+ ):
+ """Initialize a TXT-like rdata.
+
+ *rdclass*, an ``int`` is the rdataclass of the Rdata.
+
+ *rdtype*, an ``int`` is the rdatatype of the Rdata.
+
+ *strings*, a tuple of ``bytes``
+ """
+ super().__init__(rdclass, rdtype)
+ self.strings: Tuple[bytes] = self._as_tuple(
+ strings, lambda x: self._as_bytes(x, True, 255)
+ )
+ if len(self.strings) == 0:
+ raise ValueError("the list of strings must not be empty")
+
+ def to_text(
+ self,
+ origin: Optional[dns.name.Name] = None,
+ relativize: bool = True,
+ **kw: Dict[str, Any],
+ ) -> str:
+ txt = ""
+ prefix = ""
+ for s in self.strings:
+ txt += f'{prefix}"{dns.rdata._escapify(s)}"'
+ prefix = " "
+ return txt
+
+ @classmethod
+ def from_text(
+ cls,
+ rdclass: dns.rdataclass.RdataClass,
+ rdtype: dns.rdatatype.RdataType,
+ tok: dns.tokenizer.Tokenizer,
+ origin: Optional[dns.name.Name] = None,
+ relativize: bool = True,
+ relativize_to: Optional[dns.name.Name] = None,
+ ) -> dns.rdata.Rdata:
+ strings = []
+ for token in tok.get_remaining():
+ token = token.unescape_to_bytes()
+ # The 'if' below is always true in the current code, but we
+ # are leaving this check in in case things change some day.
+ if not (
+ token.is_quoted_string() or token.is_identifier()
+ ): # pragma: no cover
+ raise dns.exception.SyntaxError("expected a string")
+ if len(token.value) > 255:
+ raise dns.exception.SyntaxError("string too long")
+ strings.append(token.value)
+ if len(strings) == 0:
+ raise dns.exception.UnexpectedEnd
+ return cls(rdclass, rdtype, strings)
+
+ def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ for s in self.strings:
+ with dns.renderer.prefixed_length(file, 1):
+ file.write(s)
+
+ @classmethod
+ def from_wire_parser(cls, rdclass, rdtype, parser, origin=None):
+ strings = []
+ while parser.remaining() > 0:
+ s = parser.get_counted_bytes()
+ strings.append(s)
+ return cls(rdclass, rdtype, strings)
diff --git a/.venv/lib/python3.12/site-packages/dns/rdtypes/util.py b/.venv/lib/python3.12/site-packages/dns/rdtypes/util.py
new file mode 100644
index 00000000..653a0bf2
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/rdtypes/util.py
@@ -0,0 +1,257 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import collections
+import random
+import struct
+from typing import Any, List
+
+import dns.exception
+import dns.ipv4
+import dns.ipv6
+import dns.name
+import dns.rdata
+
+
+class Gateway:
+ """A helper class for the IPSECKEY gateway and AMTRELAY relay fields"""
+
+ name = ""
+
+ def __init__(self, type, gateway=None):
+ self.type = dns.rdata.Rdata._as_uint8(type)
+ self.gateway = gateway
+ self._check()
+
+ @classmethod
+ def _invalid_type(cls, gateway_type):
+ return f"invalid {cls.name} type: {gateway_type}"
+
+ def _check(self):
+ if self.type == 0:
+ if self.gateway not in (".", None):
+ raise SyntaxError(f"invalid {self.name} for type 0")
+ self.gateway = None
+ elif self.type == 1:
+ # check that it's OK
+ dns.ipv4.inet_aton(self.gateway)
+ elif self.type == 2:
+ # check that it's OK
+ dns.ipv6.inet_aton(self.gateway)
+ elif self.type == 3:
+ if not isinstance(self.gateway, dns.name.Name):
+ raise SyntaxError(f"invalid {self.name}; not a name")
+ else:
+ raise SyntaxError(self._invalid_type(self.type))
+
+ def to_text(self, origin=None, relativize=True):
+ if self.type == 0:
+ return "."
+ elif self.type in (1, 2):
+ return self.gateway
+ elif self.type == 3:
+ return str(self.gateway.choose_relativity(origin, relativize))
+ else:
+ raise ValueError(self._invalid_type(self.type)) # pragma: no cover
+
+ @classmethod
+ def from_text(
+ cls, gateway_type, tok, origin=None, relativize=True, relativize_to=None
+ ):
+ if gateway_type in (0, 1, 2):
+ gateway = tok.get_string()
+ elif gateway_type == 3:
+ gateway = tok.get_name(origin, relativize, relativize_to)
+ else:
+ raise dns.exception.SyntaxError(
+ cls._invalid_type(gateway_type)
+ ) # pragma: no cover
+ return cls(gateway_type, gateway)
+
+ # pylint: disable=unused-argument
+ def to_wire(self, file, compress=None, origin=None, canonicalize=False):
+ if self.type == 0:
+ pass
+ elif self.type == 1:
+ file.write(dns.ipv4.inet_aton(self.gateway))
+ elif self.type == 2:
+ file.write(dns.ipv6.inet_aton(self.gateway))
+ elif self.type == 3:
+ self.gateway.to_wire(file, None, origin, False)
+ else:
+ raise ValueError(self._invalid_type(self.type)) # pragma: no cover
+
+ # pylint: enable=unused-argument
+
+ @classmethod
+ def from_wire_parser(cls, gateway_type, parser, origin=None):
+ if gateway_type == 0:
+ gateway = None
+ elif gateway_type == 1:
+ gateway = dns.ipv4.inet_ntoa(parser.get_bytes(4))
+ elif gateway_type == 2:
+ gateway = dns.ipv6.inet_ntoa(parser.get_bytes(16))
+ elif gateway_type == 3:
+ gateway = parser.get_name(origin)
+ else:
+ raise dns.exception.FormError(cls._invalid_type(gateway_type))
+ return cls(gateway_type, gateway)
+
+
+class Bitmap:
+ """A helper class for the NSEC/NSEC3/CSYNC type bitmaps"""
+
+ type_name = ""
+
+ def __init__(self, windows=None):
+ last_window = -1
+ self.windows = windows
+ for window, bitmap in self.windows:
+ if not isinstance(window, int):
+ raise ValueError(f"bad {self.type_name} window type")
+ if window <= last_window:
+ raise ValueError(f"bad {self.type_name} window order")
+ if window > 256:
+ raise ValueError(f"bad {self.type_name} window number")
+ last_window = window
+ if not isinstance(bitmap, bytes):
+ raise ValueError(f"bad {self.type_name} octets type")
+ if len(bitmap) == 0 or len(bitmap) > 32:
+ raise ValueError(f"bad {self.type_name} octets")
+
+ def to_text(self) -> str:
+ text = ""
+ for window, bitmap in self.windows:
+ bits = []
+ for i, byte in enumerate(bitmap):
+ for j in range(0, 8):
+ if byte & (0x80 >> j):
+ rdtype = window * 256 + i * 8 + j
+ bits.append(dns.rdatatype.to_text(rdtype))
+ text += " " + " ".join(bits)
+ return text
+
+ @classmethod
+ def from_text(cls, tok: "dns.tokenizer.Tokenizer") -> "Bitmap":
+ rdtypes = []
+ for token in tok.get_remaining():
+ rdtype = dns.rdatatype.from_text(token.unescape().value)
+ if rdtype == 0:
+ raise dns.exception.SyntaxError(f"{cls.type_name} with bit 0")
+ rdtypes.append(rdtype)
+ return cls.from_rdtypes(rdtypes)
+
+ @classmethod
+ def from_rdtypes(cls, rdtypes: List[dns.rdatatype.RdataType]) -> "Bitmap":
+ rdtypes = sorted(rdtypes)
+ window = 0
+ octets = 0
+ prior_rdtype = 0
+ bitmap = bytearray(b"\0" * 32)
+ windows = []
+ for rdtype in rdtypes:
+ if rdtype == prior_rdtype:
+ continue
+ prior_rdtype = rdtype
+ new_window = rdtype // 256
+ if new_window != window:
+ if octets != 0:
+ windows.append((window, bytes(bitmap[0:octets])))
+ bitmap = bytearray(b"\0" * 32)
+ window = new_window
+ offset = rdtype % 256
+ byte = offset // 8
+ bit = offset % 8
+ octets = byte + 1
+ bitmap[byte] = bitmap[byte] | (0x80 >> bit)
+ if octets != 0:
+ windows.append((window, bytes(bitmap[0:octets])))
+ return cls(windows)
+
+ def to_wire(self, file: Any) -> None:
+ for window, bitmap in self.windows:
+ file.write(struct.pack("!BB", window, len(bitmap)))
+ file.write(bitmap)
+
+ @classmethod
+ def from_wire_parser(cls, parser: "dns.wire.Parser") -> "Bitmap":
+ windows = []
+ while parser.remaining() > 0:
+ window = parser.get_uint8()
+ bitmap = parser.get_counted_bytes()
+ windows.append((window, bitmap))
+ return cls(windows)
+
+
+def _priority_table(items):
+ by_priority = collections.defaultdict(list)
+ for rdata in items:
+ by_priority[rdata._processing_priority()].append(rdata)
+ return by_priority
+
+
+def priority_processing_order(iterable):
+ items = list(iterable)
+ if len(items) == 1:
+ return items
+ by_priority = _priority_table(items)
+ ordered = []
+ for k in sorted(by_priority.keys()):
+ rdatas = by_priority[k]
+ random.shuffle(rdatas)
+ ordered.extend(rdatas)
+ return ordered
+
+
+_no_weight = 0.1
+
+
+def weighted_processing_order(iterable):
+ items = list(iterable)
+ if len(items) == 1:
+ return items
+ by_priority = _priority_table(items)
+ ordered = []
+ for k in sorted(by_priority.keys()):
+ rdatas = by_priority[k]
+ total = sum(rdata._processing_weight() or _no_weight for rdata in rdatas)
+ while len(rdatas) > 1:
+ r = random.uniform(0, total)
+ for n, rdata in enumerate(rdatas): # noqa: B007
+ weight = rdata._processing_weight() or _no_weight
+ if weight > r:
+ break
+ r -= weight
+ total -= weight
+ ordered.append(rdata) # pylint: disable=undefined-loop-variable
+ del rdatas[n] # pylint: disable=undefined-loop-variable
+ ordered.append(rdatas[0])
+ return ordered
+
+
+def parse_formatted_hex(formatted, num_chunks, chunk_size, separator):
+ if len(formatted) != num_chunks * (chunk_size + 1) - 1:
+ raise ValueError("invalid formatted hex string")
+ value = b""
+ for _ in range(num_chunks):
+ chunk = formatted[0:chunk_size]
+ value += int(chunk, 16).to_bytes(chunk_size // 2, "big")
+ formatted = formatted[chunk_size:]
+ if len(formatted) > 0 and formatted[0] != separator:
+ raise ValueError("invalid formatted hex string")
+ formatted = formatted[1:]
+ return value