
    \                        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e
j2                  j4                        Z G d d	e
j2                  j8                        Z G d
 de
j2                  j4                        Zd Zd Z d Z!d Z"d Z# e$ed      re a%ne!a%d Z&d Z'd Z(d Z)d#dZ*	 	 	 d$dZ+	 	 d%dZ,d Z-d Z.d#dZ/	 	 d&dZ0d Z1	 	 d'd Z2e
jf                  jh                  e
jj                  jl                  ddddd!dddddde
jn                  jp                  fd"Z9y)(zTalk to a DNS server.    )
generatorsN   )longstring_typesPY3c                       e Zd ZdZy)UnexpectedSourcez=A DNS query response came from an unexpected address or port.N__name__
__module____qualname____doc__     lib/third_party/dns/query.pyr	   r	   /   s    Gr   r	   c                       e Zd ZdZy)BadResponsez<A DNS query response does not respond to the question asked.Nr
   r   r   r   r   r   3   s    Fr   r   c                   "     e Zd ZdZ fdZ xZS )TransferErrorz.A zone transfer response got a non-zero rcode.c                 ~    dt         j                  j                  |      z  }t        t        |   |       || _        y )NzZone transfer error: %s)dnsrcodeto_textsuperr   __init__)selfr   message	__class__s      r   r   zTransferError.__init__:   s2    +cii.?.?.FFmT+G4
r   )r   r   r   r   r   __classcell__)r   s   @r   r   r   7   s    8 r   r   c                 6    | y t        j                          | z   S N)time)timeouts    r   _compute_expirationr$   @   s    yy{W$$r   c                 Z   d}|r|t         j                  z  }|r|t         j                  z  }|r|t         j                  z  }t        j                         }|j                  | |       |r(|j	                  t        |dz              }t        |      S |j	                         }t        |      S )zPoll polling backend.r   i  )selectPOLLINPOLLOUTPOLLERRpollregisterr   bool)fdreadablewritableerrorr#   
event_maskpollable
event_lists           r   	_poll_forr4   K   s     Jfmm#
fnn$
fnn$
{{}Hb*%]]4$#78
 
 ]]_

r   c                     g g g }}}|r| g}|r| g}|r| g}|t        j                   |||      \  }}	}
nt        j                   ||||      \  }}	}
t        |xs |	xs |
      S )zSelect polling backend.)r&   r,   )r-   r.   r/   r0   r#   rsetwsetxsetrcountwcountxcounts              r   _select_forr<   a   s}     2r$Dttt#)==tT#B #)==tT7#K +6+V--r   c                 T   d}|sl|d }n6|t        j                          z
  }|dk  rt        j                  j                  	 t	        | ||||      st        j                  j                  	 d}|sky y # t
        $ r,}|j                  d   t        j                  k7  r|Y d }~7d }~ww xY w)NFg        r   T)	r"   r   	exceptionTimeout_polling_backendselect_errorargserrnoEINTR)r-   r.   r/   r0   
expirationdoner#   es           r   	_wait_forrH   u   s    
 DG 499;.G#~mm+++	#B(E7Kmm+++ L
    	vvayEKK' (	s   )A2 2	B';"B""B'c                     | a y r!   )r@   )fns    r   _set_polling_backendrK      s
    
 r   r*   c                 "    t        | ddd|       y )NTFrH   srE   s     r   _wait_for_readablerP      s    audJ/r   c                 "    t        | ddd|       y )NFTrM   rN   s     r   _wait_for_writablerR      s    adJ/r   c                     	 t         j                  j                  | |d         }t         j                  j                  | |d         }||k(  xr |dd  |dd  k(  S # t         j                  j                  $ r Y yw xY w)Nr   Fr   )r   inet	inet_ptonr>   SyntaxError)afa1a2n1n2s        r   _addresses_equalr\      s{    XXBqE*XXBqE* 8(12"QR&(( ==$$ s   AA A:9A:c                 l   |  	 t         j                  j                  |      } | t         j                  j                  k(  r||f}||dk7  r=|d}||f}n4| t         j                  j
                  k(  r||ddf}||dk7  r
|d}||ddf}| |fS # t        $ r t         j                  j                  } Y w xY w)Nr   z0.0.0.0z::)r   rT   af_for_address	ExceptionAF_INETAF_INET6)rW   whereportsourcesource_portdestinations         r   _destination_and_sourcerg      s     
z	"((/B 
SXXdm!1~"k*F	sxx  	 dAq)!1~k1a0FV$$  	"!!B	"s   B #B32B3c                     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_wirerR   r"   sendto)sockwhatrf   rE   	sent_timens         r   send_udprq      sR    " $++,||~tZ(		ID+&Ay>r   Fc                 r   d}	 t        | |       | j                  d      \  }}	t        | j                  |	|      s-t        j
                  j                  |d         r|	dd |dd k(  rn|st        d|	d|      yt        j                         }
