U
    d                     @   sj  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZmZmZmZ ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZdd Zdd ZdZdZ zddl!Z!ddl"Z!ddl#Z#e!j$Z%e!j&j'j(Z)d	Zz e#j*d	d

 d	Z W 5 Q R X W n e+k
rD   Y nX G dd de%Z,G dd de#j-Z.W n$ e/k
r   G dd dZ.Y nX eZ0zddl1Z1W n$ e/k
r   G dd dZ1Y nX ejZ2G dd dej3j4Z5G dd dej3j6Z7G dd dej3j4Z8G dd dej3j4Z9ej:j;Z;dd Z<dd Z=dd Z>e?ed rPej@aAnejBaAd!d" ZCd#d$ ZDd%d& ZEd'd( ZFded)d*ZGdfd+d,ZHdd-dddddd.d	dd	dejIfejJjKeLeeM eNeeL eNeOeOee eLeOeeL eeOeLf ed/ eeN ejJjKd0d1d2ZPd3d4 ZQd5d6 ZRdgeeejJjKeSf eeeM eeNeMf d7d8d9ZTdheee eeM eOeOeeejUjVejWjXf  eeS eOeOed;
d<d=ZYdiejJjKeLeeM eNeeL eNeOeOeOeOee ejJjKd?d@dAZZdjejJjKeLeeM eNeeL eNeOeOeOee ee eejJjKeOf dBdCdDZ[dEdF Z\dGdH Z]dkeeejJjKeSf eeM eeNeMf dIdJdKZ^dleeeM eOeeejUjVejWjXf  eeS eOeejJjKeMf dLdMdNZ_dOdP Z`dmejJjKeLeeM eNeeL eNeOeOee ejJjKdQ
dRdSZadTdU ZbdnejJjKeLeeM eNeeL eNeOeOee1jc ee1jd eeL ejJjKdWdXdYZedoejJjKeLeeM eNeeL eNeOeOeejfjg eeOeLf eeL ejJjKdZd[d\Zfejhjiejjjkdd>ddd	dddddejWjlfeLeejUjVeLf eejhjmeLf eejjjneLf eeM eNeeejUjVejWjXf  eeejUjVeLf  eOeeM eeL eNeNeOeejUjVeLf ed]d^d_Z:G d`da daejoZpdd>ddddepjqfeLejrjseejJjK eNeeM eeM eeL eNepddb
dcddZtdS )pzTalk to a DNS server.    N)AnyDictOptionalTupleUnionc                 C   s,   | d krd S | t    }|dkr(tjj|S )N        )timedns	exceptionTimeout)
expirationtimeout r   -/tmp/pip-unpacked-wheel-pk5slln3/dns/query.py
_remaining-   s    r   c                 C   s   |d krd S t t |  |S N)minr   )r   r   r   r   r   _expiration_for_this_attempt6   s    r   FT)http2c                       s0   e Zd Z fddZdddZd	ddZ  ZS )
_NetworkBackendc                    s&   t    || _|| _|| _|| _d S r   )super__init___local_port	_resolver_bootstrap_address_family)selfresolver
local_portbootstrap_addressfamily	__class__r   r   r   O   s
    
z_NetworkBackend.__init__Nc              	   C   s  g }t |\}}tj|r(|| nP| jd k	r@|| j n8t|}| j}	|r^tj|}	| j	j
||	|d}
|
 }|D ]}tj|}|d k	s| jdkrtj|| jf|}nd }t|tj|}td|}z(t|tj||f|| t|W   S  tk
r   Y q|X q|tjd S )N)r    lifetimer   g       @)_compute_timesr	   inet
is_addressappendr   r   r   af_for_addressr   resolve_name	addressesr   low_level_address_tuple_make_socketsocketSOCK_STREAMr   _connect_CoreSyncStream	ExceptionhttpcoreZConnectError)r   hostportr   local_addresssocket_optionsr*   _r   r    ZanswersaddressafsourcesockZattempt_expirationr   r   r   connect_tcpV   sH    
   
