a
    PҚh                     @   s  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
Z
ddlZddlZddlmZ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l"Zdd Z#dd Z$ej%&dZ'e'rRddl(Z)ddl*Z*e)j+Z,e)j-j.j/Z0G d	d
 d
e,Z1G dd de*j2Z3nG dd dZ3e'Z4zddl5Z5W n" e6y   G dd dZ5Y n0 e	j	Z7G dd dej8j9Z:G dd dej8j;Z<G dd dej8j9Z=G dd dej8j9Z>ej?j@Z@dd ZAdd ZBdd ZCdd ZDd d! ZEd"d# ZFdvd%d&ZGdwd'd(ZHed) d)d*d+d,ZIG d-d. d.ejJZKdd/ddd0d0dd1d$dd$de	jLeKjMfejNjOePeeQ eReeP eReSeSee ePeSeeP eeSePf ed) eReKejNjOd2d3d4ZTejUjVeWeWd5d6d7ZXejUjVePeWdd8d9d:ZYdxejNjOePePeeQ eReeP eReSeSeeSePf eeP eSejNjOd<d=d>ZZd?d@ Z[dAdB Z\dyeeejNjOeWf eeeQ eeReQf dCdDdEZ]dzeee eeQ eSeSeeej^j_ej`jaf  eeW eSeSeSeejNjO edGdHdIZbd{ejNjOePeeQ eReeP eReSeSeSeSee eSejNjOdKdLdMZcd|ejNjOePeeQ eReeP eReSeSeSee ee eSeejNjOeSf dNdOdPZddQdR ZedSdT Zfd}eeejNjOeWf eeQ eeReQf dUdVdWZgd~eeeQ eSeeej^j_ej`jaf  eeW eSeejNjOeQf dXdYdZZhd[d\ ZidejNjOePeeQ eReeP eReSeSee ejNjOd]
d^d_Zjd`da ZkeeP eeSePf e5jldbdcddZmdejNjOePeeQ eReeP eReSeSee5jn ee5jl eeP eeSePf ejNjOdedfdgZodejNjOePeeQ eReeP eReSeSeejUjp eeSePf eeP eeP ejNjOdhdidjZUG dkdl dlejJZqejrjse	j	ejNjOeeR eeQ eQedmdndoZtejujvejwjxddJddd$ddddd0ej`jyfePeej^j_ePf eejujzePf eejwj{ePf eeQ eReeej^j_ej`jaf  eeej^j_ePf  eSeeQ eeP eReReSeej^j_ePf edpdqdrZ?ddJddddeqj|fePejrjseejNjO eReeQ eeQ eeP eReqdds
dtduZ}dS )zTalk to a DNS server.    N)AnyDictOptionalTupleUnioncastc                 C   s,   | d u rd S | t    }|dkr(tjj|S )N        )timedns	exceptionTimeout)
expirationtimeout r   D/wd/webapps/venvs/v2025_4um/lib/python3.9/site-packages/dns/query.py
_remaining1   s    r   c                 C   s   |d u rd S t t |  |S N)minr	   )r   r   r   r   r   _expiration_for_this_attempt:   s    r   Zdohc                       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   I   s
    
z_NetworkBackend.__init__Nc              	   C   s  g }t |\}}tj|r(|| nP| jd ur@|| j n8t|}| j}	|r^tj|}	| j	j
||	|d}
|
 }|D ]}tj|}|d us| jdkrtj|| jf|}nd }t|tj|}td|}z(t|tj||f|| t|W   S  ty   Y q|0 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    answersaddressafsourcesockZattempt_expirationr   r   r   connect_tcpP   sB    


z_NetworkBackend.connect_tcpc                 C   s   t d S r   NotImplementedError)r   pathr   r6   r   r   r   connect_unix_socketw   s    z#_NetworkBackend.connect_unix_socket)N)N)__name__
__module____qualname__r   r=   rA   __classcell__r   r   r!   r   r   H   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                   sJ   |d u r"|d u r"dd l }|j }t j|i | t||||| j_d S Nr   )dns.resolverr   Resolverr   r   r   _poolZ_network_backend)r   r   r   r   r    argskwargsr
   r!   r   r   r   }   s    	
z_HTTPTransport.__init__)rB   rC   rD   r-   	AF_UNSPECr   rE   r   r   r!   r   rF   |   s
   rF   c                   @   s   e Zd Zdd ZdS )rF   c                 C   s   t d S r   r>   )r   r3   r4   r   r5   r   r   r   r=      s    z_HTTPTransport.connect_tcpN)rB   rC   rD   r=   r   r   r   r   rF      s   c                   @   sX   e Zd 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 )sslr   c                   @   s   e Zd ZdS )zssl.WantReadExceptionNrB   rC   rD   r   r   r   r   WantReadException   s   rP   c                   @   s   e Zd ZdS )zssl.WantWriteExceptionNrO   r   r   r   r   WantWriteException   s   rQ   c                   @   s   e Zd ZdS )zssl.SSLContextNrO   r   r   r   r   
SSLContext   s   rR   c                   @   s   e Zd ZdS )zssl.SSLSocketNrO   r   r   r   r   	SSLSocket   s   rS   c                 O   s   t dd S )Nzno ssl support)r1   )clsrK   rL   r   r   r   create_default_context   s    zssl.create_default_contextN)rB   rC   rD   	CERT_NONEr1   rP   rQ   rR   rS   classmethodrU   r   r   r   r   rN      s   rN   c                   @   s   e Zd ZdZdS )UnexpectedSourcez=A DNS query response came from an unexpected address or port.NrB   rC   rD   __doc__r   r   r   r   rX      s   rX   c                   @   s   e Zd ZdZdS )BadResponsez<A DNS query response does not respond to the question asked.NrY   r   r   r   r   r[      s   r[   c                   @   s   e Zd ZdZdS )NoDOHzMDNS over HTTPS (DOH) was requested but the httpx module is not
    available.NrY   r   r   r   r   r\      s   r\   c                   @   s   e Zd ZdZdS )NoDOQzNDNS over QUIC (DOQ) was requested but the aioquic module is not
    available.NrY   r   r   r   r   r]      s   r]   c                 C   s(   t   }| d u 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}|r:|tjO }|rH|tjO }|rX|| | |d u rfd }n|t		  }|dkrt
jj||st
jjd S )Nr   Tr   )
isinstancerN   rS   pending	selectorsDefaultSelector
EVENT_READEVENT_WRITEregisterr	   r
   r   r   select)fdreadablewritabler7   r   seleventsr   r   r   r   	_wait_for   s"    


rl   c                 C   s   t | ddd| d S )NTFrl   sr   r   r   r   _wait_for_readable   s    rp   c                 C   s   t | ddd| d S )NFTrm   rn   r   r   r   _wait_for_writable   s    rq   c                 C   sb   z(t j| |d }t j| |d }W n t jjy@   Y dS 0 ||ko`|dd  |dd  kS )Nr   F   )r
   r%   	inet_ptonr   SyntaxError)r:   Za1Za2Zn1Zn2r   r   r   _addresses_equal   s    ru   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   rr   Fzgot a response from z instead of )ru   r
   r%   is_multicastrX   )r:   from_addressdestinationignore_unexpectedr   r   r   _matches_destination  s    rz   Tc                 C   s   d }d }zt j| }| }W n ty4   |r0 Y n0 |r`t j|}|r\||kr`tdn|}|r|szt j|}W n ty   tdY n0 |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_addressr:   rx   Zsafr   r   r   _destination_and_source  s4    r~   c                 C   sh   t | |}z<|d |d ur(|| |r>|j|d|dW S |W S W n tyb   |   Y n0 d S )NF)do_handshake_on_connectserver_hostname)socket_factorysetblockingbindwrap_socketr1   close)r:   typer;   ssl_contextr   ro   r   r   r   r,   @  s    



