dnspython 2.5.0__tar.gz → 2.6.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/PKG-INFO +17 -16
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/README.md +2 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/_asyncio_backend.py +3 -2
- dnspython-2.6.0rc1/dns/_features.py +92 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/_trio_backend.py +6 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/asyncquery.py +33 -17
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssec.py +10 -9
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/__init__.py +6 -7
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/edns.py +41 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/message.py +0 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/name.py +8 -8
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/nameserver.py +10 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/node.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/query.py +76 -57
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/quic/__init__.py +6 -6
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdata.py +3 -4
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdataset.py +0 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/AFSDB.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/AMTRELAY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/AVC.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CAA.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CDNSKEY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CDS.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CERT.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CNAME.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/CSYNC.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/DLV.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/DNAME.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/DNSKEY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/DS.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/EUI48.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/EUI64.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/GPOS.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/HINFO.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/HIP.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/ISDN.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/L32.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/L64.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/LOC.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/LP.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/MX.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NID.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NINFO.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NS.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NSEC.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NSEC3.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/NSEC3PARAM.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/OPENPGPKEY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/OPT.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/PTR.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/RP.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/RRSIG.py +0 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/RT.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/SOA.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/SPF.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/SSHFP.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/TKEY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/TLSA.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/TSIG.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/TXT.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/URI.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/X25.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/ZONEMD.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/CH/A.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/A.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/AAAA.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/APL.py +0 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/DHCID.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/IPSECKEY.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/KX.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/NAPTR.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/NSAP.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/NSAP_PTR.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/PX.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/SRV.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/WKS.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/dnskeybase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/dsbase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/euibase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/mxbase.py +0 -3
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/nsbase.py +0 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/svcbbase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/tlsabase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/txtbase.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rrset.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/set.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/tsig.py +0 -9
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/version.py +3 -3
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/win32util.py +4 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/zone.py +0 -9
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/zonefile.py +0 -1
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/pyproject.toml +14 -13
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_async.py +11 -20
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_dnssec.py +2 -2
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_doh.py +0 -18
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_edns.py +17 -2
- dnspython-2.6.0rc1/tests/test_features.py +77 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_resolver.py +15 -6
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_resolver_override.py +12 -7
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/util.py +9 -1
- dnspython-2.6.0rc1/util/generate-features +32 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/.gitignore +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/LICENSE +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/_asyncbackend.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/_ddr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/_immutable_ctx.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/asyncbackend.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/asyncresolver.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/base.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/cryptography.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/dsa.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/ecdsa.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/eddsa.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssecalgs/rsa.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/dnssectypes.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/e164.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/entropy.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/enum.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/exception.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/flags.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/grange.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/immutable.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/inet.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/ipv4.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/ipv6.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/namedict.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/opcode.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/py.typed +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/quic/_asyncio.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/quic/_common.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/quic/_sync.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/quic/_trio.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rcode.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdataclass.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdatatype.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/SMIMEA.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/ANY/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/CH/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/HTTPS.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/SVCB.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/IN/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/rdtypes/util.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/renderer.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/resolver.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/reversename.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/serial.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/tokenizer.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/transaction.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/tsigkeyring.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/ttl.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/update.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/versioned.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/wire.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/xfr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/dns/zonetypes.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/async_dns.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/ddns.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/ddr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/doh-json.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/doh.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/doq.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/e164.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/ecs.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/edns.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/edns_resolver.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/mx.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/name.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/query_specific.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/receive_notify.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/reverse.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/reverse_name.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/send_notify.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/wire_read_tcp.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/xfr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/examples/zonediff.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/__init__.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/example +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/example1.good +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/example2.good +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/example3.good +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/example4.good +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/keys.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/md_module.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/mx-2-0.pickle +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/nanonameserver.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/nanoquic.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/query +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/stxt_module.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/svcb_test_vectors.generic +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/svcb_test_vectors.text +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_address.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_bugs.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_constants.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_ddr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_dnssecalgs.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_doq.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_entropy.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_exceptions.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_flags.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_generate.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_grange.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_immutable.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_message.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_name.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_namedict.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_nsec3.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_nsec3_hash.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_ntoaaton.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_processing_order.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_query.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdata.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdataset.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdtypeandclass.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdtypeanydnskey.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdtypeanyeui.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdtypeanyloc.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rdtypeanytkey.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_renderer.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_resolution.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rrset.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_rrset_reader.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_serial.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_set.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_svcb.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_tokenizer.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_transaction.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_tsig.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_tsigkeyring.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_ttl.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_update.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_wire.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_xfr.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_zone.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/test_zonedigest.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/tls/ca.crt +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/tls/private.pem +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/tls/public.crt +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/ttxt_module.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/tests/utest.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/util/constants-tool +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/util/generate-mx-pickle.py +0 -0
- {dnspython-2.5.0 → dnspython-2.6.0rc1}/util/generate-rdatatype-doc.py +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dnspython
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0rc1
|
|
4
4
|
Summary: DNS toolkit
|
|
5
5
|
Project-URL: homepage, https://www.dnspython.org
|
|
6
6
|
Project-URL: repository, https://github.com/rthalley/dnspython.git
|
|
7
7
|
Project-URL: documentation, https://dnspython.readthedocs.io/en/stable/
|
|
8
8
|
Project-URL: issues, https://github.com/rthalley/dnspython/issues
|
|
9
9
|
Author-email: Bob Halley <halley@dnspython.org>
|
|
10
|
+
License-Expression: ISC
|
|
10
11
|
License-File: LICENSE
|
|
11
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
13
|
Classifier: Intended Audience :: Developers
|
|
@@ -27,26 +28,26 @@ Requires-Python: >=3.8
|
|
|
27
28
|
Provides-Extra: dev
|
|
28
29
|
Requires-Dist: black>=23.1.0; extra == 'dev'
|
|
29
30
|
Requires-Dist: coverage>=7.0; extra == 'dev'
|
|
30
|
-
Requires-Dist: flake8>=
|
|
31
|
-
Requires-Dist: mypy>=1.
|
|
32
|
-
Requires-Dist: pylint>=
|
|
33
|
-
Requires-Dist: pytest-cov>=
|
|
34
|
-
Requires-Dist: pytest>=
|
|
35
|
-
Requires-Dist: sphinx>=7.
|
|
31
|
+
Requires-Dist: flake8>=7; extra == 'dev'
|
|
32
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
33
|
+
Requires-Dist: pylint>=3; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
36
|
+
Requires-Dist: sphinx>=7.2.0; extra == 'dev'
|
|
36
37
|
Requires-Dist: twine>=4.0.0; extra == 'dev'
|
|
37
|
-
Requires-Dist: wheel>=0.
|
|
38
|
+
Requires-Dist: wheel>=0.42.0; extra == 'dev'
|
|
38
39
|
Provides-Extra: dnssec
|
|
39
|
-
Requires-Dist: cryptography>=
|
|
40
|
+
Requires-Dist: cryptography>=42; extra == 'dnssec'
|
|
40
41
|
Provides-Extra: doh
|
|
41
42
|
Requires-Dist: h2>=4.1.0; extra == 'doh'
|
|
42
|
-
Requires-Dist: httpcore>=0.
|
|
43
|
-
Requires-Dist: httpx>=0.
|
|
43
|
+
Requires-Dist: httpcore>=1.0.0; extra == 'doh'
|
|
44
|
+
Requires-Dist: httpx>=0.26.0; extra == 'doh'
|
|
44
45
|
Provides-Extra: doq
|
|
45
|
-
Requires-Dist: aioquic>=0.9.
|
|
46
|
+
Requires-Dist: aioquic>=0.9.25; extra == 'doq'
|
|
46
47
|
Provides-Extra: idna
|
|
47
|
-
Requires-Dist: idna>=
|
|
48
|
+
Requires-Dist: idna>=3.6; extra == 'idna'
|
|
48
49
|
Provides-Extra: trio
|
|
49
|
-
Requires-Dist: trio>=0.
|
|
50
|
+
Requires-Dist: trio>=0.23; extra == 'trio'
|
|
50
51
|
Provides-Extra: wmi
|
|
51
52
|
Requires-Dist: wmi>=1.5.1; extra == 'wmi'
|
|
52
53
|
Description-Content-Type: text/markdown
|
|
@@ -83,9 +84,9 @@ to facilitate the testing of DNS software.
|
|
|
83
84
|
|
|
84
85
|
## ABOUT THIS RELEASE
|
|
85
86
|
|
|
86
|
-
This is dnspython 2.
|
|
87
|
+
This is dnspython 2.6.0rc1.
|
|
87
88
|
Please read
|
|
88
|
-
[What's New](https://dnspython.readthedocs.io/en/
|
|
89
|
+
[What's New](https://dnspython.readthedocs.io/en/latest/whatsnew.html) for
|
|
89
90
|
information about the changes in this release.
|
|
90
91
|
|
|
91
92
|
## INSTALLATION
|
|
@@ -30,9 +30,9 @@ to facilitate the testing of DNS software.
|
|
|
30
30
|
|
|
31
31
|
## ABOUT THIS RELEASE
|
|
32
32
|
|
|
33
|
-
This is dnspython 2.
|
|
33
|
+
This is dnspython 2.6.0rc1.
|
|
34
34
|
Please read
|
|
35
|
-
[What's New](https://dnspython.readthedocs.io/en/
|
|
35
|
+
[What's New](https://dnspython.readthedocs.io/en/latest/whatsnew.html) for
|
|
36
36
|
information about the changes in this release.
|
|
37
37
|
|
|
38
38
|
## INSTALLATION
|
|
@@ -7,6 +7,7 @@ import socket
|
|
|
7
7
|
import sys
|
|
8
8
|
|
|
9
9
|
import dns._asyncbackend
|
|
10
|
+
import dns._features
|
|
10
11
|
import dns.exception
|
|
11
12
|
import dns.inet
|
|
12
13
|
|
|
@@ -122,7 +123,7 @@ class StreamSocket(dns._asyncbackend.StreamSocket):
|
|
|
122
123
|
return self.writer.get_extra_info("peercert")
|
|
123
124
|
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
if dns._features.have("doh"):
|
|
126
127
|
import anyio
|
|
127
128
|
import httpcore
|
|
128
129
|
import httpcore._backends.anyio
|
|
@@ -206,7 +207,7 @@ try:
|
|
|
206
207
|
resolver, local_port, bootstrap_address, family
|
|
207
208
|
)
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
else:
|
|
210
211
|
_HTTPTransport = dns._asyncbackend.NullTransport # type: ignore
|
|
211
212
|
|
|
212
213
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
|
|
2
|
+
|
|
3
|
+
import importlib.metadata
|
|
4
|
+
import itertools
|
|
5
|
+
import string
|
|
6
|
+
from typing import Dict, List, Tuple
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _tuple_from_text(version: str) -> Tuple:
|
|
10
|
+
text_parts = version.split(".")
|
|
11
|
+
int_parts = []
|
|
12
|
+
for text_part in text_parts:
|
|
13
|
+
digit_prefix = "".join(
|
|
14
|
+
itertools.takewhile(lambda x: x in string.digits, text_part)
|
|
15
|
+
)
|
|
16
|
+
try:
|
|
17
|
+
int_parts.append(int(digit_prefix))
|
|
18
|
+
except Exception:
|
|
19
|
+
break
|
|
20
|
+
return tuple(int_parts)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _version_check(
|
|
24
|
+
requirement: str,
|
|
25
|
+
) -> bool:
|
|
26
|
+
"""Is the requirement fulfilled?
|
|
27
|
+
|
|
28
|
+
The requirement must be of the form
|
|
29
|
+
|
|
30
|
+
package>=version
|
|
31
|
+
"""
|
|
32
|
+
package, minimum = requirement.split(">=")
|
|
33
|
+
try:
|
|
34
|
+
version = importlib.metadata.version(package)
|
|
35
|
+
except Exception:
|
|
36
|
+
return False
|
|
37
|
+
t_version = _tuple_from_text(version)
|
|
38
|
+
t_minimum = _tuple_from_text(minimum)
|
|
39
|
+
if t_version < t_minimum:
|
|
40
|
+
return False
|
|
41
|
+
return True
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
_cache: Dict[str, bool] = {}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def have(feature: str) -> bool:
|
|
48
|
+
"""Is *feature* available?
|
|
49
|
+
|
|
50
|
+
This tests if all optional packages needed for the
|
|
51
|
+
feature are available and recent enough.
|
|
52
|
+
|
|
53
|
+
Returns ``True`` if the feature is available,
|
|
54
|
+
and ``False`` if it is not or if metadata is
|
|
55
|
+
missing.
|
|
56
|
+
"""
|
|
57
|
+
value = _cache.get(feature)
|
|
58
|
+
if value is not None:
|
|
59
|
+
return value
|
|
60
|
+
requirements = _requirements.get(feature)
|
|
61
|
+
if requirements is None:
|
|
62
|
+
# we make a cache entry here for consistency not performance
|
|
63
|
+
_cache[feature] = False
|
|
64
|
+
return False
|
|
65
|
+
ok = True
|
|
66
|
+
for requirement in requirements:
|
|
67
|
+
if not _version_check(requirement):
|
|
68
|
+
ok = False
|
|
69
|
+
break
|
|
70
|
+
_cache[feature] = ok
|
|
71
|
+
return ok
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def force(feature: str, enabled: bool) -> None:
|
|
75
|
+
"""Force the status of *feature* to be *enabled*.
|
|
76
|
+
|
|
77
|
+
This method is provided as a workaround for any cases
|
|
78
|
+
where importlib.metadata is ineffective, or for testing.
|
|
79
|
+
"""
|
|
80
|
+
_cache[feature] = enabled
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
_requirements: Dict[str, List[str]] = {
|
|
84
|
+
### BEGIN generated requirements
|
|
85
|
+
"dnssec": ["cryptography>=42"],
|
|
86
|
+
"doh": ["httpcore>=1.0.0", "httpx>=0.26.0", "h2>=4.1.0"],
|
|
87
|
+
"doq": ["aioquic>=0.9.25"],
|
|
88
|
+
"idna": ["idna>=3.6"],
|
|
89
|
+
"trio": ["trio>=0.23"],
|
|
90
|
+
"wmi": ["wmi>=1.5.1"],
|
|
91
|
+
### END generated requirements
|
|
92
|
+
}
|
|
@@ -8,9 +8,13 @@ import trio
|
|
|
8
8
|
import trio.socket # type: ignore
|
|
9
9
|
|
|
10
10
|
import dns._asyncbackend
|
|
11
|
+
import dns._features
|
|
11
12
|
import dns.exception
|
|
12
13
|
import dns.inet
|
|
13
14
|
|
|
15
|
+
if not dns._features.have("trio"):
|
|
16
|
+
raise ImportError("trio not found or too old")
|
|
17
|
+
|
|
14
18
|
|
|
15
19
|
def _maybe_timeout(timeout):
|
|
16
20
|
if timeout is not None:
|
|
@@ -95,7 +99,7 @@ class StreamSocket(dns._asyncbackend.StreamSocket):
|
|
|
95
99
|
raise NotImplementedError
|
|
96
100
|
|
|
97
101
|
|
|
98
|
-
|
|
102
|
+
if dns._features.have("doh"):
|
|
99
103
|
import httpcore
|
|
100
104
|
import httpcore._backends.trio
|
|
101
105
|
import httpx
|
|
@@ -177,7 +181,7 @@ try:
|
|
|
177
181
|
resolver, local_port, bootstrap_address, family
|
|
178
182
|
)
|
|
179
183
|
|
|
180
|
-
|
|
184
|
+
else:
|
|
181
185
|
_HTTPTransport = dns._asyncbackend.NullTransport # type: ignore
|
|
182
186
|
|
|
183
187
|
|
|
@@ -41,7 +41,6 @@ from dns.query import (
|
|
|
41
41
|
NoDOQ,
|
|
42
42
|
UDPMode,
|
|
43
43
|
_compute_times,
|
|
44
|
-
_have_http2,
|
|
45
44
|
_make_dot_ssl_context,
|
|
46
45
|
_matches_destination,
|
|
47
46
|
_remaining,
|
|
@@ -121,6 +120,8 @@ async def receive_udp(
|
|
|
121
120
|
request_mac: Optional[bytes] = b"",
|
|
122
121
|
ignore_trailing: bool = False,
|
|
123
122
|
raise_on_truncation: bool = False,
|
|
123
|
+
ignore_errors: bool = False,
|
|
124
|
+
query: Optional[dns.message.Message] = None,
|
|
124
125
|
) -> Any:
|
|
125
126
|
"""Read a DNS message from a UDP socket.
|
|
126
127
|
|
|
@@ -134,22 +135,30 @@ async def receive_udp(
|
|
|
134
135
|
"""
|
|
135
136
|
|
|
136
137
|
wire = b""
|
|
137
|
-
while
|
|
138
|
+
while True:
|
|
138
139
|
(wire, from_address) = await sock.recvfrom(65535, _timeout(expiration))
|
|
139
|
-
if _matches_destination(
|
|
140
|
+
if not _matches_destination(
|
|
140
141
|
sock.family, from_address, destination, ignore_unexpected
|
|
141
142
|
):
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
143
|
+
continue
|
|
144
|
+
received_time = time.time()
|
|
145
|
+
try:
|
|
146
|
+
r = dns.message.from_wire(
|
|
147
|
+
wire,
|
|
148
|
+
keyring=keyring,
|
|
149
|
+
request_mac=request_mac,
|
|
150
|
+
one_rr_per_rrset=one_rr_per_rrset,
|
|
151
|
+
ignore_trailing=ignore_trailing,
|
|
152
|
+
raise_on_truncation=raise_on_truncation,
|
|
153
|
+
)
|
|
154
|
+
except Exception:
|
|
155
|
+
if ignore_errors:
|
|
156
|
+
continue
|
|
157
|
+
else:
|
|
158
|
+
raise
|
|
159
|
+
if ignore_errors and query is not None and not query.is_response(r):
|
|
160
|
+
continue
|
|
161
|
+
return (r, received_time, from_address)
|
|
153
162
|
|
|
154
163
|
|
|
155
164
|
async def udp(
|
|
@@ -165,6 +174,7 @@ async def udp(
|
|
|
165
174
|
raise_on_truncation: bool = False,
|
|
166
175
|
sock: Optional[dns.asyncbackend.DatagramSocket] = None,
|
|
167
176
|
backend: Optional[dns.asyncbackend.Backend] = None,
|
|
177
|
+
ignore_errors: bool = False,
|
|
168
178
|
) -> dns.message.Message:
|
|
169
179
|
"""Return the response obtained after sending a query via UDP.
|
|
170
180
|
|
|
@@ -206,9 +216,13 @@ async def udp(
|
|
|
206
216
|
q.mac,
|
|
207
217
|
ignore_trailing,
|
|
208
218
|
raise_on_truncation,
|
|
219
|
+
ignore_errors,
|
|
220
|
+
q,
|
|
209
221
|
)
|
|
210
222
|
r.time = received_time - begin_time
|
|
211
|
-
|
|
223
|
+
# We don't need to check q.is_response() if we are in ignore_errors mode
|
|
224
|
+
# as receive_udp() will have checked it.
|
|
225
|
+
if not (ignore_errors or q.is_response(r)):
|
|
212
226
|
raise BadResponse
|
|
213
227
|
return r
|
|
214
228
|
|
|
@@ -226,6 +240,7 @@ async def udp_with_fallback(
|
|
|
226
240
|
udp_sock: Optional[dns.asyncbackend.DatagramSocket] = None,
|
|
227
241
|
tcp_sock: Optional[dns.asyncbackend.StreamSocket] = None,
|
|
228
242
|
backend: Optional[dns.asyncbackend.Backend] = None,
|
|
243
|
+
ignore_errors: bool = False,
|
|
229
244
|
) -> Tuple[dns.message.Message, bool]:
|
|
230
245
|
"""Return the response to the query, trying UDP first and falling back
|
|
231
246
|
to TCP if UDP results in a truncated response.
|
|
@@ -261,6 +276,7 @@ async def udp_with_fallback(
|
|
|
261
276
|
True,
|
|
262
277
|
udp_sock,
|
|
263
278
|
backend,
|
|
279
|
+
ignore_errors,
|
|
264
280
|
)
|
|
265
281
|
return (response, False)
|
|
266
282
|
except dns.message.Truncated:
|
|
@@ -534,7 +550,7 @@ async def https(
|
|
|
534
550
|
transport = backend.get_transport_class()(
|
|
535
551
|
local_address=local_address,
|
|
536
552
|
http1=True,
|
|
537
|
-
http2=
|
|
553
|
+
http2=True,
|
|
538
554
|
verify=verify,
|
|
539
555
|
local_port=local_port,
|
|
540
556
|
bootstrap_address=bootstrap_address,
|
|
@@ -546,7 +562,7 @@ async def https(
|
|
|
546
562
|
cm: contextlib.AbstractAsyncContextManager = NullContext(client)
|
|
547
563
|
else:
|
|
548
564
|
cm = httpx.AsyncClient(
|
|
549
|
-
http1=True, http2=
|
|
565
|
+
http1=True, http2=True, verify=verify, transport=transport
|
|
550
566
|
)
|
|
551
567
|
|
|
552
568
|
async with cm as the_client:
|
|
@@ -27,6 +27,7 @@ import time
|
|
|
27
27
|
from datetime import datetime
|
|
28
28
|
from typing import Callable, Dict, List, Optional, Set, Tuple, Union, cast
|
|
29
29
|
|
|
30
|
+
import dns._features
|
|
30
31
|
import dns.exception
|
|
31
32
|
import dns.name
|
|
32
33
|
import dns.node
|
|
@@ -1169,7 +1170,7 @@ def _need_pyca(*args, **kwargs):
|
|
|
1169
1170
|
) # pragma: no cover
|
|
1170
1171
|
|
|
1171
1172
|
|
|
1172
|
-
|
|
1173
|
+
if dns._features.have("dnssec"):
|
|
1173
1174
|
from cryptography.exceptions import InvalidSignature
|
|
1174
1175
|
from cryptography.hazmat.primitives.asymmetric import dsa # pylint: disable=W0611
|
|
1175
1176
|
from cryptography.hazmat.primitives.asymmetric import ec # pylint: disable=W0611
|
|
@@ -1184,20 +1185,20 @@ try:
|
|
|
1184
1185
|
get_algorithm_cls_from_dnskey,
|
|
1185
1186
|
)
|
|
1186
1187
|
from dns.dnssecalgs.base import GenericPrivateKey, GenericPublicKey
|
|
1187
|
-
|
|
1188
|
-
validate = _need_pyca
|
|
1189
|
-
validate_rrsig = _need_pyca
|
|
1190
|
-
sign = _need_pyca
|
|
1191
|
-
make_dnskey = _need_pyca
|
|
1192
|
-
make_cdnskey = _need_pyca
|
|
1193
|
-
_have_pyca = False
|
|
1194
|
-
else:
|
|
1188
|
+
|
|
1195
1189
|
validate = _validate # type: ignore
|
|
1196
1190
|
validate_rrsig = _validate_rrsig # type: ignore
|
|
1197
1191
|
sign = _sign
|
|
1198
1192
|
make_dnskey = _make_dnskey
|
|
1199
1193
|
make_cdnskey = _make_cdnskey
|
|
1200
1194
|
_have_pyca = True
|
|
1195
|
+
else: # pragma: no cover
|
|
1196
|
+
validate = _need_pyca
|
|
1197
|
+
validate_rrsig = _need_pyca
|
|
1198
|
+
sign = _need_pyca
|
|
1199
|
+
make_dnskey = _need_pyca
|
|
1200
|
+
make_cdnskey = _need_pyca
|
|
1201
|
+
_have_pyca = False
|
|
1201
1202
|
|
|
1202
1203
|
### BEGIN generated Algorithm constants
|
|
1203
1204
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from typing import Dict, Optional, Tuple, Type, Union
|
|
2
2
|
|
|
3
3
|
import dns.name
|
|
4
|
+
from dns.dnssecalgs.base import GenericPrivateKey
|
|
5
|
+
from dns.dnssectypes import Algorithm
|
|
6
|
+
from dns.exception import UnsupportedAlgorithm
|
|
7
|
+
from dns.rdtypes.ANY.DNSKEY import DNSKEY
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
from dns.dnssecalgs.base import GenericPrivateKey
|
|
9
|
+
if dns._features.have("dnssec"):
|
|
7
10
|
from dns.dnssecalgs.dsa import PrivateDSA, PrivateDSANSEC3SHA1
|
|
8
11
|
from dns.dnssecalgs.ecdsa import PrivateECDSAP256SHA256, PrivateECDSAP384SHA384
|
|
9
12
|
from dns.dnssecalgs.eddsa import PrivateED448, PrivateED25519
|
|
@@ -16,13 +19,9 @@ try:
|
|
|
16
19
|
)
|
|
17
20
|
|
|
18
21
|
_have_cryptography = True
|
|
19
|
-
|
|
22
|
+
else:
|
|
20
23
|
_have_cryptography = False
|
|
21
24
|
|
|
22
|
-
from dns.dnssectypes import Algorithm
|
|
23
|
-
from dns.exception import UnsupportedAlgorithm
|
|
24
|
-
from dns.rdtypes.ANY.DNSKEY import DNSKEY
|
|
25
|
-
|
|
26
25
|
AlgorithmPrefix = Optional[Union[bytes, dns.name.Name]]
|
|
27
26
|
|
|
28
27
|
algorithms: Dict[Tuple[Algorithm, AlgorithmPrefix], Type[GenericPrivateKey]] = {}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
"""EDNS Options"""
|
|
19
19
|
|
|
20
|
+
import binascii
|
|
20
21
|
import math
|
|
21
22
|
import socket
|
|
22
23
|
import struct
|
|
@@ -58,7 +59,6 @@ class OptionType(dns.enum.IntEnum):
|
|
|
58
59
|
|
|
59
60
|
|
|
60
61
|
class Option:
|
|
61
|
-
|
|
62
62
|
"""Base class for all EDNS option types."""
|
|
63
63
|
|
|
64
64
|
def __init__(self, otype: Union[OptionType, str]):
|
|
@@ -76,6 +76,9 @@ class Option:
|
|
|
76
76
|
"""
|
|
77
77
|
raise NotImplementedError # pragma: no cover
|
|
78
78
|
|
|
79
|
+
def to_text(self) -> str:
|
|
80
|
+
raise NotImplementedError # pragma: no cover
|
|
81
|
+
|
|
79
82
|
@classmethod
|
|
80
83
|
def from_wire_parser(cls, otype: OptionType, parser: "dns.wire.Parser") -> "Option":
|
|
81
84
|
"""Build an EDNS option object from wire format.
|
|
@@ -141,7 +144,6 @@ class Option:
|
|
|
141
144
|
|
|
142
145
|
|
|
143
146
|
class GenericOption(Option): # lgtm[py/missing-equals]
|
|
144
|
-
|
|
145
147
|
"""Generic Option Class
|
|
146
148
|
|
|
147
149
|
This class is used for EDNS option types for which we have no better
|
|
@@ -343,6 +345,8 @@ class EDECode(dns.enum.IntEnum):
|
|
|
343
345
|
class EDEOption(Option): # lgtm[py/missing-equals]
|
|
344
346
|
"""Extended DNS Error (EDE, RFC8914)"""
|
|
345
347
|
|
|
348
|
+
_preserve_case = {"DNSKEY", "DS", "DNSSEC", "RRSIGs", "NSEC", "NXDOMAIN"}
|
|
349
|
+
|
|
346
350
|
def __init__(self, code: Union[EDECode, str], text: Optional[str] = None):
|
|
347
351
|
"""*code*, a ``dns.edns.EDECode`` or ``str``, the info code of the
|
|
348
352
|
extended error.
|
|
@@ -360,6 +364,13 @@ class EDEOption(Option): # lgtm[py/missing-equals]
|
|
|
360
364
|
|
|
361
365
|
def to_text(self) -> str:
|
|
362
366
|
output = f"EDE {self.code}"
|
|
367
|
+
if self.code in EDECode:
|
|
368
|
+
desc = EDECode.to_text(self.code)
|
|
369
|
+
desc = " ".join(
|
|
370
|
+
word if word in self._preserve_case else word.title()
|
|
371
|
+
for word in desc.split("_")
|
|
372
|
+
)
|
|
373
|
+
output += f" ({desc})"
|
|
363
374
|
if self.text is not None:
|
|
364
375
|
output += f": {self.text}"
|
|
365
376
|
return output
|
|
@@ -392,9 +403,37 @@ class EDEOption(Option): # lgtm[py/missing-equals]
|
|
|
392
403
|
return cls(code, btext)
|
|
393
404
|
|
|
394
405
|
|
|
406
|
+
class NSIDOption(Option):
|
|
407
|
+
def __init__(self, nsid: bytes):
|
|
408
|
+
super().__init__(OptionType.NSID)
|
|
409
|
+
self.nsid = nsid
|
|
410
|
+
|
|
411
|
+
def to_wire(self, file: Any = None) -> Optional[bytes]:
|
|
412
|
+
if file:
|
|
413
|
+
file.write(self.nsid)
|
|
414
|
+
return None
|
|
415
|
+
else:
|
|
416
|
+
return self.nsid
|
|
417
|
+
|
|
418
|
+
def to_text(self) -> str:
|
|
419
|
+
if all(c >= 0x20 and c <= 0x7E for c in self.nsid):
|
|
420
|
+
# All ASCII printable, so it's probably a string.
|
|
421
|
+
value = self.nsid.decode()
|
|
422
|
+
else:
|
|
423
|
+
value = binascii.hexlify(self.nsid).decode()
|
|
424
|
+
return f"NSID {value}"
|
|
425
|
+
|
|
426
|
+
@classmethod
|
|
427
|
+
def from_wire_parser(
|
|
428
|
+
cls, otype: Union[OptionType, str], parser: dns.wire.Parser
|
|
429
|
+
) -> Option:
|
|
430
|
+
return cls(parser.get_remaining())
|
|
431
|
+
|
|
432
|
+
|
|
395
433
|
_type_to_class: Dict[OptionType, Any] = {
|
|
396
434
|
OptionType.ECS: ECSOption,
|
|
397
435
|
OptionType.EDE: EDEOption,
|
|
436
|
+
OptionType.NSID: NSIDOption,
|
|
398
437
|
}
|
|
399
438
|
|
|
400
439
|
|
|
@@ -1086,7 +1086,6 @@ def _message_factory_from_opcode(opcode):
|
|
|
1086
1086
|
|
|
1087
1087
|
|
|
1088
1088
|
class _WireReader:
|
|
1089
|
-
|
|
1090
1089
|
"""Wire format reader.
|
|
1091
1090
|
|
|
1092
1091
|
parser: the binary parser
|
|
@@ -1386,7 +1385,6 @@ def from_wire(
|
|
|
1386
1385
|
|
|
1387
1386
|
|
|
1388
1387
|
class _TextReader:
|
|
1389
|
-
|
|
1390
1388
|
"""Text format reader.
|
|
1391
1389
|
|
|
1392
1390
|
tok: the tokenizer.
|
|
@@ -24,18 +24,19 @@ import functools
|
|
|
24
24
|
import struct
|
|
25
25
|
from typing import Any, Callable, Dict, Iterable, Optional, Tuple, Union
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
import idna # type: ignore
|
|
29
|
-
|
|
30
|
-
have_idna_2008 = True
|
|
31
|
-
except ImportError: # pragma: no cover
|
|
32
|
-
have_idna_2008 = False
|
|
33
|
-
|
|
27
|
+
import dns._features
|
|
34
28
|
import dns.enum
|
|
35
29
|
import dns.exception
|
|
36
30
|
import dns.immutable
|
|
37
31
|
import dns.wire
|
|
38
32
|
|
|
33
|
+
if dns._features.have("idna"):
|
|
34
|
+
import idna # type: ignore
|
|
35
|
+
|
|
36
|
+
have_idna_2008 = True
|
|
37
|
+
else: # pragma: no cover
|
|
38
|
+
have_idna_2008 = False
|
|
39
|
+
|
|
39
40
|
CompressType = Dict["Name", int]
|
|
40
41
|
|
|
41
42
|
|
|
@@ -355,7 +356,6 @@ def _maybe_convert_to_binary(label: Union[bytes, str]) -> bytes:
|
|
|
355
356
|
|
|
356
357
|
@dns.immutable.immutable
|
|
357
358
|
class Name:
|
|
358
|
-
|
|
359
359
|
"""A DNS name.
|
|
360
360
|
|
|
361
361
|
The dns.name.Name class represents a DNS name as a tuple of
|
|
@@ -115,6 +115,7 @@ class Do53Nameserver(AddressAndPortNameserver):
|
|
|
115
115
|
raise_on_truncation=True,
|
|
116
116
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
117
117
|
ignore_trailing=ignore_trailing,
|
|
118
|
+
ignore_errors=True,
|
|
118
119
|
)
|
|
119
120
|
return response
|
|
120
121
|
|
|
@@ -153,6 +154,7 @@ class Do53Nameserver(AddressAndPortNameserver):
|
|
|
153
154
|
backend=backend,
|
|
154
155
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
155
156
|
ignore_trailing=ignore_trailing,
|
|
157
|
+
ignore_errors=True,
|
|
156
158
|
)
|
|
157
159
|
return response
|
|
158
160
|
|
|
@@ -163,11 +165,13 @@ class DoHNameserver(Nameserver):
|
|
|
163
165
|
url: str,
|
|
164
166
|
bootstrap_address: Optional[str] = None,
|
|
165
167
|
verify: Union[bool, str] = True,
|
|
168
|
+
want_get: bool = False,
|
|
166
169
|
):
|
|
167
170
|
super().__init__()
|
|
168
171
|
self.url = url
|
|
169
172
|
self.bootstrap_address = bootstrap_address
|
|
170
173
|
self.verify = verify
|
|
174
|
+
self.want_get = want_get
|
|
171
175
|
|
|
172
176
|
def kind(self):
|
|
173
177
|
return "DoH"
|
|
@@ -201,10 +205,13 @@ class DoHNameserver(Nameserver):
|
|
|
201
205
|
request,
|
|
202
206
|
self.url,
|
|
203
207
|
timeout=timeout,
|
|
208
|
+
source=source,
|
|
209
|
+
source_port=source_port,
|
|
204
210
|
bootstrap_address=self.bootstrap_address,
|
|
205
211
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
206
212
|
ignore_trailing=ignore_trailing,
|
|
207
213
|
verify=self.verify,
|
|
214
|
+
post=(not self.want_get),
|
|
208
215
|
)
|
|
209
216
|
|
|
210
217
|
async def async_query(
|
|
@@ -222,10 +229,13 @@ class DoHNameserver(Nameserver):
|
|
|
222
229
|
request,
|
|
223
230
|
self.url,
|
|
224
231
|
timeout=timeout,
|
|
232
|
+
source=source,
|
|
233
|
+
source_port=source_port,
|
|
225
234
|
bootstrap_address=self.bootstrap_address,
|
|
226
235
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
227
236
|
ignore_trailing=ignore_trailing,
|
|
228
237
|
verify=self.verify,
|
|
238
|
+
post=(not self.want_get),
|
|
229
239
|
)
|
|
230
240
|
|
|
231
241
|
|