U
    <{f0                     @   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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#r>ddl$Z%ddl&Z&e%j'Z(e%j)j*j+Z,G d	d
 d
e(Z-G dd de&j.Z/nG dd dZ/e#Z0zddl1Z1W n$ e2k
r   G dd dZ1Y nX ejZ3G dd dej4j5Z6G dd dej4j7Z8G dd dej4j5Z9G dd dej4j5Z:ej;j<Z<dd Z=dd Z>dd Z?e@edrejAaBnejCaBdd  ZDd!d" ZEd#d$ ZFd%d& ZGdhd(d)ZHdid*d+ZIdd,ddd-d-dd.d'dd'dejJfejKjLeMeeN eOeeM eOePePee eMePeeM eePeMf ed/ eeO ejKjLd0d1d2ZQd3d4 ZRd5d6 ZSdjeeejKjLeTf eeeN eeOeNf d7d8d9ZUdkeee eeN ePePeeejVjWejXjYf  eeT ePePePeejKjL ed;d<d=ZZdlejKjLeMeeN eOeeM eOePePePePee ePejKjLd?d@dAZ[dmejKjLeMeeN eOeeM eOePePePee ee ePeejKjLePf dBdCdDZ\dEdF Z]dGdH Z^dneeejKjLeTf eeN eeOeNf dIdJdKZ_doeeeN ePeeejVjWejXjYf  eeT ePeejKjLeNf dLdMdNZ`dOdP ZadpejKjLeMeeN eOeeM eOePePee ejKjLdQ
dRdSZbdTdU ZceeM eePeMf e1jddVdWdXZedqejKjLeMeeN eOeeM eOePePee1jf ee1jd eeM eePeMf ejKjLdZd[d\ZgdrejKjLeMeeN eOeeM eOePePeejhji eePeMf eeM ejKjLd]d^d_Zhejjjkejljmdd>ddd'ddddd-ejXjnfeMeejVjWeMf eejjjoeMf eejljpeMf eeN eOeeejVjWejXjYf  eeejVjWeMf  ePeeN eeM eOeOePeejVjWeMf ed`dadbZ;G dcdd ddejqZrdd>dddderjsfeMejtjueejKjL eOeeN eeN eeM eOerdde
dfdgZvdS )sz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   H/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/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_attempt8   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   G   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_tcpN   sH    
   
z_NetworkBackend.connect_tcpc                 C   s   t d S r   NotImplementedError)r   pathr   r5   r   r   r   connect_unix_socketu   s    z#_NetworkBackend.connect_unix_socket)N)N)__name__
__module____qualname__r   r;   r?   __classcell__r   r   r    r   r   F   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__)r@   rA   rB   r,   	AF_UNSPECr   rC   r   r   r    r   rD   z   s
   rD   c                   @   s   e Zd Zdd ZdS )rD   c                 C   s   t d S r   r<   )r   r2   r3   r   r4   r   r   r   r;      s    z_HTTPTransport.connect_tcpN)r@   rA   rB   r;   r   r   r   r   rD      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r@   rA   rB   r   r   r   r   WantReadException   s   rM   c                   @   s   e Zd ZdS )zssl.WantWriteExceptionNrL   r   r   r   r   WantWriteException   s   rN   c                   @   s   e Zd ZdS )zssl.SSLContextNrL   r   r   r   r   
SSLContext   s   rO   c                   @   s   e Zd ZdS )zssl.SSLSocketNrL   r   r   r   r   	SSLSocket   s   rP   c                 O   s   t dd S )Nzno ssl support)r0   )clsrH   rI   r   r   r   create_default_context   s    zssl.create_default_contextN)r@   rA   rB   	CERT_NONEr0   rM   rN   rO   rP   classmethodrR   r   r   r   r   rK      s   rK   c                   @   s   e Zd ZdZdS )UnexpectedSourcez=A DNS query response came from an unexpected address or port.Nr@   rA   rB   __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   )
isinstancerK   rP   pending_selector_class	selectors
EVENT_READEVENT_WRITEregisterr   r	   r
   r   select)fdreadablewritabler6   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)r8   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   )r8   from_addressdestinationignore_unexpectedr   r   r   _matches_destination  s    ry   Tc                 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'   r0   
ValueErrorZ
any_for_afr*   )wherer3   r9   source_portZwhere_must_be_addressr8   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_socketr0   close)r8   typer9   ssl_contextr   rn   r   r   r   r+   R  s    



r+   i  Fz
/dns-queryzdns.resolver.Resolver)qr{   r   r3   r9   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
d
|||||d}|rt|}ntjd
d
||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)r4   http1http2r   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\   httpxZClientrz   to_wirer}   r	   r$   r%   r,   AF_INETformatAF_INET6rD   
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   r3   r9   r|   r   r   r   r>   r   r   r   r   r   wirer8   r6   Z
the_sourcer   r   urlr4   r   cmresponseZtwirerr   r   r   httpsf  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_truncationignore_errorsqueryr   c              
   C   s   d}t | d|\}}t| j|||s&qt }ztjj||||||d}W nj tjjk
r } z*|	r|
dk	r|
| sW Y 
qn W 5 d}~X Y n  t	k
r   |	rY qn Y nX |	r|
dk	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   ry   r   r   r	   r   r   	Truncatedr   r0   )r:   rw   r   rx   r   r   r   r   r   r   r   r   rv   received_timer   er   r   r   receive_udp2  sJ    >   