z_NetworkBackend.connect_tcpc                 C   s   t d S r   NotImplementedError)r   pathr   r6   r   r   r   connect_unix_socket}   s    z#_NetworkBackend.connect_unix_socket)N)N)__name__
__module____qualname__r   r<   r@   __classcell__r   r   r!   r   r   N   s
    
( r   c                       s*   e Zd Zdddejd fdd
Z  ZS )_HTTPTransportr   N)r   r   r   r    c                   s>   |d krdd l }|j }t j|| t||||| j_d S Nr   )Zdns.resolverr   Resolverr   r   r   _poolZ_network_backend)r   r   r   r   r    argskwargsr	   r!   r   r   r      s    	
   z_HTTPTransport.__init__)rA   rB   rC   r-   	AF_UNSPECr   rD   r   r   r!   r   rE      s
   rE   c                   @   s   e Zd Zdd ZdS )rE   c                 C   s   t d S r   r=   )r   r3   r4   r   r5   r   r   r   r<      s    z_HTTPTransport.connect_tcpN)rA   rB   rC   r<   r   r   r   r   rE      s   c                   @   sT   e Zd ZG dd deZG dd deZG dd dZG dd dZed	d
 Z	dS )sslc                   @   s   e Zd ZdS )zssl.WantReadExceptionNrA   rB   rC   r   r   r   r   WantReadException   s   rN   c                   @   s   e Zd ZdS )zssl.WantWriteExceptionNrM   r   r   r   r   WantWriteException   s   rO   c                   @   s   e Zd ZdS )zssl.SSLContextNrM   r   r   r   r   
SSLContext   s   rP   c                   @   s   e Zd ZdS )zssl.SSLSocketNrM   r   r   r   r   	SSLSocket   s   rQ   c                 O   s   t dd S )Nzno ssl support)r1   )clsrI   rJ   r   r   r   create_default_context   s    zssl.create_default_contextN)
rA   rB   rC   r1   rN   rO   rP   rQ   classmethodrS   r   r   r   r   rL      s   rL   c                   @   s   e Zd ZdZdS )UnexpectedSourcez=A DNS query response came from an unexpected address or port.NrA   rB   rC   __doc__r   r   r   r   rU      s   rU   c                   @   s   e Zd ZdZdS )BadResponsez<A DNS query response does not respond to the question asked.NrV   r   r   r   r   rX      s   rX   c                   @   s   e Zd ZdZdS )NoDOHzMDNS over HTTPS (DOH) was requested but the httpx module is not
    available.NrV   r   r   r   r   rY      s   rY   c                   @   s   e Zd ZdZdS )NoDOQzNDNS over QUIC (DOQ) was requested but the aioquic module is not
    available.NrV   r   r   r   r   rZ      s   rZ   c                 C   s(   t   }| d kr|d fS |||  fS d S r   )r   )r   nowr   r   r   r$      s    r$   c                 C   s   |r t | tjr |  dkr dS t }d}|r8|tjO }|rF|tjO }|rV|| | |d krdd }n|t		  }|dkrt
jj||st
jjd S )Nr   Tr   )
isinstancerL   rQ   pending_selector_class	selectors
EVENT_READEVENT_WRITEregisterr   r	   r
   r   select)fdreadablewritabler7   r   seleventsr   r   r   r   	_wait_for   s"    


