B
    H/\Pb                 @   s  d dl 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m	Z	 d dlm
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d dlZd d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ dgZdd Ze Zdd Zeej_ej Z ej j!Z"e#eddd Z$dded d d fddZ%e%e _%dZ&ej'j(fddZ)e)Z*dd Z+G dd de,Z-G d d! d!ej j.Z/G d"d# d#e,Z0G d$d% d%e,Z1d&d' Z2G d(d deZ3dS ))    )absolute_importprint_functiondivisionN)AI_NUMERICHOST)error)NI_NUMERICSERV)AF_INET)AF_INET6)	AF_UNSPEC)AbstractResolver)hostname_types)string_types)	iteritems)import_patched)configResolverc              C   sJ   t d} x<dD ]4}t |}x&|jD ]}t||t |d |  q"W qW | S )Ndns)r   zdns.rdtypeszdns.rdtypes.INzdns.rdtypes.ANY.)r   __all__setattr)toppkgmodname r   8lib/python3.7/site-packages/gevent/resolver/dnspython.py
_patch_dns\   s    
 r   c             C   s   |  dstt|  tS )Nr   )
startswithAssertionErrorr   r   )r   r   r   r   _dns_import_patchedi   s    r   Z	exc_clearc               C   s   d S )Nr   r   r   r   r   <lambda>y   s    r    c             C   s   |t jt jB @ dkrt| d kr4|d kr4t t jg }g }d }y| d krd}|t j@ dkrr|d |d q|d |d n>| d}	t	|	dkr|	d }
n| }
t
j|
}||  | }W n tk
r`   t  y t
j| }||  | }W nX tk
rZ   t  |t j@ dkrVy|t jksD|t jkrtjj| t
jjd	d
}|j} |jd}|jd k	rx|jD ]}||j qW |t jks|t jkr tjj| t
jjd	d
}|j} |jd}|jd k	r x|jD ]}||j qW W nR t
jjk
r.   t  t t jY n( tk
rT   t  t t j Y nX Y nX Y nX d }y|d krxd}nt!|}W nX tk
r   t  |t j"@ dkryt #|}W n tk
r   t  Y nX Y nX |d krt t jg }|dkrt j$t j%g}n|g}|t j&@ dkr*|}nd}|t jksF|t jkrxR|D ]J}xB|D ]:}x2tj'| D ]$}|t j|||||ddff qfW qVW qLW |t jks|t jkrxN|D ]F}x>|D ]6}x.tj'| D ] }|t j|||||ff qW qW qW t	|dkrt t j|S )Nr   	localhostz::z0.0.0.0z::1z	127.0.0.1%   F)raise_on_no_answerT )(socketZAI_ADDRCONFIGZAI_V4MAPPEDNotImplementedErrorgaierrorZ
EAI_NONAMEZ
AI_PASSIVEappendsplitlenr   ipv6	inet_aton	Exception
_exc_clearipv4r   r	   r
   resolver	_resolverquery	rdatatypeAAAAqnamecanonical_nameZto_textrrsetZaddressr   ANXDOMAINZ
EAI_SYSTEMintZAI_NUMERICSERVZgetservbynameZ
SOCK_DGRAMZSOCK_STREAMZAI_CANONNAMEZ_protocols_for_socktype)hostZservicefamilysocktypeprotoflagsZv6addrsZv4addrsr7   partsZahostaddrv6rdatav4portZtuplesZ	socktypescnamer   r   r   _getaddrinfo   s    












$

 rH   g     r@c             C   sL   | sdS t | tstt| y||  W n tjjk
rB   dS X dS d S )NFT)
isinstancer   r   reprr   Z	exceptionSyntaxError)r<   parser   r   r   _is_addr   s    rM   c             C   s4   | r&t | trdnd}| |dd } t| tjjS )Nr"      %   r   )rI   strr*   rM   r   r,   r-   )r<   sr   r   r   _is_ipv6_addr  s    rR   c               @   s@   e Zd ZdZedejZdddZdd Z	dd	 Z
d
d ZdS )	HostsFilezD
    A class to read the contents of a hosts file (/etc/hosts).
    z
        \s*  # Leading space
        ([^\r\n#]+?)  # The actual match, non-greedy so as not to include trailing space
        \s*  # Trailing space
        (?:[#][^\r\n]+)?  # Comments
        (?:$|[\r\n]+)  # EOF or newline
    Nc             C   s`   i | _ i | _i | _i | _|d krFtjdkr0d}ntjdkrFtjd}|| _| jsVt	d| _
d S )Nposixz
/etc/hostsntz'%SystemRoot%\system32\drivers\etc\hostsr   )rE   rC   aliasesreverseosr   path
expandvarsfnamer   
_last_load)selfr[   r   r   r   __init__  s    


zHostsFile.__init__c          	   C   sF   t | jd}| }W d Q R X t|ts6|jddn|}| j|S )Nrbignore)errors)openr[   readrI   rP   decodeLINES_REfindall)r]   fpZfdataZudatar   r   r   
_readlines%  s    zHostsFile._readlinesc          	   C   sj  yt | jj}|| jk}W n> ttfk
rZ   ddlm} | j	| ft
   d}Y nX |sdd S i }i }i }i }x|  D ]}| }	t|	dk rq~|	d}
