3
[_ð]‹\  ã               @   sÆ  d Z ddl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lmZmZmZ er–eZnejZejZG dd„ de
jjƒZG dd	„ d	e
jjƒZG d
d„ de
jjƒZdd„ Zdd„ Z dd„ Z!dd„ Z"dd„ Z#e$edƒ�re a%ne!a%dd„ Z&dd„ Z'dd„ Z(dd„ Z)d7dd „Z*d8d#d$„Z+d9d&d'„Z,d(d)„ Z-d*d+„ Z.d:d,d-„Z/d;d.d/„Z0d0d1„ Z1d<d2d3„Z2e
j3j4e
j5j6dd%ddd4dddddd!e
j7j8fd5d6„Z9dS )=zTalk to a DNS server.é    )Ú
generatorsNé   )ÚlongÚstring_typesÚPY3c               @   s   e Zd ZdZdS )ÚUnexpectedSourcez=A DNS query response came from an unexpected address or port.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú./tmp/pip-build-yz_zf6az/dnspython/dns/query.pyr   /   s   r   c               @   s   e Zd ZdZdS )ÚBadResponsez<A DNS query response does not respond to the question asked.N)r   r	   r
   r   r   r   r   r   r   3   s   r   c                   s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚTransferErrorz.A zone transfer response got a non-zero rcode.c                s*   dt jj|ƒ }tt| ƒj|ƒ || _d S )NzZone transfer error: %s)ÚdnsÚrcodeZto_textÚsuperr   Ú__init__)Úselfr   Úmessage)Ú	__class__r   r   r   :   s    zTransferError.__init__)r   r	   r
   r   r   Ú__classcell__r   r   )r   r   r   7   s   r   c             C   s   | d krd S t j ƒ |  S d S )N)Útime)Útimeoutr   r   r   Ú_compute_expiration@   s    r   c             C   sj   d}|r|t jO }|r |t jO }|r.|t jO }t jƒ }|j| |ƒ |rZ|jt|d ƒƒ}n|jƒ }t|ƒS )zPoll polling backend.r   iè  )ÚselectÚPOLLINÚPOLLOUTÚPOLLERRÚpollÚregisterr   Úbool)ÚfdÚreadableÚwritableÚerrorr   Ú
event_maskZpollableZ
event_listr   r   r   Ú	_poll_forK   s    


