network
— DNS resolution utilities¶
This module uses dns
to handle DNS queries.
Changed in version 0.5.4: The module was completely rewritten in 0.5.4. The documented API stayed mostly the same though.
Configure the resolver¶
New in version 0.5.4: The whole thread-local resolver thing was added in 0.5.4. This includes the magic to re-configure the used resolver when a query fails.
The module uses a thread-local resolver instance. It can be accessed using
get_resolver()
. Re-read of the system-wide resolver configuration can be
forced by calling reconfigure_resolver()
. To configure a custom resolver
instance, use set_resolver()
.
By setting a custom resolver instance, the facilities which automatically reconfigure the resolver whenever DNS timeouts occur are disabled.
Note
Currently, there is no way to set a resolver per XMPP client. If such a way
is desired, feel free to open a bug against aioxmpp
. I cannot really
imagine such a situation, but if you encounter one, please let me know.
-
aioxmpp.network.
get_resolver
()[source]¶ Return the thread-local
dns.resolver.Resolver
instance used byaioxmpp
.
-
aioxmpp.network.
reconfigure_resolver
()[source]¶ Reset the resolver configured for this thread to a fresh instance. This essentially re-reads the system-wide resolver configuration.
If a custom resolver has been set using
set_resolver()
, the flag indicating that no automatic re-configuration shall take place is cleared.
-
aioxmpp.network.
set_resolver
(resolver)[source]¶ Replace the current thread-local resolver (which can be accessed using
get_resolver()
) with resolver.This also sets an internal flag which prohibits the automatic calling of
reconfigure_resolver()
fromrepeated_query()
. To re-allow automatic reconfiguration, callreconfigure_resolver()
.
Querying records¶
In addition to using the dns.resolver.Resolver
instance returned by
get_resolver()
, one can also use repeated_query()
. The latter takes
care of re-trying the query up to a configurable amount of times. It will also
automatically call reconfigure_resolver()
(unless a custom resolver has
been set) if a timeout occurs and switch to TCP if problems persist.
-
async
aioxmpp.network.
repeated_query
(qname, rdtype, nattempts=None, resolver=None, require_ad=False, executor=None)[source]¶ Repeatedly fire a DNS query until either the number of allowed attempts (nattempts) is exceeded or a non-error result is returned (NXDOMAIN is a non-error result).
If nattempts is
None
, it is set to 3 if resolver isNone
and to 2 otherwise. This way, no query is made without a possible change to a local parameter. (When using the thread-local resolver, it will be re-configured after the first failed query and after the second failed query, TCP is used. With a fixed resolver, TCP is used after the first failed query.)qname must be the (IDNA encoded, as
bytes
) name to query, rdtype the record type to query for. If resolver is notNone
, it must be a DNSPythondns.resolver.Resolver
instance; if it isNone
, the resolver obtained fromget_resolver()
is used.If require_ad is
True
, the peer resolver is asked to do DNSSEC validation and if the AD flag is missing in the response,ValueError
is raised. If require_ad isFalse
, the resolver is asked to do DNSSEC validation nevertheless, but missing validation (in contrast to failed validation) is not an error.Note
This function modifies the flags of the resolver instance, no matter if it uses the thread-local resolver instance or the resolver passed as an argument.
If the first query fails and resolver is
None
and the thread-local resolver has not been overridden withset_resolver()
,reconfigure_resolver()
is called and the query is re-attempted immediately.If the next query after reconfiguration of the resolver (if the preconditions for resolver reconfigurations are not met, this applies to the first failing query),
repeated_query()
switches to TCP.If no result is received before the number of allowed attempts is exceeded,
TimeoutError
is raised.Return the result set or
None
if the domain does not exist.This is a coroutine; the query is executed in an executor using the
asyncio.BaseEventLoop.run_in_executor()
of the current event loop. By default, the default executor provided by the event loop is used, but it can be overridden using the executor argument.If the used resolver raises
dns.resolver.NoNameservers
(semantically, that no nameserver was able to answer the request), this function suspects that DNSSEC validation failed, as responding with SERVFAIL is what unbound does. To test that case, a simple check is made: the query is repeated, but with a flag set which indicates that we would like to do the validation ourselves. If that query succeeds, we assume that the error is in fact due to DNSSEC validation failure and raiseValidationError
. Otherwise, the answer is discarded and theNoNameservers
exception is treated as normal timeout. If the exception re-occurs in the second query, it is re-raised, as it indicates a serious configuration problem.
SRV records¶
-
async
aioxmpp.network.
lookup_srv
(domain: bytes, service: str, transport: str = 'tcp', **kwargs)[source]¶ Query the DNS for SRV records describing how the given service over the given transport is implemented for the given domain. domain must be an IDNA-encoded
bytes
object; service must be a normalstr
.Keyword arguments are passed to
repeated_query()
.Return a list of tuples
(prio, weight, (hostname, port))
, where hostname is a IDNA-encodedbytes
object containing the hostname obtained from the SRV record. The other fields are also as obtained from the SRV records. The trailing dot is stripped from the hostname.If the DNS query returns an empty result,
None
is returned. If any of the found SRV records has the root zone (.
) as hostname, this indicates that the service is not available at the given domain andValueError
is raised.
-
aioxmpp.network.
group_and_order_srv_records
(all_records, rng=None)[source]¶ Order a list of SRV record information (as returned by
lookup_srv()
) and group and order them as specified by the RFC.Return an iterable, yielding each
(hostname, port)
tuple inside the SRV records in the order specified by the RFC. For hosts with the same priority, the given rng implementation is used (if none is given, therandom
module is used).