o
    ¯bæ  ã                   @   sŠ   d dgZ ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZmZ ddlmZ G d	d„ dejƒZG d
d „ d eƒZdS )ÚSecondaryAuthorityÚSecondaryAuthorityServiceé    )Úservice)ÚdeferÚtask)ÚclientÚcommonÚdnsÚresolve)ÚFileAuthority)ÚfailureÚlog)ÚnativeStringc                   @   sD   e Zd ZdZdZdZdd„ Zedd„ ƒZdd	„ Z	d
d„ Z
dd„ ZdS )r   a:  
    A service that keeps one or more authorities up to date by doing hourly
    zone transfers from a master.

    @ivar primary: IP address of the master.
    @type primary: L{str}

    @ivar domains: An authority for each domain mirrored from the master.
    @type domains: L{list} of L{SecondaryAuthority}
    Né5   c                    s"   t ˆ ƒ| _‡ fdd„|D ƒ| _dS )a  
        @param primary: The IP address of the server from which to perform
        zone transfers.
        @type primary: L{str}

        @param domains: A sequence of domain names for which to perform
        zone transfers.
        @type domains: L{list} of L{bytes}
        c                    s   g | ]}t ˆ |ƒ‘qS © )r   ©Ú.0Úd©Úprimaryr   ú9/usr/lib/python3/dist-packages/twisted/names/secondary.pyÚ
<listcomp>+   s    z6SecondaryAuthorityService.__init__.<locals>.<listcomp>N)r   r   Údomains)Úselfr   r   r   r   r   Ú__init__    s   

z"SecondaryAuthorityService.__init__c                    s0   ˆ \}}| |g ƒ}||_ ‡ fdd„|D ƒ|_|S )aˆ  
        Construct a new L{SecondaryAuthorityService} from a tuple giving a
        server address and a C{str} giving the name of a domain for which this
        is an authority.

        @param serverAddress: A two-tuple, the first element of which is a
            C{str} giving an IP address and the second element of which is a
            C{int} giving a port number.  Together, these define where zone
            transfers will be attempted from.

        @param domains: Domain names for which to perform zone transfers.
        @type domains: sequence of L{bytes}

        @return: A new instance of L{SecondaryAuthorityService}.
        c                    s   g | ]}t  ˆ |¡‘qS r   )r   ÚfromServerAddressAndDomainr   ©ÚserverAddressr   r   r   A   s    
ÿÿzISecondaryAuthorityService.fromServerAddressAndDomains.<locals>.<listcomp>)Ú_portr   )Úclsr   r   r   Úportr   r   r   r   ÚfromServerAddressAndDomains-   s   

þz5SecondaryAuthorityService.fromServerAddressAndDomainsc                 C   s   t  | j¡S )z_
        Get a resolver for the transferred domains.

        @rtype: L{ResolverChain}
        )r
   ÚResolverChainr   ©r   r   r   r   ÚgetAuthorityG   s   z&SecondaryAuthorityService.getAuthorityc                 C   sV   t j | ¡ dd„ | jD ƒ| _d}ddlm} | jD ]}| ||jd¡ |d7 }qd S )Nc                 S   s   g | ]}t  |j¡‘qS r   )r   ÚLoopingCallÚtransferr   r   r   r   r   Q   s    z:SecondaryAuthorityService.startService.<locals>.<listcomp>r   ©Úreactori  é   )	r   ÚServiceÚstartServicer   ÚcallsÚtwisted.internetr(   Ú	callLaterÚstart)r   Úir(   Úcr   r   r   r+   O   s   

ýz&SecondaryAuthorityService.startServicec                 C   s$   t j | ¡ | jD ]}| ¡  q	d S ©N)r   r*   ÚstopServicer,   Ústop)r   r1   r   r   r   r3   Z   s   