r'   c             C   sr   g g g   }}}|r| g}|r$| g}|r.| g}|dkrLt j |||ƒ\}}	}
nt j ||||ƒ\}}	}
t|pn|	pn|
ƒS )zSelect polling backend.N)r   r!   )r"   r#   r$   r%   r   ZrsetZwsetZxsetZrcountZwcountZxcountr   r   r   Ú_select_fora   s    r(   c             C   s”   d}xŠ|sŽ|d krd }n|t j ƒ  }|dkr4tjj‚yt| ||||ƒsNtjj‚W n6 tk
r† } z|jd tjkrv|‚W Y d d }~X nX d}qW d S )NFg        r   T)	r   r   Ú	exceptionÚTimeoutÚ_polling_backendÚselect_errorÚargsÚerrnoZEINTR)r"   r#   r$   r%   Ú
expirationÚdoner   Úer   r   r   Ú	_wait_foru   s    r2   c             C   s   | a d S )N)r+   )Úfnr   r   r   Ú_set_polling_backend‹   s    r4   r   c             C   s   t | ddd|ƒ d S )NTF)r2   )Úsr/   r   r   r   Ú_wait_for_readable›   s    r6   c             C   s   t | ddd|ƒ d S )NFT)r2   )r5   r/   r   r   r   Ú_wait_for_writableŸ   s    r7   c             C   sb   y(t jj| |d ƒ}t jj| |d ƒ}W n t jjk
r@   dS X ||ko`|dd … |dd … kS )Nr   Fr   )r   ÚinetÚ	inet_ptonr)   ÚSyntaxError)ÚafZa1Za2Zn1Zn2r   r   r   Ú_addresses_equal£   s    r<   c             C   sº   | d kr6yt jj|ƒ} W n tk
r4   t jj} Y nX | t jjkrp||f}|d k	sZ|dkr°|d krfd}||f}n@| t jjkr°||ddf}|d k	s˜|dkr°|d kr¤d}||ddf}| ||fS )Nr   z0.0.0.0z::)r   r8   Zaf_for_addressÚ	ExceptionÚAF_INETÚAF_INET6)r;   ÚwhereÚportÚsourceÚsource_portÚdestinationr   r   r   Ú_destination_and_source¯   s$    
rE   c             C   s<   t |tjjƒr|jƒ }t| |ƒ tjƒ }| j||ƒ}||fS )aþ  Send a DNS message to the specified UDP socket.

    *sock*, a ``socket``.

    *what*, a ``binary`` 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.
    )Ú
isinstancer   r   ÚMessageÚto_wirer7   r   Úsendto)ÚsockÚwhatrD   r/   Ú	sent_timeÚnr   r   r   Úsend_udpÆ   s    
rN   Fó    c             C   s”   d}xht | |ƒ | jdƒ\}}	t| j|	|ƒsTtjj|d ƒrV|	dd… |dd… krVP |std|	|f ƒ‚qW tjƒ }
tj	j
|||||d�}||
f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 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 ``binary``, 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`` object.
    rO   iÿÿ  r   r   Nz$got a response from %s instead of %s)ÚkeyringÚrequest_macÚone_rr_per_rrsetÚignore_trailing)r6   Úrecvfromr<   Úfamilyr   r8   Úis_multicastr   r   r   Ú	from_wire)rJ   rD   r/   Úignore_unexpectedrR   rP   rQ   rS   ÚwireÚfrom_addressÚreceived_timeÚrr   r   r   Úreceive_udpß   s"    !
r]   é5   c
             C   sÎ   | j ƒ }
t|||||ƒ\}}}t|tjdƒ}d}d}zXt|ƒ}|jdƒ |dk	rZ|j|ƒ t||
||ƒ\}}t	|||||| j
| j|	ƒ\}}W d|dksž|dkr¤d}n|| }|jƒ  X ||_| j|ƒsÊt‚|S )añ  Return the response obtained after sending a query via UDP.

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

    *where*, a ``text`` 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.

    *af*, an ``int``, the address family to use.  The default is ``None``,
    which causes the address family to use to be inferred from the form of
    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

    *source*, a ``text`` 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.

    Returns a ``dns.message.Message``.
    r   N)rH   rE   Úsocket_factoryÚsocketÚ
SOCK_DGRAMr   ÚsetblockingÚbindrN   r]   rP   ÚmacÚcloser   Úis_responser   )Úqr@   r   rA   r;   rB   rC   rX   rR   rS   rY   rD   r5   r[   rL   r/   Ú_r\   Úresponse_timer   r   r   Úudp  s.    %



rj   c             C   sJ   d}x@|dkrDt | |ƒ | j|ƒ}|dkr.t‚|t|ƒ }|| }qW |S )zßRead 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.
    rO   r   )r6   ÚrecvÚEOFErrorÚlen)rJ   Úcountr/   r5   rM   r   r   r   Ú	_net_readR  s    


ro   c             C   s>   d}t |ƒ}x,||k r8t| |ƒ || j||d… ƒ7 }qW dS )z‘Write the specified data to the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    r   N)rm   r7   Úsend)rJ   Údatar/   ÚcurrentÚlr   r   r   Ú
_net_writec  s
    

rt   c             C   sX   t |tjjƒr|jƒ }t|ƒ}tjd|ƒ| }t| |ƒ t	j	ƒ }t
| ||ƒ t|ƒ|fS )a|  Send a DNS message to the specified TCP socket.

    *sock*, a ``socket``.

    *what*, a ``binary`` 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.
    z!H)rF   r   r   rG   rH   rm   ÚstructÚpackr7   r   rt   )rJ   rK   r/   rs   ÚtcpmsgrL   r   r   r   Úsend_tcpo  s    
rx   c             C   sL   t | d|ƒ}tjd|ƒ\}t | ||ƒ}tjƒ }	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 ``binary``, 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`` object.
    é   z!H)rP   rQ   rR   rS   )ro   ru   Úunpackr   r   r   rW   )rJ   r/   rR   rP   rQ   rS   Úldatars   rY   r[   r\   r   r   r   Úreceive_tcp‰  s    r|   c             C   sp   y| j |ƒ W n\ tjk
rj   tjƒ d d… \}}t|dƒrF|j}n|d }|tjtjtj	gkrf|‚Y nX d S )Nry   r.   r   )
Úconnectr`   r%   ÚsysÚexc_infoÚhasattrr.   ZEINPROGRESSÚEWOULDBLOCKZEALREADY)r5   ÚaddressÚtyÚvZv_errr   r   r   Ú_connect¬  s    
r…   c	             C   sÖ   | j ƒ }	t|||||ƒ\}}
}t|tjdƒ}d}d}z`t|ƒ}|jdƒ tjƒ }|dk	rb|j|ƒ t	||
ƒ t
||	|ƒ t|||| j| j|ƒ\}}W d|dks¦|dkr¬d}n|| }|jƒ  X ||_| j|ƒsÒt‚|S )a�  Return the response obtained after sending a query via TCP.

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

    *where*, a ``text`` 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.

    *af*, an ``int``, the address family to use.  The default is ``None``,
    which causes the address family to use to be inferred from the form of
    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

    *source*, a ``text`` 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.

    Returns a ``dns.message.Message``.
    r   N)rH   rE   r_   r`   ÚSOCK_STREAMr   rb   r   rc   r…   rx   r|   rP   rd   re   rf   r   )rg   r@   r   rA   r;   rB   rC   rR   rS   rY   rD   r5   Z