r,   zdns.resolver.Resolver)r   returnc                 C   s   | d u rdd l }|j } | S rG   )rH   r   rI   )r   r
   r   r   r   _maybe_get_resolverT  s    
r   c                   @   s,   e Zd ZdZdZdZdZdZdZdZ	dZ
dS )HTTPVersionzWhich version of HTTP should be used?

    DEFAULT will select the first version from the list [2, 1.1, 3] that
    is available.
    r   rr         N)rB   rC   rD   rZ   DEFAULTZHTTP_1H1ZHTTP_2H2ZHTTP_3H3r   r   r   r   r   b  s   r   i  Fz
/dns-query)qr|   r   r4   r;   r}   one_rr_per_rrsetignore_trailingsessionr@   postr   verifyr   r    http_versionr   c           "      C   s  t ||||d\}}}|durjtj|rj|tjkrJd| d| |	 }qn|tjkrnd| d| |	 }n|}i }|du rtj	|}|j
du rtdtj|j
r|j
}|j
|d< |jdur|j}|tjks|tjkrBtsB|du r$t|}|j
dusJ ||j
|}tt| }t| ||||||||||
d	S tsLt|rht|tjshtd
|  }ddi}|tjtjfv }|tjtjfv }|du rd}d}n|d }|d }|rt |}n*t!||||||||d}tj||||d}|t}|
r2|"dt#t$|d |j%|||||d}n0t&'|(d}|) } |j*|||d| i|d}W d   n1 sx0    Y  |j+dk s|j+dkrt| d|j+ d|j, tj-j.|j,| j/| j0||d}!|j12 |!_3| 4|!st5|!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.

    *http_version*, a ``dns.query.HTTPVersion``, indicating which HTTP version to use.

    Returns a ``dns.message.Message``.
    FNzhttps://:z	https://[z]:zno hostname in URLZsni_hostname)r   r   z)session parameter must be an httpx.Clientacceptzapplication/dns-messager   rr   )r5   http1http2r   r   r   r   r    )r   r   r   	transport)zcontent-typezcontent-length)headerscontentr   