t|
r|}nt|
r~|
drq~|}nq~|	d }|
||< x$|	D ]}| }|
||< |||< qW ||kr,dt|
dd }n|
d }||kr~|||< q~W || _|| _|| _|| _|| _d S )	Nr   )get_hubFr#   fe80r   z.in-addr.arpaz
.ip6.arpa.)rX   statr[   st_mtimer\   IOErrorOSErrorgeventri   handle_errorsysexc_inforh   r*   r+   pop_is_ipv4_addrrR   r   lowerjoinreversedrE   rC   rV   rW   )r]   Z	load_timeZ
needs_loadri   rE   rC   rV   rW   linerA   ZipZipmaprG   aliasZptrr   r   r   load4  sR    




zHostsFile.loadc             c   sP   |    x t| jD ]\}}||fV  qW x t| jD ]\}}||fV  q6W d S )N)rz   r   rE   rC   )r]   r   rB   r   r   r   iter_all_host_addr_pairsm  s
    z"HostsFile.iter_all_host_addr_pairs)N)__name__
__module____qualname____doc__recompileVERBOSEre   r^   rh   rz   r{   r   r   r   r   rS     s   

9rS   c               @   s   e Zd ZdddZdS )_HostsAnswerTc             C   sX   d | _ || _|| _|| _|| _|s0|r0tj || _t	|drNt

 |j nd| _d S )Nttlr   )Zresponser6   rdtyperdclassr7   r   r1   NoAnswerr8   hasattrtimer   Z
expiration)r]   r6   r   r   r8   r$   r   r   r   r^   w  s    
z_HostsAnswer.__init__N)T)r|   r}   r~   r^   r   r   r   r   r   t  s   r   c               @   sB   e Zd ZdZdefddZejjej	j
dddfddZd	d
 ZdS )_HostsResolverz'
    Class to parse the hosts file
    Nc             C   s   t || _|| _d| _d S )Nr   )rS   
hosts_fileintervalr\   )r]   r[   r   r   r   r   r^     s    
z_HostsResolver.__init__FTc             C   sL  t   }| j}| j| j |k r,|| _|  tjj}t|t	rP|}	tj
|}nt|}	|	 }	tj|||}
| j| j | |
_|tjjkr|j}tjjjj}nV|tjjkr|j}tjjjj}n6|tjjkr|j}dd }n|tjjkr|j}dd }||	}|s$| r$||	d d }|r<|
|||| t||||
|S )Nc             S   s   t jjj| |t j|S )N)r   rdtypesANYCNAMEr   	from_text)ctrB   r   r   r   r      s    z&_HostsResolver.query.<locals>.<lambda>c             S   s   t jjj| |t j|S )N)r   r   r   PTRr   r   )r   r   rB   r   r   r   r      s    )r   r   r\   r   rz   r   
rdataclassINrI   r   r   r   rP   ru   r8   ZRRsetr   r4   r9   rE   r   r5   rC   r   rV   r   rW   getZis_absoluteaddr   )r]   r6   r   r   tcpsourcer$   Znowr   r   r8   mappingZkindrB   r   r   r   r3     s>    


z_HostsResolver.queryc             C   sb   | j j}g }||kr|| }n|}|| x&t|D ]\}}||kr6|| q6W || |S )N)r   rV   r)   r   remove)r]   hostnamerV   resultZcannonry   rG   r   r   r   
getaliases  s    


z_HostsResolver.getaliases)r|   r}   r~   r   	HOSTS_TTLr^   r   r4   r9   r   r   r3   r   r   r   r   r   r     s
   0r   c               @   sD   e Zd Zdd Zejjejjdddejjejj	ejj
ffddZdS )_DualResolverc             C   s"   t  | _t | _t | j_d S )N)r   hosts_resolverr1   Zget_default_resolvernetwork_resolverZLRUCachecache)r]   r   r   r   r^     s    
z_DualResolver.__init__FNTc       
      C   s   |d krd}t |ts*t |tr*|d}t |trBtj|d }t |trXtj|}|tjj	kr||kry| j
j||dd}W n6 tk
r   ddlm}	 |	 j| ft   Y nX |jr|S | jj||||||dS )Nz0.0.0.0idnaF)r$   r   )ri   )rI   r   bytesrd   r   r   r   r4   r   r   r   r3   r.   ro   ri   rp   rq   rr   r8   r   )
r]   r6   r   r   r   r   r$   Z_hosts_rdtypesZanswerri   r   r   r   r3     s&    




z_DualResolver.query)r|   r}   r~   r^   r   r4   r9   r   r   r5   r   r3   r   r   r   r   r     s   r   c             C   s:   | t jkrtjj}n"| t jkr(tjj}nt t jd|S )NzAddress family not supported)	r&   r   r   r4   r9   r	   r5   r(   Z
EAI_FAMILY)r=   r   r   r   r   _family_to_rdtype  s    