ri   c                 C   s   | a d S r   )r^   )Zselector_classr   r   r   _set_selector_class   s    rj   PollSelectorc                 C   s   t | ddd| d S )NTFri   sr   r   r   r   _wait_for_readable  s    ro   c                 C   s   t | ddd| d S )NFTrl   rm   r   r   r   _wait_for_writable  s    rp   c                 C   sd   z(t j| |d }t j| |d }W n t jjk
rB   Y dS X ||kob|dd  |dd  kS )Nr   F   )r	   r%   	inet_ptonr
   SyntaxError)r9   Za1Za2Zn1Zn2r   r   r   _addresses_equal  s    rt   c                 C   s`   |sdS t | ||s<tj|d r@|dd  |dd  kr@dS |rHdS td| d| d S )NTr   rq   Fzgot a response from z instead of )rt   r	   r%   is_multicastrU   )r9   from_addressdestinationignore_unexpectedr   r   r   _matches_destination  s    ry   c                 C   s   d }d }zt j| }| }W n tk
r6   |r2 Y nX |rbt j|}|r^||krbtdn|}|r|szt j|}W n tk
r   tdY nX |rt j||f|}|rt j||f|}|||fS )Nz5different address families for source and destinationz3source_port specified but address family is unknown)r	   r%   r(   r1   
ValueErrorZ
any_for_afr+   )wherer4   r:   source_portZwhere_must_be_addressr9   rw   Zsafr   r   r   _destination_and_source,  s4    r}   c                 C   sj   t | |}z<|d |d k	r(|| |r>|j|d|dW S |W S W n tk
rd   |   Y nX d S )NF)do_handshake_on_connectserver_hostname)socket_factorysetblockingbindwrap_socketr1   close)r9   typer:   ssl_contextr   rn   r   r   r   r,   X  s    



r,   i  z
/dns-queryzdns.resolver.Resolver)qr{   r   r4   r:   r|   one_rr_per_rrsetignore_trailingsessionr?   postr   verifyr   r    returnc              
   C   s  t st|r t|tjs td|  }t||||d\}}}d}ddi}|dk	rtj	
|r|tjkrxd|||	}q|tjkrd|||	}n|}|dkrd}d}n|d }|d	 }t|d
t|||||d}|rt|}ntjd
t||d}|f}|
r*|dtt|d |j||||d}n.t|d}| }|j|||d|id}W 5 Q R X |jdk sz|jdkrtd||j|jtjj|j| j | j!||d}|j"# |_$| %|st&|S )a  Return the response obtained after sending a query via DNS-over-HTTPS.

    *q*, a ``dns.message.Message``, the query to send.

    *where*, a ``str``, the nameserver IP address or the full URL. If an IP address is
    given, the URL will be constructed using the following schema:
    https://<IP-address>:<port>/<path>.

    *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query
    times out. If ``None``, the default, wait forever.

    *port*, a ``int``, the port to send the query to. The default is 443.

    *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.

    *session*, an ``httpx.Client``.  If provided, the client session to use to send the
    queries.

    *path*, a ``str``. If *where* is an IP address, then *path* will be used to
    construct the URL to send the DNS query to.

    *post*, a ``bool``. If ``True``, the default, POST method will be used.

    *bootstrap_address*, a ``str``, the IP address to use to bypass resolution.

    *verify*, a ``bool`` or ``str``.  If a ``True``, then TLS certificate verification
    of the server is done using the default CA bundle; if ``False``, then no
    verification is done; if a `str` then it specifies the path to a certificate file or
    directory which will be used for verification.

    *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use for
    resolution of hostnames in URLs.  If not specified, a new resolver with a default
    configuration will be used; note this is *not* the default resolver as that resolver
    might have been configured to use DoH causing a chicken-and-egg problem.  This
    parameter only has an effect if the HTTP library is httpx.

    *family*, an ``int``, the address family.  If socket.AF_UNSPEC (the default), both A
    and AAAA records will be retrieved.

    Returns a ``dns.message.Message``.
    z)session parameter must be an httpx.ClientFNacceptzapplication/dns-messagezhttps://{}:{}{}zhttps://[{}]:{}{}r   rq   T)r5   http1r   r   r   r   r   r    )r   r   r   	transport)zcontent-typezcontent-length)headerscontentr      =r	   )r   r   params   i+  z2{} responded with status code {}
Response body: {}keyringrequest_macr   r   )'have_dohrY   r\   httpxClientrz   to_wirer}   r	   r%   r&   r-   AF_INETformatAF_INET6rE   _have_http2
contextlibnullcontextupdatestrlenr   base64urlsafe_b64encoderstripdecodegetstatus_coder   message	from_wirer   r   elapsedtotal_secondsr   is_responserX   )r   r{   r   r4   r:   r|   r   r   r   r?   r   r   r   r   r    wirer9   r7   Z
the_sourcer   r   urlr5   r   cmresponseZtwirerr   r   r   httpsl  s    D    


   
     r   c                 C   s2   z|  |W S  tk
r*   t| | Y q X q dS )zReads a datagram from the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    N)recvfromBlockingIOErrorro   )r;   max_sizer   r   r   r   	_udp_recv  s    r   c                 C   sH   z"|r|  ||W S | |W S W q  tk
r@   t| | Y q X q dS )zSends the specified datagram to destination over the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    N)sendtosendr   rp   )r;   datarw   r   r   r   r   	_udp_send  s    r   )r;   whatrw   r   r   c                 C   s4   t |tjjr| }t }t| |||}||fS )a  Send a DNS message to the specified UDP socket.

    *sock*, a ``socket``.

    *what*, a ``bytes`` or ``dns.message.Message``, the message to send.

    *destination*, a destination tuple appropriate for the address family
    of the socket, specifying where to send the query.

    *expiration*, a ``float`` or ``None``, the absolute time at which
    a timeout exception should be raised.  If ``None``, no timeout will
    occur.

    Returns an ``(int, float)`` tuple of bytes sent and the sent time.
    )r\   r	   r   Messager   r   r   )r;   r   rw   r   	sent_timenr   r   r   send_udp  s
    r       )
r;   rw   r   rx   r   r   r   r   raise_on_truncationr   c	                 C   sb   d}	t | d|\}	}
t| j|
||rq(qt }tjj|	|||||d}|rT||fS |||
fS dS )a  Read a DNS message from a UDP socket.

    *sock*, a ``socket``.

    *destination*, a destination tuple appropriate for the address family
    of the socket, specifying where the message is expected to arrive from.
    When receiving a response, this would be where the associated query was
    sent.

    *expiration*, a ``float`` or ``None``, the absolute time at which
    a timeout exception should be raised.  If ``None``, no timeout will
    occur.

    *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.

    *keyring*, a ``dict``, the keyring to use for TSIG.

    *request_mac*, a ``bytes`` or ``None``, the MAC of the request (for TSIG).

    *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.

    Raises if the message is malformed, if network errors occur, of if
    there is a timeout.

    If *destination* is not ``None``, returns a ``(dns.message.Message, float)``
    tuple of the received message and the received time.

    If *destination* is ``None``, returns a
    ``(dns.message.Message, float, tuple)``
    tuple of the received message, the received time, and the address where
    the message arrived from.
    r     )r   r   r   r   r   N)r   ry   r    r   r	   r   r   )r;   rw   r   rx   r   r   r   r   r   r   rv   received_timer   r   r   r   receive_udp:  s*    4   r   5   )r   r{   r   r4   r:   r|   rx   r   r   r   r;   r   c                 C   s   |   }t||||\}}}t|\}}|
r8t|
}nt|tj|}|X}t|||| t	|||||| j
| j||		\}}|| |_| |st|W  5 Q R  S Q R X dstdS )aL  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 ``socket.socket``, 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 nonblocking datagram socket,
    and the *source* and *source_port* are ignored.

    Returns a ``dns.message.Message``.
    FN)r   r}   r$   r   r   r,   r-   
SOCK_DGRAMr   r   r   macr   r   rX   AssertionError)r   r{   r   r4   r:   r|   rx   r   r   r   r;   r   r9   rw   
begin_timer   r   rn   r   r   r   r   r   udp  s<    3   


r   )r   r{   r   r4   r:   r|   rx   r   r   udp_socktcp_sockr   c                 C   sd   z&t | ||||||||d|	}|dfW S  tjjk
r^   t| ||||||||
	}|df Y S X dS )a  Return the response to the query, trying UDP first and falling back
    to TCP if UDP results in a truncated response.

    *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.

    *udp_sock*, a ``socket.socket``, or ``None``, the socket to use for the
    UDP query.  If ``None``, the default, a socket is created.  Note that
    if a socket is provided, it must be a nonblocking datagram socket,
    and the *source* and *source_port* are ignored for the UDP query.

    *tcp_sock*, a ``socket.socket``, or ``None``, the connected socket to use for the
    TCP query.  If ``None``, the default, a socket is created.  Note that
    if a socket is provided, it must be a nonblocking connected stream
    socket, and *where*, *source* and *source_port* are ignored for the TCP
    query.

    Returns a (``dns.message.Message``, tcp) tuple where tcp is ``True``
    if and only if TCP was used.
    TFN)r   r	   r   Z	Truncatedtcp)r   r{   r   r4   r:   r|   rx   r   r   r   r   r   r   r   r   udp_with_fallback  s8    7
r   c              	   C   s   d}|dkrz.|  |}|dkr$t|t|8 }||7 }W q ttjfk
r^   t| | Y q tjk
r|   t| | Y qX q|S )zRead the specified number of bytes from sock.  Keep trying until we
    either get the desired amount, or we hit EOF.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    r   r   )	recvEOFErrorr   r   rL   SSLWantReadErrorro   SSLWantWriteErrorrp   )r;   countr   rn   r   r   r   r   	_net_read+  s    
r   c              	   C   sx   d}t |}||k rtz|| ||d 7 }W q ttjfk
rR   t| | Y q tjk
rp   t| | Y qX qdS )zWrite the specified data to the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    r   N)r   r   r   rL   r   rp   r   ro   )r;   r   r   currentlr   r   r   
_net_write@  s    r   )r;   r   r   r   c                 C   sT   t |tjjr| }n|}t|}td|| }t }t	| || t||fS )a{  Send a DNS message to the specified TCP socket.

    *sock*, a ``socket``.

    *what*, a ``bytes`` or ``dns.message.Message``, the message to send.

    *expiration*, a ``float`` or ``None``, the absolute time at which
    a timeout exception should be raised.  If ``None``, no timeout will
    occur.

    Returns an ``(int, float)`` tuple of bytes sent and the sent time.
    !H)
r\   r	   r   r   r   r   structpackr   r   )r;   r   r   r   r   tcpmsgr   r   r   r   send_tcpP  s    
r   )r;   r   r   r   r   r   r   c                 C   sL   t | d|}td|\}t | ||}t }	tjj|||||d}
|
|	fS )a  Read a DNS message from a TCP socket.

    *sock*, a ``socket``.

    *expiration*, a ``float`` or ``None``, the absolute time at which
    a timeout exception should be raised.  If ``None``, no timeout will
    occur.

    *one_rr_per_rrset*, a ``bool``.  If ``True``, put each RR into its own
    RRset.

    *keyring*, a ``dict``, the keyring to use for TSIG.

    *request_mac*, a ``bytes`` or ``None``, the MAC of the request (for TSIG).

    *ignore_trailing*, a ``bool``.  If ``True``, ignore trailing
    junk at end of the received message.

    Raises if the message is malformed, if network errors occur, of if
    there is a timeout.

    Returns a ``(dns.message.Message, float)`` tuple of the received message
    and the received time.
       r   r   )r   r   unpackr   r	   r   r   )r;   r   r   r   r   r   ldatar   r   r   r   r   r   r   receive_tcpp  s    !r   c                 C   s`   |  |}|dkrd S |tjtjtjfkrDt| | | tjtj	}|dkr\t