extensions   =r
   )r   r   paramsr      +   responded with status code z
Response body: keyringrequest_macr   r   )6r~   r
   r%   r&   r-   AF_INETAF_INET6urllibparseurlparsehostnamer{   r4   r   r   r   have_dohr   r)   randomchoicelistr*   _http3r\   r_   httpxZClientto_wirer   r   
contextlibnullcontextrF   updatestrlenr   base64urlsafe_b64encoderstripdecodegetstatus_coder   message	from_wirer   r   elapsedtotal_secondsr	   is_responser[   )"r   r|   r   r4   r;   r}   r   r   r   r@   r   r   r   r   r    r   r:   r7   Z
the_sourceurlr   parsedr8   wirer   Zh1Zh2r5   r   cmr   responseZtwirerr   r   r   httpsr  s    G










&
r   )r   namer   c                 C   s2   | d u rt | D ]\}}||kr|  S qt d S r   )KeyError)r   r   headervaluer   r   r   _find_header9  s    
r   )r   peerr   r   c                 C   s   t | d}|d u rtdt|}|dk r2td|dk sB|dkrd}t|dkrvzd|  }W n tyt   Y n0 t| d	| | d S )
Ns   :statuszno :status header in responser   zstatus is negativer   r    z: r   )r   rt   intr   r   r1   r{   )r   r   r   r   statuserrorr   r   r   _check_statusB  s    
r   U  )r   r|   r   r   r4   r;   r}   r   r   r   r   r   r   c              	   C   s.  t jjstdtj|}|j}
|jd ur2|j}d| _	| 
 }t jj|	|
dd}| |||||}t|\}}||<}|||| |t|}t| || W d    n1 s0    Y  t }W d    n1 s0    Y  t jj|| j| j||d}t|| d|_| |s*t|S )Nz DNS-over-HTTP3 is not available.r   T)verify_modeserver_nameZh3r   r   )r
   quic	have_quicr\   r   r   r   r   r4   idr   SyncQuicManagerconnectr$   make_streamZsend_h3receiver   r   r   r	   r   r   r   r   maxr   r[   )r   r|   r   r   r4   r;   r}   r   r   r   r   r   Z	url_partsr   manager
connectionstartr   streamfinishr   r   r   r   r   S  s<    
.&r   c                 C   s0   z|  |W S  ty(   t| | Y q 0 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BlockingIOErrorrp   )r<   max_sizer   r   r   r   	_udp_recv  s    r   c                 C   sF   z"|r|  ||W S | |W S W q  ty>   t| | Y q 0 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   rq   )r<   datarx   r   r   r   r   	_udp_send  s    r   )r<   whatrx   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   rx   r   	sent_timenr   r   r   send_udp  s
    r       )r<   rx   r   ry   r   r   r   r   raise_on_truncationignore_errorsqueryr   c              
   C   s   d}t | d|\}}t| j|||s&qt }ztjj||||||d}W nn tjjy } z6|	r|
dur|
| sW Y d}~qn W Y d}~n&d}~0  t	y   |	rY qn Y n0 |	r|
dur|
|sq|r||fS |||fS q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.

    *ignore_errors*, a ``bool``.  If various format errors or response
    mismatches occur, ignore them and keep listening for a valid response.
    The default is ``False``.

    *query*, a ``dns.message.Message`` or ``None``.  If not ``None`` and
    *ignore_errors* is ``True``, check that the received message is a response
    to this query, and if not keep listening for a valid response.
    r     )r   r   r   r   r   N)
