async def udp( q: dns.message.Message, where: str, timeout: Optional[float] = None, port: int = 53, source: Optional[str] = None, source_port: int = 0, ignore_unexpected: bool = False, one_rr_per_rrset: bool = False, ignore_trailing: bool = False, raise_on_truncation: bool = False, sock: Optional[dns.asyncbackend.DatagramSocket] = None, backend: Optional[dns.asyncbackend.Backend] = None, ) -> dns.message.Message: """Return the response obtained after sending a query via UDP. *sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, the *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.udp()` for the documentation of the other parameters, exceptions, and return type of this method. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) af = dns.inet.af_for_address(where) destination = _lltuple((where, port), af) if sock: cm: contextlib.AbstractAsyncContextManager = NullContext(sock) else: if not backend: backend = dns.asyncbackend.get_default_backend() stuple = _source_tuple(af, source, source_port) if backend.datagram_connection_required(): dtuple = (where, port) else: dtuple = None cm = await backend.make_socket(af, socket.SOCK_DGRAM, 0, stuple, dtuple) async with cm as s: await send_udp(s, wire, destination, expiration) (r, received_time, _) = await receive_udp( s, destination, expiration, ignore_unexpected, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing, raise_on_truncation, ) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r
async def tls(q, where, timeout=None, port=853, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None, ssl_context=None, server_hostname=None): """Return the response obtained after sending a query via TLS. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tls()` for the documentation of the other parameters, exceptions, and return type of this method. """ # After 3.6 is no longer supported, this can use an AsyncExitStack. (begin_time, expiration) = _compute_times(timeout) if not sock: if ssl_context is None: ssl_context = ssl.create_default_context() if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname) else: s = sock try: timeout = _timeout(expiration) response = await tcp(q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend) end_time = time.time() response.time = end_time - begin_time return response finally: if not sock and s: await s.close()
async def tcp(q, where, timeout=None, port=53, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None): """Return the response obtained after sending a query via TCP. *sock*, a ``dns.asyncbacket.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided *where*, *port*, *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tcp()` for the documentation of the other parameters, exceptions, and return type of this method. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) s = None # After 3.6 is no longer supported, this can use an AsyncExitStack. try: if sock: # Verify that the socket is connected, as if it's not connected, # it's not writable, and the polling in send_tcp() will time out or # hang forever. await sock.getpeername() s = sock else: # These are simple (address, port) pairs, not # family-dependent tuples you pass to lowlevel socket # code. af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout) await send_tcp(s, wire, expiration) (r, received_time) = await receive_tcp(s, expiration, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r finally: if not sock and s: await s.close()
async def udp(q, where, timeout=None, port=53, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False, ignore_trailing=False, raise_on_truncation=False, sock=None, backend=None): """Return the response obtained after sending a query via UDP. *sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, the *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.udp()` for the documentation of the other parameters, exceptions, and return type of this method. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) s = None # After 3.6 is no longer supported, this can use an AsyncExitStack. try: af = dns.inet.af_for_address(where) destination = _lltuple((where, port), af) if sock: s = sock else: if not backend: backend = dns.asyncbackend.get_default_backend() stuple = _source_tuple(af, source, source_port) if backend.datagram_connection_required(): dtuple = (where, port) else: dtuple = None s = await backend.make_socket(af, socket.SOCK_DGRAM, 0, stuple, dtuple) await send_udp(s, wire, destination, expiration) (r, received_time, _) = await receive_udp(s, destination, expiration, ignore_unexpected, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing, raise_on_truncation) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r finally: if not sock and s: await s.close()
async def tcp( q: dns.message.Message, where: str, timeout: Optional[float] = None, port: int = 53, source: Optional[str] = None, source_port: int = 0, one_rr_per_rrset: bool = False, ignore_trailing: bool = False, sock: Optional[dns.asyncbackend.StreamSocket] = None, backend: Optional[dns.asyncbackend.Backend] = None, ) -> dns.message.Message: """Return the response obtained after sending a query via TCP. *sock*, a ``dns.asyncbacket.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided *where*, *port*, *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tcp()` for the documentation of the other parameters, exceptions, and return type of this method. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) if sock: # Verify that the socket is connected, as if it's not connected, # it's not writable, and the polling in send_tcp() will time out or # hang forever. await sock.getpeername() cm: contextlib.AbstractAsyncContextManager = NullContext(sock) else: # These are simple (address, port) pairs, not family-dependent tuples # you pass to low-level socket code. af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() cm = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout) async with cm as s: await send_tcp(s, wire, expiration) (r, received_time) = await receive_tcp(s, expiration, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r
async def inbound_xfr(where, txn_manager, query=None, port=53, timeout=None, lifetime=None, source=None, source_port=0, udp_mode=UDPMode.NEVER, backend=None): """Conduct an inbound transfer and apply it via a transaction from the txn_manager. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.inbound_xfr()` for the documentation of the other parameters, exceptions, and return type of this method. """ if query is None: (query, serial) = dns.xfr.make_query(txn_manager) rdtype = query.question[0].rdtype is_ixfr = rdtype == dns.rdatatype.IXFR origin = txn_manager.from_wire_origin() wire = query.to_wire() af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) (_, expiration) = _compute_times(lifetime) retry = True while retry: retry = False if is_ixfr and udp_mode != UDPMode.NEVER: sock_type = socket.SOCK_DGRAM is_udp = True else: sock_type = socket.SOCK_STREAM is_udp = False if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, sock_type, 0, stuple, dtuple, _timeout(expiration)) async with s: if is_udp: await s.sendto(wire, dtuple, _timeout(expiration)) else: tcpmsg = struct.pack("!H", len(wire)) + wire await s.sendall(tcpmsg, expiration) with dns.xfr.Inbound(txn_manager, rdtype, serial, is_udp) as inbound: done = False tsig_ctx = None while not done: (_, mexpiration) = _compute_times(timeout) if mexpiration is None or \ (expiration is not None and mexpiration > expiration): mexpiration = expiration if is_udp: destination = _lltuple((where, port), af) while True: timeout = _timeout(mexpiration) (rwire, from_address) = await s.recvfrom(65535, timeout) if _matches_destination(af, from_address, destination, True): break else: ldata = await _read_exactly(s, 2, mexpiration) (l, ) = struct.unpack("!H", ldata) rwire = await _read_exactly(s, l, mexpiration) is_ixfr = (rdtype == dns.rdatatype.IXFR) r = dns.message.from_wire(rwire, keyring=query.keyring, request_mac=query.mac, xfr=True, origin=origin, tsig_ctx=tsig_ctx, multi=(not is_udp), one_rr_per_rrset=is_ixfr) try: done = inbound.process_message(r) except dns.xfr.UseTCP: assert is_udp # should not happen if we used TCP! if udp_mode == UDPMode.ONLY: raise done = True retry = True udp_mode = UDPMode.NEVER continue tsig_ctx = r.tsig_ctx if not retry and query.keyring and not r.had_tsig: raise dns.exception.FormError("missing TSIG")
async def tls(q, where, timeout=None, port=853, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None, ssl_context=None, server_hostname=None): """Return the response obtained after sending a query via TLS. *q*, a ``dns.message.Message``, the query to send *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, an ``int``, the port send the message to. The default is 853. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. *ssl_context*, an ``ssl.SSLContext``, the context to use when establishing a TLS connection. If ``None``, the default, creates one with the default configuration. *server_hostname*, a ``str`` containing the server's hostname. The default is ``None``, which means that no hostname is known, and if an SSL context is created, hostname checking will be disabled. Returns a ``dns.message.Message``. """ # After 3.6 is no longer supported, this can use an AsyncExitStack. (begin_time, expiration) = _compute_times(timeout) if not sock: if ssl_context is None: ssl_context = ssl.create_default_context() if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname) else: s = sock try: timeout = _timeout(expiration) response = await tcp(q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend) end_time = time.time() response.time = end_time - begin_time return response finally: if not sock and s: await s.close()
async def tcp(q, where, timeout=None, port=53, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None): """Return the response obtained after sending a query via TCP. *q*, a ``dns.message.Message``, the query to send *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, an ``int``, the port send the message to. The default is 53. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *sock*, a ``dns.asyncbacket.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided *where*, *port*, *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. Returns a ``dns.message.Message``. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) s = None # After 3.6 is no longer supported, this can use an AsyncExitStack. try: if sock: # Verify that the socket is connected, as if it's not connected, # it's not writable, and the polling in send_tcp() will time out or # hang forever. await sock.getpeername() s = sock else: # These are simple (address, port) pairs, not # family-dependent tuples you pass to lowlevel socket # code. af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout) await send_tcp(s, wire, expiration) (r, received_time) = await receive_tcp(s, expiration, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r finally: if not sock and s: await s.close()
async def udp(q, where, timeout=None, port=53, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False, ignore_trailing=False, raise_on_truncation=False, sock=None, backend=None): """Return the response obtained after sending a query via UDP. *q*, a ``dns.message.Message``, the query to send *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, an ``int``, the port send the message to. The default is 53. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from unexpected sources. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *raise_on_truncation*, a ``bool``. If ``True``, raise an exception if the TC bit is set. *sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, the *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. Returns a ``dns.message.Message``. """ wire = q.to_wire() (begin_time, expiration) = _compute_times(timeout) s = None # After 3.6 is no longer supported, this can use an AsyncExitStack. try: af = dns.inet.af_for_address(where) destination = _lltuple((where, port), af) if sock: s = sock else: if not backend: backend = dns.asyncbackend.get_default_backend() stuple = _source_tuple(af, source, source_port) s = await backend.make_socket(af, socket.SOCK_DGRAM, 0, stuple) await send_udp(s, wire, destination, expiration) (r, received_time, _) = await receive_udp(s, destination, expiration, ignore_unexpected, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing, raise_on_truncation) r.time = received_time - begin_time if not q.is_response(r): raise BadResponse return r finally: if not sock and s: await s.close()
async def tls( q: dns.message.Message, where: str, timeout: Optional[float] = None, port: int = 853, source: Optional[str] = None, source_port: int = 0, one_rr_per_rrset: bool = False, ignore_trailing: bool = False, sock: Optional[dns.asyncbackend.StreamSocket] = None, backend: Optional[dns.asyncbackend.Backend] = None, ssl_context: Optional[ssl.SSLContext] = None, server_hostname: Optional[str] = None, ) -> dns.message.Message: """Return the response obtained after sending a query via TLS. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tls()` for the documentation of the other parameters, exceptions, and return type of this method. """ (begin_time, expiration) = _compute_times(timeout) if sock: cm: contextlib.AbstractAsyncContextManager = NullContext(sock) else: if ssl_context is None: # See the comment about ssl.create_default_context() in query.py ssl_context = ssl.create_default_context( ) # lgtm[py/insecure-protocol] ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() cm = await backend.make_socket( af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname, ) async with cm as s: timeout = _timeout(expiration) response = await tcp( q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend, ) end_time = time.time() response.time = end_time - begin_time return response