t        j                  j                  |||||      }||
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.
    r   r     r   Nzgot a response from z instead of keyringrequest_macone_rr_per_rrsetignore_trailing)rP   recvfromr\   familyr   rT   is_multicastr	   r"   r   	from_wire)rm   rf   rE   ignore_unexpectedrw   ru   rv   rx   wirefrom_addressreceived_timers               r   receive_udpr      s    B D
4,#}}U3|DKK{CHH!!+a.1AB/ "9E9D$F G G  IIKMdG/?.= 	 	?A }r   5   c
           
         | j                         }
t        |||||      \  }}}t        |t        j                  d      }d}d}	 t        |      }|j                  d       ||j                  |       t        ||
||      \  }}t        |||||| j                  | j                  |	      \  }}||d}n||z
  }|j                          ||_        | j                  |      st        |S # ||d}n||z
  }|j                          w xY w)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)rk   rg   socket_factorysocket
SOCK_DGRAMr$   setblockingbindrq   r   ru   maccloser"   is_responser   )qrb   r#   rc   rW   rd   re   r}   rw   rx   r~   rf   rO   r   ro   rE   _r   response_times                      r   udpr     s    J 99;D 7E48>!MRfr6,,a0AMI(1
	aFF6N!!T;
CI(K):<L)*AEE?LM  5M)I5M		AF==H  5M)I5M		s   A)C) )Dc                     d}|dkD  rAt        | |       | j                  |      }|dk(  rt        |t        |      z
  }||z   }|dkD  rA|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   )rP   recvEOFErrorlen)rm   countrE   rO   rp   s        r   	_net_readr   R  sZ     	A
!)4,IIe8NAE !) Hr   c                 |    d}t        |      }||k  r*t        | |       || j                  ||d       z  }||k  r)yy)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   rR   send)rm   datarE   currentls        r   
_net_writer   c  sE    
 GD	A
A+4,499T'(^,, A+r   c                 &   t        |t        j                  j                        r|j	                         }t        |      }t        j                  d|      |z   }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.
    !H)ri   r   r   rj   rk   r   structpackrR   r"   r   )rm   rn   rE   r   tcpmsgro   s         r   send_tcpr   o  ss     $++,||~D	A [[q!D(FtZ(		ItVZ(K##r   c                     t        | d|      }t        j                  d|      \  }t        | ||      }t        j                         }	t        j
                  j                  |||||      }
|
|	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.
       r   rt   )r   r   unpackr"   r   r   r|   )rm   rE   rw   ru   rv   rx   ldatar   r~   r   r   s              r   receive_tcpr     so    4 dAz*E==u%DQT1j)DIIKMdG/?.= 	 	?A }r   c                 0   	 | j                  |       y # t        j                  $ rn t        j                         d d \  }}t        |d      r|j                  }n|d   }|t        j                  t        j                  t        j                  fvr|Y y w xY w)Nr   rC   r   )
connectr   r0   sysexc_infohasattrrC   EINPROGRESSEWOULDBLOCKEALREADY)rO   addresstyvv_errs        r   _connectr     s    
			'<< ,,.!$Q1gGGEaDE**E,=,=u~~NNG Os    A>BBc	                 H   | j                         }	t        |||||      \  }}
}t        |t        j                  d      }d}d}	 t        |      }|j                  d       t        j                         }||j                  |       t        ||
       t        ||	|       t        |||| j                  | j                  |      \  }}||d}n||z
  }|j                          ||_        | j                  |      st         |S # ||d}n||z
  }|j                          w xY w)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)rk   rg   r   r   SOCK_STREAMr$   r   r"   r   r   r   r   ru   r   r   r   r   )r   rb   r#   rc   rW   rd   re   rw   rx   r~   rf   rO   