r   rz   r    r	   r
   r   r   	Truncatedr   r1   )r<   rx   r   ry   r   r   r   r   r   r   r   r   rw   received_timer   er   r   r   receive_udp  sD    >

r   5   )r   r|   r   r4   r;   r}   ry   r   r   r   r<   r   r   c                 C   s   |   }t||||\}}}t|\}}|
r8t|
}nt|tj|}|b}t|||| t	|||||| j
| j||	|| \}}|| |_|s| |st|W  d   S 1 s0    Y  dsJ dS )a  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.

    *ignore_errors*, a ``bool``.  If various format errors or response
    mismatches occur, ignore them and keep listening for a valid response.
    The default is ``False``.

    Returns a ``dns.message.Message``.
    NF)r   r~   r$   r   r   r,   r-   
SOCK_DGRAMr   r   r   macr	   r   r[   )r   r|   r   r4   r;   r}   ry   r   r   r   r<   r   r   r:   rx   
begin_timer   r   ro   r   r   r   r   r   udp&  s:    8

"r  )r   r|   r   r4   r;   r}   ry   r   r   udp_socktcp_sockr   r   c                 C   sd   z(t | ||||||||d|	|}|dfW S  tjjy^   t| ||||||||
	}|df Y S 0 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.

    *ignore_errors*, a ``bool``.  If various format errors or response mismatches occur
    while listening for UDP, ignore them and keep listening for a valid response. The
    default is ``False``.

    Returns a (``dns.message.Message``, tcp) tuple where tcp is ``True`` if and only if
    TCP was used.
    TFN)r  r
   r   r   tcp)r   r|   r   r4   r;   r}   ry   r   r   r  r  r   r   r   r   r   udp_with_fallback  s:    9
r  c              	   C   s   d}|dkrz2|  |}|dkr(td|t|8 }||7 }W q ttjfy`   t| | Y q tjy|   t| | Y q0 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   ZEOF)	recvEOFErrorr   r   rN   SSLWantReadErrorrp   SSLWantWriteErrorrq   )r<   countr   ro   r   r   r   r   	_net_read  s    
r  c              	   C   st   d}t |}||k rpz|| ||d 7 }W q ttjfyP   t| | Y q tjyl   t| | Y q0 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   rN   r	  rq   r  rp   )r<   r   r   currentlr   r   r   
_net_write  s    r  )r<   r   r   r   c                 C   sP   t |tjjr|jdd}nt|d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.
    T)Zprepend_lengthr   big)	r_   r
   r   r   r   r   to_bytesr	   r  )r<   r   r   tcpmsgr   r   r   r   send_tcp  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   !Hr   )r  structunpackr	   r
   r   r   )r<   r   r   r   r   r   ldatar  r   r   r   r   r   r   receive_tcp  s    !r  c                 C   s`   |  |}|dkrd S |tjtjtjfv rDt| | | tjtj	}|dkr\t
|t|d S rG   )
connect_exerrnoZEINPROGRESSEWOULDBLOCKZEALREADYrq   
getsockoptr-   
SOL_SOCKETSO_ERROROSErrorosstrerror)ro   r9   r   errr   r   r   r/   K  s    

r/   )
r   r|   r   r4   r;   r}   r   r   r<   r   c	                 C   s   |   }	t|\}
}|r$t|}n"t||||\}}}t|tj|}|b}|s\t||| t	||	| t
|||| j| j|\}}||
 |_| |st|W  d   S 1 s0    Y  dsJ 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``.
    NF)r   r$   r   r   r~   r,   r-   r.   r/   r  r  r   r   r	   r   r[   )r   r|   r   r4   r;   r}   r   r   r<   r   r   r   r   r:   rx   ro   r   r   r   r   r   r  V  s*    +


"r  c                 C   sP   z|    W d S  tjy,   t| | Y q  tjyH   t| | Y q 0 q d S r   )do_handshakerN   r  rp   r	  rq   rn   r   r   r   _tls_handshake  s    r#  )r   r   r   c                 C   s   d }d }t |tr>tj|r$|}ntj|r6|}ntdtj||d}tj	j
|_| d u rdd|_|dg |du rtj|_|S )Nzinvalid verify string)cafilecapathFdot)r_   r   r  r@   isfileisdirr{   rN   rU   
TLSVersionTLSv1_2minimum_versioncheck_hostnameset_alpn_protocolsrV   r   )r   r   r$  r%  r   r   r   r   _make_dot_ssl_context  s     