|t|d S rF   )
connect_exerrnoZEINPROGRESSEWOULDBLOCKZEALREADYrp   
getsockoptr-   
SOL_SOCKETSO_ERROROSErrorosstrerror)rn   r8   r   errr   r   r   r/     s    

r/   )
r   r{   r   r4   r:   r|   r   r   r;   r   c	              
   C   s   |   }	t|\}
}|r$t|}n"t||||\}}}t|tj|}|`}|s\t||| t	||	| t
|||| j| j|\}}||
 |_| |st|W  5 Q R  S Q R X dstdS )a  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 ``socket.socket``, or ``None``, the connected 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 nonblocking connected stream
    socket, and *where*, *port*, *source* and *source_port* are ignored.

    Returns a ``dns.message.Message``.
    FN)r   r$   r   r   r}   r,   r-   r.   r/   r   r   r   r   r   r   rX   r   )r   r{   r   r4   r:   r|   r   r   r;   r   r   r   r   r9   rw   rn   r   r   r   r   r   r     s:    +   
     

r   c                 C   sT   z|    W d S  tjk
r.   t| | Y q  tjk
rL   t| | Y q X q d S r   )do_handshakerL   r   ro   r   rp   rm   r   r   r   _tls_handshake  s    r   U  )r   r{   r   r4   r:   r|   r   r   r;   r   r   r   c              
   C   s   |rt | ||||||||	S |  }t|\}}t||||\}}}|	dkrp|spt }	tjj|	_|