begin_timer[   r/   r\   ri   r   r   r   Útcpº  s0    "




r‡   Tc       '      c   sÔ  t |tƒrtjj|ƒ}t |tƒr,tjj|ƒ}tjj|||ƒ}|tjjkrltj	j|dddd| ƒ}|j
j|ƒ |dk	r„|j|||d� |jƒ }t|	| |||ƒ\}	}}|rÊ|tjjkrºtdƒ‚t|	tjdƒ}nt|	tjdƒ}|jdƒ |dk	rô|j|ƒ t|
ƒ}t||ƒ t|ƒ}|�r*t||ƒ |j|ƒ ntjd|ƒ| }t|||ƒ d	}d
}d	}d}|�rj|}tjj}nd}|}d}d
}�xJ|�sÆt|ƒ} | dk�s | |k�r¤|} |�rÄt||ƒ |j dƒ\}}!n&t!|d| ƒ}"tj"d|"ƒ\}t!||| ƒ}|tjjk}#tjj#||j$|j%d
||d
||#d�	}$|$j&ƒ }%|%tj&j'k�r6t(|%ƒ‚|$j)}d	}d}&|dk�rÐ|$j* �sj|$j*d j|k�rvtj+j,dƒ‚|$j*d }|j-tjj.k�rœtj+j,dƒ‚d}&|j/ƒ }|tjjk�rÐ|d j0|k�rÌd
}nd
}xÆ|$j*|&d… D ]´}|�rötj+j,dƒ‚|j-tjj.k�r€|j|k�r€|�r:|d j0|k�r4tj+j,dƒ‚d	}n|tjjk�rN| }||k�r’|tjj1k�sz|tjjk�r’|�r’d
}n|�ràtjj1}d	}�qàW |�r¼|j$�r¼|$j2 �r¼tj+j,dƒ‚|$V  �q~W |j3ƒ  dS )aç  Return a generator for the responses to a zone transfer.

    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

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

    *rdtype*, an ``int`` or ``text``, 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 ``text``, 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 ``text``, 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.

    *af*, an ``int``, the address family to use.  The default is ``None``,
    which causes the address family to use to be inferred from the form of
    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

    *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 ``text`` 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 ``text``, 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 AXFRz!HFTiÿÿ  ry   )rP   rQ   ÚxfrÚoriginÚtsig_ctxZmultiÚfirstrR   z No answer or RRset not for qnamezfirst RRset is not an SOAr   zanswers after final SOAzIXFR base serial mismatchzmissing TSIG)4rF   r   r   ÚnameZ	from_textÚ	rdatatyper   Z
make_queryZIXFRÚrrsetÚ	authorityÚappendZuse_tsigrH   rE   Ú
ValueErrorr_   r`   ra   r†   rb   rc   r   r…   rm   r7   rp   ru   rv   rt   Úemptyr6   rT   ro   rz   rW   rP   rd   r   ZNOERRORr   r�   Zanswerr)   Ú	FormErrorÚrdtyper‰   ÚcopyÚserialÚAXFRZhad_tsigre   )'r@   Úzoner—   Zrdclassr   rA   rP   ZkeynameZ
relativizer;   ZlifetimerB   rC   r™   Zuse_udpZkeyalgorithmrg   r‘   rY   rD   r5   r/   rs   rw   r0   Zdelete_modeZexpecting_SOAZ	soa_rrsetrŒ   Zonamer�   rŽ   ZmexpirationrZ   r{   Zis_ixfrr\   r   Zanswer_indexr   r   r   r‹   ø  sÂ    =













r‹   )N)NFFNrO   F)Nr^   NNr   FFF)N)NFNrO   F)Nr^   NNr   FF):r   Ú
__future__r   r.   r   r`   ru   r~   r   Zdns.exceptionr   Zdns.inetZdns.nameZdns.messageZ	dns.rcodeZdns.rdataclassZdns.rdatatypeÚ_compatr   r   r   ÚOSErrorr,   r%   r_   r)   ZDNSExceptionr   r–   r   r   r   r'   r(   r2   r4   r€   r+   r6   r7   r<   rE   rN   r]   rj   ro   rt   rx   r|   r…   r‡   r�   rš   Z
rdataclassrˆ   ZtsigZdefault_algorithmr‹   r   r   r   r   Ú<module>   sh   	
  
1 
?
 
" 
=