r   c               @   sP   e Zd ZdZdddZedd Zdd Zd	d
 ZdddZ	dd Z
dd ZdS )r   a  
    An *experimental* resolver that uses `dnspython`_.

    This is typically slower than the default threaded resolver
    (unless there's a cache hit, in which case it can be much faster).
    It is usually much faster than the c-ares resolver. It tends to
    scale well as more concurrent resolutions are attempted.

    Under Python 2, if the ``idna`` package is installed, this
    resolver can resolve Unicode host names that the system resolver
    cannot.

    .. note::

        This **does not** use dnspython's default resolver object, or share any
        classes with ``import dns``. A separate copy of the objects is imported to
        be able to function in a non monkey-patched process. The documentation for the resolver
        object still applies.

        The resolver that we use is available as the :attr:`resolver` attribute
        of this object (typically ``gevent.get_hub().resolver.resolver``).

    .. caution::

        Many of the same caveats about DNS results apply here as are documented
        for :class:`gevent.resolver.ares.Resolver`.

    .. caution::

        This resolver is experimental. It may be removed or modified in
        the future. As always, feedback is welcome.

    .. versionadded:: 1.3a2

    .. _dnspython: http://www.dnspython.org
    Nc             C   sZ   t jd kr>t  }t _tjr.tj|jjd d < tjr>tj|j_t	t jtsNt
t j| _d S )N)r1   r2   r   r   Zresolver_nameserversr   ZnameserversZresolver_timeoutZlifetimerI   r   )r]   Zhubr2   r   r   r   r^   +  s    

zResolver.__init__c             C   s   | j jS )a  
        The dnspython resolver object we use.

        This object has several useful attributes that can be used to
        adjust the behaviour of the DNS system:

        * ``cache`` is a :class:`dns.resolver.LRUCache`. Its maximum size
          can be configured by calling :meth:`resolver.cache.set_max_size`
        * ``nameservers`` controls which nameservers to talk to
        * ``lifetime`` configures a timeout for each individual query.
        )r2   r   )r]   r   r   r   r1   7  s    zResolver.resolverc             C   s   d S )Nr   )r]   r   r   r   closeF  s    zResolver.closec          
   C   s   t |tst |tr|d}| jj|}| jj}t|}xxy|	|t
jj|}W n< t
jjt
jjt
jjfk
r|   P Y q> tk
r   P Y q>X |dd |jD  |d j}q>W |S )Nr   c             s   s   | ]}t |jV  qd S )N)rP   target).0Zrrr   r   r   	<genexpr>X  s    z'Resolver._getaliases.<locals>.<genexpr>r   )rI   rP   r   rd   r2   r   r   r   r   r3   r   r4   r   r1   r   r:   ZNoNameserversdTimeoutextendr8   r   )r]   r   r=   rV   Znet_resolverr   Zansr   r   r   _getaliasesI  s     


 zResolver._getaliasesr   c             C   s   |dks,t |r|ds,t|tr,|t@ r@t||||||S |tkryt||||||S  t	j
k
r   yt||t|||S  t	j
k
r   t||t|||S X Y qX nt||||||S d S )N)r!   s	   localhostrj   )rR   r   rI   rP   r   _socketgetaddrinfor
   rH   r&   r(   r	   r   )r]   r<   rF   r=   r>   r?   r@   r   r   r   r   \  s    
zResolver.getaddrinfoc             C   s   |r*t |ttfr*|d dkr*t||S t |ttfrNt |d tsNtdyt||S  t	k
r~   |szt|t
S Y nX d S )Nr   )z::1z	127.0.0.1r!   z(getnameinfo(): illegal sockaddr argument)rI   listtupler   getnameinfor   	TypeErrorr1   Z_getnameinfor   r   )r]   Zsockaddrr@   r   r   r   r   }  s    zResolver.getnameinfoc             C   s8   |dkrt |S t|ts.tdt|f t|S )N)z	127.0.0.1z::1s	   127.0.0.1s   ::1r!   z2argument 1 must be str, bytes or bytearray, not %s)r   gethostbyaddrrI   r   r   typer1   Z_gethostbyaddr)r]   Z
ip_addressr   r   r   r     s
    

zResolver.gethostbyaddr)N)r   r   r   r   )r|   r}   r~   r   r^   propertyr1   r   r   r   r   r   r   r   r   r   r     s   $

!)4Z
__future__r   r   r   r   r   rX   rq   r   r   r   r   r   r	   r
   r&   Zgevent.resolverr   r   Zgevent._compatr   r   Zgevent._patcherr   Zgevent._configr   r   r   r   r   rD   
__import__r1   ZTimeoutr   getattrr/   rH   r   r0   r-   rM   rt   rR   objectrS   ZAnswerr   r   r   r   r   r   r   r   r   <module>=   sN   mlN)