r.  )r   r|   r   r4   r;   r}   r   r   r<   r   r   r   r   c              
   C   s   |rt | ||||||||	S |  }t|\}}t||||\}}}|	du rZ|sZt|
|}	t|tj||	|
dh}t||| t	|| t
||| t|||| j| j|\}}|| |_| |st|W  d   S 1 s0    Y  dsJ dS )ak  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.

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

    Returns a ``dns.message.Message``.

    N)r   r   F)r  r   r$   r~   r.  r,   r-   r.   r/   r#  r  r  r   r   r	   r   r[   )r   r|   r   r4   r;   r}   r   r   r<   r   r   r   r   r   r   r:   rx   ro   r   r   r   r   r   tls  sN    =




"r/  )r   r|   r   r4   r;   r}   r   r   r   r   r   r   r   c              	   C   s(  t jjstd|dur$|
du r$|}
d| _|  }|rFtd}|}nt jj|	|
d}|}|| |st|	||||}t
|\}}||*}||d |t|}W d   n1 s0    Y  t }W d   n1 s0    Y  t jj|| j| j||d}t|| d|_| |s$t|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.

    *hostname*, a ``str`` containing the server's hostname or ``None``.  The default is
    ``None``, which means that no hostname is known, and if an SSL context is created,
    hostname checking will be disabled.  This value is ignored if *url* is not
    ``None``.

    *server_hostname*, a ``str`` or ``None``.  This item is for backwards compatibility
    only, and has the same meaning as *hostname*.

    Returns a ``dns.message.Message``.
    zDNS-over-QUIC is not available.Nr   )r   r   Tr   r   )r
   r   r   r]   r   r   r   r   r   r   r$   r   r   r   r   r	   r   r   r   r   r   r   r[   )r   r|   r   r4   r;   r}   r   r   r   r   r   r   r   r   Zthe_connectionZthe_managerr   r   r   r   r   r   r   r   r   '  s<    7
,&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   rr   r   N)rB   rC   rD   rZ   NEVERZ	TRY_FIRSTONLYr   r   r   r   r0    s   r0  )txn_managerro   r   serialr   r   r   c                 c   sh  |j d j}|tjjk}|  }| }	|jtj	k}
|
rHt
||	d| n tdt|	|	 }t||| tj| |||
}d}d}|s(t|\}}|du s|dur||kr|}|
rt|d|\}}n&t|d|}td|\}t|||}tjj||j|jd|||
 |d}||}|V  |j}q|jrD|jsDtjd	W d   n1 sZ0    Y  dS )
z'Given a socket, does the zone transfer.r   Nr  Fr   r   T)r   r   xfrorigintsig_ctxmultir   zmissing TSIG)questionrdtyper
   	rdatatypeIXFRZfrom_wire_originr   r   r-   r   r   r  packr   r  r5  ZInboundr$   r   r  r  r   r   r   r   Zprocess_messager7  Zhad_tsigr   	FormError)r3  ro   r   r4  r   r   r:  Zis_ixfrr6  r   Zis_udpr  Zinbounddoner7  r7   ZmexpirationZrwirer  r  r   r   r   r   _inbound_xfr  sP    	

r@  )r|   zoner:  rdclassr   r4   r   keyname
relativizer#   r;   r}   r4  use_udpkeyalgorithmr   c                 c   sR  G dd dt jj}t|tr*t j|}t jj	|}t j
|||}|t jjkr|j|j|t jjt jjdd}t jddd| }||d |d	ur|j|||d
 t| ||
|\}}}
t|	\}}|||}|r|t jjkrtd|rtjntj}t|||
4}t||| t||||||E d	H  W d	   n1 sD0    Y  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.
    c                   @   sL   e Zd Zdd Zdd ZejjdddZdd	 Z	de