r   5   )r   r{   r   r3   r9   r|   rx   r   r   r   r:   r   r   c                 C   s   |   }t||||\}}}t|\}}|
r8t|
}nt|tj|}|`}t|||| t	|||||| j
| j||	|| \}}|| |_|s| |st|W  5 Q R  S Q R X dst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``.
    FN)r   r}   r#   r   r   r+   r,   
SOCK_DGRAMr   r   r   macr   r   rX   AssertionError)r   r{   r   r3   r9   r|   rx   r   r   r   r:   r   r   r8   rw   
begin_timer   r   rn   r   r   r   r   r   udp  s@    8   

r   )r   r{   r   r3   r9   r|   rx   r   r   udp_socktcp_sockr   r   c                 C   sf   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.

    *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   r3   r9   r|   rx   r   r   r   r   r   r   r   r   r   udp_with_fallback  s:    9
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   rK   SSLWantReadErrorro   SSLWantWriteErrorrp   )r:   countr   rn   r   r   r   r   	_net_readO  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   rK   r   rp   r   ro   )r:   r   r   currentlr   r   r   
_net_writed  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_length   big)	r\   r	   r   r   r   r   to_bytesr   r   )r:   r   r   tcpmsgr   r   r   r   send_tcpt  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krDt| | | tjtj	}|dkr\t
|t|d S rE   )
connect_exerrnoZEINPROGRESSEWOULDBLOCKZEALREADYrp   
getsockoptr,   
SOL_SOCKETSO_ERROROSErrorosstrerror)rn   r7   r   errr   r   r   r.     s    

r.   )
r   r{   r   r3   r9   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   r3   r9   r|   r   r   r:   r   r   r   r   r8   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_handshakerK   r   ro   r   rp   rm   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 krdd|_|dg |dkrtj|_|S )Nzinvalid verify string)cafilecapathFdot)r\   r   r   r>   isfileisdirrz   rK   rR   
TLSVersionTLSv1_2minimum_versioncheck_hostnameset_alpn_protocolsrS   verify_mode)r   r   r   r   r   r   r   r   _make_dot_ssl_context  s     

r   U  )r   r{   r   r3   r9   r|   r   r   r:   r   r   r   r   c              
   C   s   |rt | ||||||||	S |  }t|\}}t||||\}}}|	dkrZ|sZt|
|}	t|tj||	|
df}t||| t	|| t
||| t|||| j| j|\}}|| |_| |st|W  5 Q R  S Q R X dst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   rX   r   )r   r{   r   r3   r9   r|   r   r   r:   r   r   r   r   r   r   r8   rw   rn   r   r   r   r   r   tls1  s^    =   


     

r  )r   r{   r   r3   r9   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)r   Z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   r3   r9   r|   r   r   r  r   r   r   managerZthe_connectionZthe_managerstartr   streamfinishr   r   r   r   r    s>    2
 
r  )r{   zonerdtyperdclassr   r3   r   keyname
relativizer"   r9   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_ctx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   packr   emptyr   r   r   r   r   r   rcodeZNOERRORTransferErrorr  Zanswerr
   	FormErrorr  r  copyr  ZSerialAXFRhad_tsig)'r{   r  r  r  r   r3   r   r  r  r"   r9   r|   r  r  r  r   r#  r   r8   rw   	sock_typern   r6   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)r@   rA   rB   rW   NEVERZ	TRY_FIRSTONLYr   r   r   r   r1    s   r1  )
r{   txn_managerr   r3   r   r"   r9   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_queryquestionr  r  r"  Zfrom_wire_originr   r}   r#   r1  r2  r,   r   r-   r+   r.   r   r   r%  r   r   ZInboundr   r   r   r   r   r   r   Zprocess_messageZUseTCPr   r3  r  r,  r
   r)  )r{   r4  r   r3   r   r"   r9   r|   r5  r  r  r0  r  r   r8   rw   r6   r   retryr-  Zis_udprn   r   Zinboundr.  r  r/  Zrwirer   r   r   r   r   r   inbound_xfr  s    /   




r8  )T)NN)N)
NNFFNr   FFFN)
Nr   Nr   FFFFNF)
Nr   Nr   FFFNNF)N)NFNr   F)Nr   Nr   FFN)
Nr  Nr   FFNNNT)	Nr  Nr   FFNTN)wrW   r   r   enumr   r   os.pathr_   r,   r   r   typingr   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.syncr1   r   ZNetworkBackendZ_CoreNetworkBackendZ	_backendssyncZ
SyncStreamr/   r   ZHTTPTransportrD   r   rK   ImportErrorr   r
   ZDNSExceptionrU   r)  rX   rY   rZ   r  r(  r#   ri   rj   hasattrrk   r^   SelectSelectorro   rp   rt   ry   r}   r+   rJ   r   r   r   floatintboolr   r   r   bytesr   r  NameZtsigKeyr   r   r   r   r   r   r   r.   r   r   rO   r   rP   r  r  ZSyncQuicConnectionr  r+  Z
rdataclassr  Zdefault_algorithmr  Z
RdataClassIntEnumr1  r2  ZtransactionZTransactionManagerr8  r   r   r   r   <module>   s  	
4 
,

  
          
m          ^          X 
      /       D 
          
n         

Z ;