begin_timer   rE   r   r   s                    r   tcpr     s(   D 99;D 7E48>!MRfr6--q1AJM(1
	aYY[
FF6NK D*%(J8H)*AEE?LM !6M)J6M		AF==H !6M)J6M		s   BD D!Tc              #   F  K   t        |t              rt        j                  j	                  |      }t        |t              rt        j
                  j	                  |      }t        j                  j                  |||      }|t        j
                  j                  k(  rAt        j                  j	                  |dddd|z        }|j                  j                  |       ||j                  |||       |j                         }t        |	| |||      \  }	}}|rD|t        j
                  j                  k7  rt        d      t!        |	t"        j$                  d      }nt!        |	t"        j&                  d      }|j)                  d       ||j+                  |       t-        |
      }t/        ||       t1        |      }|rt3        ||       |j5                  |       n&t7        j8                  d|      |z   }t;        |||       d	}d
}d	}d}|r|}t        j                  j<                  }nd}|}d}d
}|sXt-        |      } | | |kD  r|} |r!t?        ||       |jA                  d      \  }}!n2tC        |d|       }"t7        jD                  d|"      \  }tC        |||       }|t        j
                  j                  k(  }#t        j                  jG                  ||jH                  |jJ                  d
||d
||#	      }$|$jM                         }%|%t        jL                  jN                  k7  rtQ        |%      |$jR                  }d	}d}&||$jT                  r|$jT                  d   j                  |k7  rt        jV                  jY                  d      |$jT                  d   }|jZ                  t        j
                  j\                  k7  rt        jV                  jY                  d      d}&|j_                         }|t        j
                  j                  k(  r|d   j`                  |k  rd
}nd
}|$jT                  |&d D ]  }|rt        jV                  jY                  d      |jZ                  t        j
                  j\                  k(  r|j                  |k(  r|r4|d   j`                  |k7  rt        jV                  jY                  d      d	}n |t        j
                  j                  k(  r| }||k(  s|t        j
                  jb                  k(  s!|t        j
                  j                  k(  s|sd
}|st        j
                  jb                  }d	} |r7|jH                  r+|$jd                  st        jV                  jY                  d      |$ |sX|jg                          yw)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 AXFRr   FTrs   r   )ru   rv   xfrorigintsig_ctxmultifirstrw   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)4ri   r   r   name	from_text	rdatatyper   
make_queryIXFRrrset	authorityappenduse_tsigrk   rg   
ValueErrorr   r   r   r   r   r   r$   r   r   rR   r   r   r   r   emptyrP   ry   r   r   r|   ru   r   r   NOERRORr   r   answerr>   	FormErrorrdtyper   copyserialAXFRhad_tsigr   )'rb   zoner   rdclassr#   rc   ru   keyname
relativizerW   lifetimerd   re   r   use_udpkeyalgorithmr   r   r~   rf   rO   rE   r   r   rF   delete_modeexpecting_SOA	soa_rrsetr   onamer   r   mexpirationr   r   is_ixfrr   r   answer_indexs'                                          r   r   r     s    z $%xx!!$'&,'((0tVW5A###		##D!T5$4v$=?	5!	

7G|
<99;D 7E48>!MRfS]]'''3442v00!42v1115MM!	v$X.JQD	A1j)	tT1%,1fj)DKMIHE)'2+
":$Kq*-#$::e#4 T<aK0E==u-DQQ;/DS]]///KK!!$		quu&*6H(,E3: " < 	CII%%%&&::88qxx{//58mm--68 8HHQKE||s}}000mm--.IJJL

I+++Q<&&&0  D$(M
 XXlm,Emm--.GHH||s}}000UZZ55H Qx&0!mm5579 9$)Ms}}111&1/K I%3==#5#55 CMM$6$66;D ++ %7 -8 AIIajj--)).99S T GGIs%   S)V!,:V!'V!*V!0AV!V!r!   )NFFNr   F)Nr   NNr   FFF)NFNr   F)Nr   NNr   FF):r   
__future__r   rC   r&   r   r   r   r"   dns.exceptionr   dns.inetdns.namedns.message	dns.rcodedns.rdataclassdns.rdatatype_compatr   r   r   OSErrorrA   r0   r   r>   DNSExceptionr	   r   r   r   r$   r4   r<   rH   rK   r   r@   rP   rR   r\   rg   rq   r   r   r   r   r   r   r   r   r   r   
rdataclassr   tsigdefault_algorithmr   r   r   r   <module>r      s  $  !     
         , ,L<<L Hs}}11 HG#--)) GCMM.. %,.(, 66 !"00	)%.2 /3:??D1f LMIN=@"	-$4 9>?D!F LM05;|  MM..8I8I2tTd$t1CHH$>$>sr   