ejjdddZdS )z$xfr.<locals>.DummyTransactionManagerc                 S   s   |||rt jjn|f| _d S r   )r
   r   emptyinfo)r   r6  rD  r   r   r   r   
  s    z-xfr.<locals>.DummyTransactionManager.__init__c                 S   s   | j S r   )rH  r   r   r   r   origin_information  s    z7xfr.<locals>.DummyTransactionManager.origin_information)r   c                 S   s   t d S r   r>   rI  r   r   r   	get_class  s    z.xfr.<locals>.DummyTransactionManager.get_classc                 S   s   t d S r   r>   rI  r   r   r   reader  s    z+xfr.<locals>.DummyTransactionManager.readerF)replacementr   c                 S   s   G dd d}t tjj| S )Nc                   @   s   e Zd Zdd Zdd ZdS )zExfr.<locals>.DummyTransactionManager.writer.<locals>.DummyTransactionc                 _   s   d S r   r   )r   rK   kwr   r   r   nop  s    zIxfr.<locals>.DummyTransactionManager.writer.<locals>.DummyTransaction.nopc                 S   s   | j S r   )rO  )r   r7   r   r   r   __getattr__  s    zQxfr.<locals>.DummyTransactionManager.writer.<locals>.DummyTransaction.__getattr__N)rB   rC   rD   rO  rP  r   r   r   r   DummyTransaction  s   rQ  )r   r
   transactionTransaction)r   rM  rQ  r   r   r   writer  s    z+xfr.<locals>.DummyTransactionManager.writerN)F)rB   rC   rD   r   rJ  r
   
rdataclass
RdataClassrK  rL  boolrR  rS  rT  r   r   r   r   DummyTransactionManager	  s
   rX  T)createINSOAz. . %u 0 0 0 0r   N)	algorithmzcannot do a UDP AXFR)r
   rR  TransactionManagerr_   r   r   Z	from_textr;  	RdataTypemaker   
make_queryr<  Z
find_rrset	authorityrU  rZ  r[  ZrdataaddZuse_tsigr~   r$   r{   r-   r   r.   r,   r/   r@  )r|   rA  r:  rB  r   r4   r   rC  rD  r#   r;   r}   r4  rE  rF  rX  r   ZrrsetZsoar:   rx   r7   r   tmZ	sock_typero   r   r   r   r5    s0    E


r5  )
r|   r3  r   r4   r   r#   r;   r}   udp_moder   c	              	   C   sF  |du rt j|\}}	nt j|}	t| |||\}
}}t|\}}|jd jt jj	kr|t
jkrt|
tj|j}t||| z*t||||	||D ]}qW W d   dS  t jjy   |t
jkrȂ Y n0 W d   n1 s0    Y  t|
tj|6}t||| t||||	||D ]}qW d   n1 s80    Y  d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   )r
   r5  r`  Zextract_serial_from_queryr~   r$   r9  r:  r;  r<  r0  r1  r,   r-   r   r/   r@  ZUseTCPr2  r.   )r|   r3  r   r4   r   r#   r;   r}   rd  r4  r:   rx   r7   r   ro   r   r   r   inbound_xfr9  s.    /

&re  )T)NN)	Nr   Nr   FFTNT)N)
NNFFNr   FFFN)
Nr   Nr   FFFFNF)
Nr   Nr   FFFNNF)N)NFNr   F)Nr   Nr   FFN)
Nr   Nr   FFNNNT)
Nr   Nr   FFNTNN)~rZ   r   r   enumr  r  os.pathr   ra   r-   r  r	   urllib.parser   typingr   r   r   r   r   r   Zdns._featuresr
   Zdns.exceptionZdns.inetZdns.messageZdns.nameZdns.quicZ	dns.rcodeZdns.rdataclassZdns.rdatatypeZ
dns.serialZdns.transactionZdns.tsigZdns.xfrr   r   Z	_featuresZhaveZ_have_httpxZhttpcore._backends.syncr2   r   ZNetworkBackendZ_CoreNetworkBackendZ	_backendssyncZ
SyncStreamr0   r   ZHTTPTransportrF   r   rN   ImportErrorr   r   ZDNSExceptionrX   r>  r[   r\   r]   r5  ZTransferErrorr$   rl   rp   rq   ru   rz   r~   r,   r   IntEnumr   rM   r   r   r   r   floatr   rW  r   r   ZHeadersbytesr   r   r   r   r   r   r   NameZtsigKeyr   r  r  r  r  r  r  r/   r  r#  rR   r.  rS   r/  ZSyncQuicConnectionr0  rR  r]  r@  r;  ZAXFRrU  rZ  Zdefault_algorithmr^  rV  r1  re  r   r   r   r   <module>   s   	
4 
,

 H	         
1 
          
m          ^          X 
      /       E          
n          

]6x