dkrpd|	_	t
|tj||	|
df}t||| t|| t||| t|||| j| j|\}}|| |_| |st|W  5 Q R  S Q R X dstdS )a:  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 ``ssl.SSLSocket``, 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 nonblocking connected
    SSL stream socket, and *where*, *port*, *source*, *source_port*,
    and *ssl_context* are ignored.

    *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``.

    NF)r   r   )r   r   r$   r}   rL   rS   
TLSVersionTLSv1_2minimum_versioncheck_hostnamer,   r-   r.   r/   r   r   r   r   r   r   r   rX   r   )r   r{   r   r4   r:   r|   r   r   r;   r   r   r   r   r   r9   rw   rn   r   r   r   r   r   tls  sd    7   


     

r   )r   r{   r   r4   r:   r|   r   r   
connectionr   r   r   c              
   C   s   t jjstdd| _|  }|r2td}|}nt jj|	|
d}|}|^ |s`|	||||}t
|\}}|| }||d |t|}W 5 Q R X t }W 5 Q R X t jj|| j| j||d}t|| d|_| |st|S )a  Return the response obtained after sending a query via DNS-over-QUIC.

    *q*, a ``dns.message.Message``, the query to send.

    *where*, a ``str``, the nameserver IP address.

    *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query
    times out. If ``None``, the default, wait forever.

    *port*, a ``int``, the port to send the query 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.

    *connection*, a ``dns.quic.SyncQuicConnection``.  If provided, the
    connection to use to send the query.

    *verify*, a ``bool`` or ``str``.  If a ``True``, then TLS certificate verification
    of the server is done using the default CA bundle; if ``False``, then no
    verification is done; if a `str` then it specifies the path to a certificate file or
    directory which will be used for verification.

    *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``.
    zDNS-over-QUIC is not available.r   N)verify_modeZserver_nameTr   r   )r	   quicZ	have_quicrZ   idr   r   r   ZSyncQuicManagerconnectr$   Zmake_streamr   Zreceiver   r   r   r   r   r   maxr   rX   )r   r{   r   r4   r:   r|   r   r   r   r   r   r   managerZthe_connectionZthe_managerstartr   streamfinishr   r   r   r   r   a  s>    2
 
r   )r{   zonerdtyperdclassr   r4   r   keyname
relativizer#   r:   r|   serialuse_udpkeyalgorithmr   c           '      c   s  t |trtj|}tjj|}tj	|||}|tjj
krdtj|dddd| }|j| |dk	r||j|||d | }t| ||
|\}}}
|r|tjj
krtd|rtjntj}t|||
}t|	\}}t||| t|}|rt||d| ntd|| }t||| d	}d
}d	}d}|rF|}tjj}nd}|}d} |st|\}}!|!dks|dk	r|!|kr|}!|rt|d|!\}}n&t|d|!}"t d|"\}t|||!}|tjj
k}#tjj!||j"|j#d
|| d
|#d}$|$$ }%|%tj$j%krt&|%|$j'} d}&|dkr|$j(r<|$j(d j|krHtj)*d|$j(d }|j+tjj,krntj)*dd}&|- }|tjj
krtj./|d j.|krd
}nd
}|$j(|&d D ]}|rtj)*d|j+tjj,krX|j|krX|r|d j.|krtj)*dd	}n|tjj
kr&| }||krj|tjj0ksR|tjj
krj|rjd
}n|rtjj0}d	}q|r|j"r|$j1stj)*d|$V  qRW 5 Q R X dS )a  Return a generator for the responses to a zone transfer.

    *where*, a ``str`` containing an IPv4 or IPv6 address,  where
    to send the message.

    *zone*, a ``dns.name.Name`` or ``str``, the name of the zone to transfer.

    *rdtype*, an ``int`` or ``str``, the type of zone transfer.  The
    default is ``dns.rdatatype.AXFR``.  ``dns.rdatatype.IXFR`` can be
    used to do an incremental transfer instead.

    *rdclass*, an ``int`` or ``str``, the class of the zone transfer.
    The default is ``dns.rdataclass.IN``.

    *timeout*, a ``float``, the number of seconds to wait for each
    response message.  If None, the default, wait forever.

    *port*, an ``int``, the port send the message to.  The default is 53.

    *keyring*, a ``dict``, the keyring to use for TSIG.

    *keyname*, a ``dns.name.Name`` or ``str``, the name of the TSIG
    key to use.

    *relativize*, a ``bool``.  If ``True``, all names in the zone will be
    relativized to the zone origin.  It is essential that the
    relativize setting matches the one specified to
    ``dns.zone.from_xfr()`` if using this generator to make a zone.

    *lifetime*, a ``float``, the total number of seconds to spend
    doing the transfer.  If ``None``, the default, then there is no
    limit on the time the transfer may take.

    *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.

    *serial*, an ``int``, the SOA serial number to use as the base for
    an IXFR diff sequence (only meaningful if *rdtype* is
    ``dns.rdatatype.IXFR``).

    *use_udp*, a ``bool``.  If ``True``, use UDP (only meaningful for IXFR).

    *keyalgorithm*, a ``dns.name.Name`` or ``str``, the TSIG algorithm to use.

    Raises on errors, and so does the generator.

    Returns a generator of ``dns.message.Message`` objects.
    r   INSOAz. . %u 0 0 0 0N)	algorithmzcannot do a UDP AXFRr   FTr   r   r   r   xfrorigintsig_ctxZmultir   z No answer or RRset not for qnamezfirst RRset is not an SOArq   zanswers after final SOAzIXFR base serial mismatchmissing TSIG)2r\   r   r	   nameZ	from_text	rdatatype	RdataTypemaker   
make_queryIXFRrrset	authorityr'   Zuse_tsigr   r}   rz   r-   r   r.   r,   r$   r/   r   r   r   r   r   emptyr   r   r   r   r   r   rcodeZNOERRORTransferErrorr  Zanswerr
   	FormErrorr  r
  copyr  ZSerialAXFRhad_tsig)'r{   r  r  r  r   r4   r   r  r  r#   r:   r|   r  r  r  r   r  r   r9   rw   	sock_typern   r7   r   r   r   doneZdelete_modeZexpecting_SOAZ	soa_rrsetr  Zonamer  mexpirationr   is_ixfrr   r  Zanswer_indexr   r   r   r    s    E
   








r  c                   @   s   e Zd ZdZdZdZdZdS )UDPModea  How should UDP be used in an IXFR from :py:func:`inbound_xfr()`?

    NEVER means "never use UDP; always use TCP"
    TRY_FIRST means "try to use UDP but fall back to TCP if needed"
    ONLY means "raise ``dns.xfr.UseTCP`` if trying UDP does not succeed"
    r   rq   r   N)rA   rB   rC   rW   NEVERZ	TRY_FIRSTONLYr   r   r   r   r$  r  s   r$  )
r{   txn_managerqueryr4   r   r#   r:   r|   udp_moder   c	                 C   s>  |dkrt j|\}}	nt j|}	|jd j}
|
t jjk}| }|	 }t
| |||\}}}t|\}}d}|r:d}|r|tjkrtj}d}n
tj}d}t|||}t||| |rt||d| n tdt|| }t||| t j||
|	|$}d}d}|st|\}}|dks>|dk	rB||krB|}|rZt|d|\}}n&t|d|}td|\}t|||}t jj||j|jd||| |d}z| |}W nF t jj!k
r   |st"|tj#krނ d}d}tj}Y qY nX |j$}q|s$|jr$|j%s$t j&'d	W 5 Q R X W 5 Q R X qrdS )
a  Conduct an inbound transfer and apply it via a transaction from the
    txn_manager.

    *where*, a ``str`` containing an IPv4 or IPv6 address,  where
    to send the message.

    *txn_manager*, a ``dns.transaction.TransactionManager``, the txn_manager
    for this transfer (typically a ``dns.zone.Zone``).

    *query*, the query to send.  If not supplied, a default query is
    constructed using information from the *txn_manager*.

    *port*, an ``int``, the port send the message to.  The default is 53.

    *timeout*, a ``float``, the number of seconds to wait for each
    response message.  If None, the default, wait forever.

    *lifetime*, a ``float``, the total number of seconds to spend
    doing the transfer.  If ``None``, the default, then there is no
    limit on the time the transfer may take.

    *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.

    *udp_mode*, a ``dns.query.UDPMode``, determines how UDP is used
    for IXFRs.  The default is ``dns.UDPMode.NEVER``, i.e. only use
    TCP.  Other possibilities are ``dns.UDPMode.TRY_FIRST``, which
    means "try UDP but fallback to TCP if needed", and
    ``dns.UDPMode.ONLY``, which means "try UDP and raise
    ``dns.xfr.UseTCP`` if it does not succeed.

    Raises on errors.
    Nr   TFr   r   r   r  r  )(r	   r  r  Zextract_serial_from_queryZquestionr  r  r  Zfrom_wire_originr   r}   r$   r$  r%  r-   r   r.   r,   r/   r   r   r   r   r   ZInboundr   r   r   r   r   r   r   Zprocess_messageZUseTCPr   r&  r  r  r
   r  )r{   r'  r(  r4   r   r#   r:   r|   r)  r  r  r#  r  r   r9   rw   r7   r   retryr   Zis_udprn   r   Zinboundr!  r  r"  Zrwirer   r   r   r   r   r   inbound_xfr  s    /   




r+  )T)NN)N)NNFFNr   FF)	Nr   Nr   FFFFN)	Nr   Nr   FFFNN)N)NFNr   F)Nr   Nr   FFN)	Nr   Nr   FFNNN)	Nr   Nr   FFNTN)urW   r   r   enumr   r   r_   r-   r   r   typingr   r   r   r   r   Zdns.exceptionr	   Zdns.inetZdns.messageZdns.nameZdns.quicZ	dns.rcodeZdns.rdataclassZdns.rdatatypeZ
dns.serialZdns.transactionZdns.tsigZdns.xfrr   r   Z_have_httpxr   r2   Zhttpcore._backends.syncr   ZNetworkBackendZ_CoreNetworkBackendZ	_backendssyncZ
SyncStreamr0   r   r1   r   ZHTTPTransportrE   ImportErrorr   rL   r   r
   ZDNSExceptionrU   r  rX   rY   rZ   r  r  r$   ri   rj   hasattrrk   r^   SelectSelectorro   rp   rt   ry   r}   r,   rK   r   r   r   floatintboolr   r   r   bytesr   r  NameZtsigZKeyr   r   r   r   r   r   r   r/   r   r   rQ   rP   r   r   ZSyncQuicConnectionr  r  Z
rdataclassr	  Zdefault_algorithmr  Z
RdataClassIntEnumr$  r%  ZtransactionZTransactionManagerr+  r   r   r   r   <module>   sx  	
4 
,

  
        M         U         U 
"     /       D         k         

Z ;