ÿz%SecondaryAuthorityService.stopService)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r,   r   r   Úclassmethodr!   r$   r+   r3   r   r   r   r   r      s    
c                   @   sr   e Zd ZdZdZd ZZdZdZdd„ Z	e
dd„ ƒZd	d
„ Zddd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )r   a  
    An Authority that keeps itself updated by performing zone transfers.

    @ivar primary: The IP address of the server from which zone transfers will
    be attempted.
    @type primary: L{str}

    @ivar _port: The port number of the server from which zone transfers will
    be attempted.
    @type _port: L{int}

    @ivar domain: The domain for which this is the secondary authority.
    @type domain: L{bytes}

    @ivar _reactor: The reactor to use to perform the zone transfers, or
    L{None} to use the global reactor.
    FNr   c                 C   s&   t j | ¡ t|ƒ| _t |¡| _dS )z�
        @param domain: The domain for which this will be the secondary
            authority.
        @type domain: L{bytes} or L{str}
        N)r   ÚResolverBaser   r   r   r	   ÚdomainStringÚdomain)r   Ú	primaryIPr<   r   r   r   r   x   s   	
zSecondaryAuthority.__init__c                 C   s   |\}}| ||ƒ}||_ |S )af  
        Construct a new L{SecondaryAuthority} from a tuple giving a server
        address and a C{bytes} giving the name of a domain for which this is an
        authority.

        @param serverAddress: A two-tuple, the first element of which is a
            C{str} giving an IP address and the second element of which is a
            C{int} giving a port number.  Together, these define where zone
            transfers will be attempted from.

        @param domain: A C{bytes} giving the domain to transfer.
        @type domain: L{bytes}

        @return: A new instance of L{SecondaryAuthority}.
        )r   )r   r   r<   r   r    Ú	secondaryr   r   r   r   …   s   
z-SecondaryAuthority.fromServerAddressAndDomainc                 C   s^   | j rdS d| _| j}|du rddlm} tj| j| jfg|d�}| 	| j
¡ | j¡ | j¡S )z›
        Attempt a zone transfer.

        @returns: A L{Deferred} that fires with L{None} when attempted zone
            transfer has completed.
        NTr   r'   )Úserversr(   )ÚtransferringÚtransferingÚ_reactorr-   r(   r   ÚResolverr   r   Ú
lookupZoner<   ÚaddCallbackÚ_cbZoneÚ
addErrbackÚ_ebZone)r   r(   Úresolverr   r   r   r&   ›   s   	ÿ
ýzSecondaryAuthority.transferc                 C   s4   | j r| jst t t |¡¡¡S t 	| ||||¡S r2   )
ÚsoaÚrecordsr   Úfailr   ÚFailurer	   ÚDomainErrorr   Ú_lookup)r   Únamer   ÚtypeÚtimeoutr   r   r   rO   µ   s   zSecondaryAuthority._lookupc                 C   sf   |\}}}i  | _ }|D ]$}| js"|jtjkr"|jj ¡ |jf| _q| |jj ¡ g ¡ 	|j¡ qd S r2   )
rK   rJ   rQ   r	   ÚSOArP   ÚlowerÚpayloadÚ
setdefaultÚappend)r   ÚzoneÚansÚ_ÚrÚrecr   r   r   rF   ¼   s   

üzSecondaryAuthority._cbZonec                 C   s$   t  d| j| jf ¡ t  |¡ d S )Nz/Updating %s from %s failed during zone transfer)r   Úmsgr<   r   Úerr©r   r   r   r   r   rH   Å   s   
ÿÿzSecondaryAuthority._ebZonec                 C   s   |   ¡  | j| j¡ d S r2   )r&   ÚaddCallbacksÚ_cbTransferredÚ_ebTransferredr#   r   r   r   ÚupdateÌ   s   zSecondaryAuthority.updatec                 C   s
   d| _ d S )NF)r@   )r   Úresultr   r   r   ra   Ï   s   
z!SecondaryAuthority._cbTransferredc                 C   s*   d| _ t d| j| jf ¡ t |¡ d S )NFz2Transferring %s from %s failed after zone transfer)Útransferredr   r]   r<   r   r^   r_   r   r   r   rb   Ò   s   
ÿÿz!SecondaryAuthority._ebTransferredr2   )r5   r6   r7   r8   r@   rJ   rK   r   rB   r   r9   r   r&   rO   rF   rH   rc   ra   rb   r   r   r   r   r   `   s     

	N)Ú__all__Útwisted.applicationr   r-   r   r   Útwisted.namesr   r   r	   r
   Útwisted.names.authorityr   Útwisted.pythonr   r   Útwisted.python.compatr   r*   r   r   r   r   r   r   Ú<module>   s   P