Ë
    ojˆ0  ã                   ó”   — d Z ddlmZ ddlmZmZmZ ddlmZ  G d„ d«      Z	 G d„ dej                  «      Zd	„ Z G d
„ d«      Zdd„Zy)zÁ
Resolver implementation for querying successive authoritative servers to
lookup a record, starting from the root nameservers.

@author: Jp Calderone

todo::
    robustify it
    documentation
é    )Údefer)ÚcommonÚdnsÚerror)ÚFailurec                   ó   — e Zd ZdZd„ Zy)Ú_DummyControllerz²
    A do-nothing DNS controller.  This is useful when all messages received
    will be responses to previously issued queries.  Anything else received
    will be ignored.
    c                  ó   — y ©N© )ÚselfÚargss     ú4/usr/lib/python3/dist-packages/twisted/names/root.pyÚmessageReceivedz _DummyController.messageReceived   s   € Øó    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r	   r	      s   „ ñór   r	   c                   ó6   — e Zd ZdZd	d„Zd„ Zd„ Zd„ Zd„ Zd„ Z	y)
ÚResolverao  
    L{Resolver} implements recursive lookup starting from a specified list of
    root servers.

    @ivar hints: See C{hints} parameter of L{__init__}
    @ivar _maximumQueries: See C{maximumQueries} parameter of L{__init__}
    @ivar _reactor: See C{reactor} parameter of L{__init__}
    @ivar _resolverFactory: See C{resolverFactory} parameter of L{__init__}
    Nc                 óŠ   — t         j                  j                  | «       || _        || _        || _        |€ddlm} || _        y)a‡  
        @param hints: A L{list} of L{str} giving the dotted quad
            representation of IP addresses of root servers at which to
            begin resolving names.
        @type hints: L{list} of L{str}

        @param maximumQueries: An optional L{int} giving the maximum
             number of queries which will be attempted to resolve a
             single name.
        @type maximumQueries: L{int}

        @param reactor: An optional L{IReactorTime} and L{IReactorUDP}
             provider to use to bind UDP ports and manage timeouts.
        @type reactor: L{IReactorTime} and L{IReactorUDP} provider

        @param resolverFactory: An optional callable which accepts C{reactor}
             and C{servers} arguments and returns an instance that provides a
             C{queryUDP} method. Defaults to L{twisted.names.client.Resolver}.
        @type resolverFactory: callable
        Nr   ©r   )	r   ÚResolverBaseÚ__init__ÚhintsÚ_maximumQueriesÚ_reactorÚtwisted.names.clientr   Ú_resolverFactory)r   r   ÚmaximumQueriesÚreactorÚresolverFactorys        r   r   zResolver.__init__+   s?   € ô* 	×Ñ×$Ñ$ TÔ*ØˆŒ
Ø-ˆÔØˆŒØÐ"ÝHØ /ˆÕr   c                 ó`   — | j                   D �cg c]  }|t        j                  f‘Œ c}S c c}w )z‚
        Return a list of two-tuples representing the addresses of the root
        servers, as defined by C{self.hints}.
        )r   r   ÚPORT)r   Úips     r   Ú_rootszResolver._rootsH   s$   € ð
 *.¯©Ö4 2�”S—X‘X’Ò4Ð4ùÒ4s   �+c                 ó    — | j                  || j                  ¬«      }|j                  |g|«      }|r|j                  |j                  «       |S )a­  
        Issue one query and return a L{Deferred} which fires with its response.

        @param query: The query to issue.
        @type query: L{dns.Query}

        @param servers: The servers which might have an answer for this
            query.
        @type servers: L{list} of L{tuple} of L{str} and L{int}

        @param timeout: A timeout on how long to wait for the response.
        @type timeout: L{tuple} of L{int}

        @param filter: A flag indicating whether to filter the results.  If
            C{True}, the returned L{Deferred} will fire with a three-tuple of
            lists of L{twisted.names.dns.RRHeader} (like the return value of
            the I{lookup*} methods of L{IResolver}.  IF C{False}, the result
            will be a L{Message} instance.
        @type filter: L{bool}

        @return: A L{Deferred} which fires with the response or a timeout
            error.
        @rtype: L{Deferred}
        )Úserversr"   )r    r   ÚqueryUDPÚaddCallbackÚfilterAnswers)r   Úqueryr)   ÚtimeoutÚfilterÚrÚds          r   Ú_queryzResolver._queryO   sG   € ð2 ×!Ñ!¨'¸4¿=¹=Ð!ÓIˆØ�J‰J˜�w Ó(ˆÙØ�M‰M˜!Ÿ/™/Ô*Øˆr   c                 óŒ   — |€d}| j                  t        j                  |||«      | j                  «       || j                  «      S )z½
        Implement name lookup by recursively discovering the authoritative
        server for the name and then asking it, starting at one of the servers
        in C{self.hints}.
        )é   é   é   é-   )Ú_discoverAuthorityr   ÚQueryr'   r   )r   ÚnameÚclsÚtyper.   s        r   Ú_lookupzResolver._lookupn   sE   € ð ˆ?ð %ˆGØ×&Ñ&Ü�I‰I�d˜D #Ó&¨¯©«°wÀ×@TÑ@Tó
ð 	
r   c                 ó¶   — |dk  rt        t        j                  d«      «      S | j                  |||d«      }|j	                  | j
                  |||dz
  «       |S )a#  
        Issue a query to a server and follow a delegation if necessary.

        @param query: The query to issue.
        @type query: L{dns.Query}

        @param servers: The servers which might have an answer for this
            query.
        @type servers: L{list} of L{tuple} of L{str} and L{int}

        @param timeout: A C{tuple} of C{int} giving the timeout to use for this
            query.

        @param queriesLeft: A C{int} giving the number of queries which may
            yet be attempted to answer this query before the attempt will be
            abandoned.

        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} giving the response, or with a
            L{Failure} if there is a timeout or response error.
        r   z"Query limit reached without resultFr4   )r   r   ÚResolverErrorr2   r+   Ú_discoveredAuthority)r   r-   r)   r.   ÚqueriesLeftr1   s         r   r8   zResolver._discoverAuthority|   sX   € ð. ˜!ÒÜœ5×.Ñ.Ð/SÓTÓUÐUà�K‰K˜˜w¨°Ó7ˆØ	�‰�d×/Ñ/°¸ÀÈqÁÔQØˆr   c                 ó‚  ‡ ‡‡‡‡‡— |j                   t        j                  k7  r*t         ‰ j	                  |j                   «      |«      «      S i Š|j
                  D ]-  }‰j                  |j                  g «      j                  |«       Œ/ ˆfd„}t        «       }‰j                  }d}		 |j                  |«       |	Š ||‰j                  ‰j                  «      }	|	€||‰j                  k(  rní‰ j                  t        j                  t        |«      ‰j                  ‰j                  «      ‰ j!                  «       ‰‰«      }
ˆfd„}|
j#                  |«       |
S |	j                  ‰j                  k(  r#|j
                  |j$                  |j&                  fS |	j(                  j                  |v rt+        j,                  d«      ‚|	j(                  j                  }�Œ0i }|j&                  D ]Q  }|j                  t        j.                  k(  sŒ!|j(                  j1                  «       ||j                  j                  <   ŒS g }g }|j$                  D ]z  }|j                  t        j2                  k(  sŒ!|j(                  j                  j                  }||v r%|j                  ||   t        j4                  f«       Œj|j                  |«       Œ| |r‰ j                  ‰|‰‰«      S |rB‰ j7                  |d   ‰«      }
d„ }|
j#                  |«       |
j#                  ˆˆˆ ˆfd„«       |
S t        t+        j,                  d«      «      S )	as  
        Interpret the response to a query, checking for error codes and
        following delegations if necessary.

        @param response: The L{Message} received in response to issuing C{query}.
        @type response: L{Message}

        @param query: The L{dns.Query} which was issued.
        @type query: L{dns.Query}.

        @param timeout: The timeout to use if another query is indicated by
            this response.
        @type timeout: L{tuple} of L{int}

        @param queriesLeft: A C{int} giving the number of queries which may
            yet be attempted to answer this query before the attempt will be
            abandoned.

        @return: A L{Failure} indicating a response error, a three-tuple of
            lists of L{twisted.names.dns.RRHeader} giving the response to
            C{query} or a L{Deferred} which will fire with one of those.
        c                 óÀ   •— d }‰j                  | g «      D ]E  }|j                  |k(  sŒ|j                  |k(  r|c S |j                  t        j                  k(  sŒD|}ŒG |S r   )Úgetr;   r<   r   ÚCNAME)r:   r<   r;   ÚcnameÚrecordÚrecordss        €r   ÚfindAnswerOrCNamez8Resolver._discoveredAuthority.<locals>.findAnswerOrCName¹   s[   ø€ ØˆEØ!Ÿ+™+ d¨BÓ/ò '�Ø—:‘: Ó$Ø—{‘{ dÒ*Ø%šØŸ™¬¯	©	Ó1Ø &™ð'ð ˆLr   Nc                 ó>   •— | \  }}}|j                  d‰«       |||fS ©Nr   )Úinsert)ÚresultsÚanswersÚ	authorityÚ
additionalÚpreviouss       €r   Ú
cbResolvedz1Resolver._discoveredAuthority.<locals>.cbResolvedÜ   s*   ø€ Ø9@Ñ6˜ ¨JØŸ™ q¨(Ô3Ø '¨°JÐ?Ð?r   zCycle in CNAME processingr   c                 óH   — | \  }}}|d   j                   j                  «       S rK   )ÚpayloadÚ
dottedQuad)rM   rN   rO   rP   s       r   ÚgetOneAddressz4Resolver._discoveredAuthority.<locals>.getOneAddress   s'   € Ø18Ñ.�˜ JØ˜q‘z×)Ñ)×4Ñ4Ó6Ð6r   c                 óT   •— ‰j                  ‰| t        j                  fg‰‰dz
  «      S )Nr4   )r8   r   r%   )ÚhintrA   r-   r   r.   s    €€€€r   ú<lambda>z/Resolver._discoveredAuthority.<locals>.<lambda>  s+   ø€ ˜T×4Ñ4Ø˜T¤3§8¡8Ð,Ð-¨w¸Àa¹ó€ r   z/Stuck at response without answers or delegation)ÚrCoder   ÚOKr   ÚexceptionForCoderN   Ú
setdefaultr:   ÚappendÚsetÚaddr<   r;   r8   r9   Ústrr'   r+   rO   rP   rT   r   r?   ÚArU   ÚNSr%   ÚlookupAddress)r   Úresponser-   r.   rA   ÚanswerrI   Úseenr:   rG   r1   rR   Ú	addressesÚrrr   ÚtrapsÚnsrV   rQ   rH   s   ` ```             @@r   r@   zResolver._discoveredAuthorityš   sÇ  ý€ ð. �>‰>œSŸV™VÒ#ÜÐ@˜4×0Ñ0°·±Ó@ÀÓJÓKÐKð ˆØ×&Ñ&ò 	?ˆFØ×Ñ˜vŸ{™{¨BÓ/×6Ñ6°vÕ>ð	?ô
	ô ‹uˆØ�z‰zˆØˆØØ�H‰H�TŒNØˆHÙ& t¨U¯Z©Z¸¿¹ÓCˆFØˆ~Ø˜5Ÿ:™:Ò%ð ð ×/Ñ/ÜŸ	™	¤# d£)¨U¯Z©Z¸¿¹ÓCØŸ™›ØØ#ó	�Aô@ð
 —M‘M *Ô-Ø�HØ—‘ §
¡
Ò*Ø ×(Ñ(¨(×*<Ñ*<¸h×>QÑ>QÐRÐRð —>‘>×&Ñ&¨$Ñ.Ü×-Ñ-Ð.IÓJÐJØ—~‘~×*Ñ*�ñE ðJ ˆ	Ø×%Ñ%ò 	BˆBØ�w‰wœ#Ÿ%™%ÓØ*,¯*©*×*?Ñ*?Ó*A�	˜"Ÿ'™'Ÿ,™,Ò'ð	Bð ˆØˆØ×$Ñ$ò 	%ˆBØ�w‰wœ#Ÿ&™&Ó Ø—Z‘Z—_‘_×)Ñ)�Ø˜‘?Ø—L‘L )¨B¡-´·±Ð!:Õ;à—L‘L Õ$ð	%ñ Ø×*Ñ*¨5°%¸À+ÓNÐNÙØ×"Ñ" 5¨¡8¨WÓ5ˆAò7ð �M‰M˜-Ô(Ø�M‰Möôð
 ˆHäÜ×#Ñ#Ð$UÓVóð r   )é
   NN)
r   r   r   r   r   r'   r2   r=   r8   r@   r   r   r   r   r       s&   „ ñó0ò:5òò>
òó<tr   r   c                 ó   ‡ ‡— ˆ ˆfd„}|S )Nc                  ó8   •‡ ‡— ‰j                  ˆ ˆˆfd„«       ‰S )Nc                 ó(   •—  t        | ‰«      ‰i ‰¤ŽS r   )Úgetattr)r0   r   Úkwr:   s    €€€r   rY   z6makePlaceholder.<locals>.placeholder.<locals>.<lambda>  s   ø€ Ð'7¤w¨q°$Ó'7¸Ð'DÀÑ'D€ r   )r+   )r   rq   Údeferredr:   s   ``€€r   Úplaceholderz$makePlaceholder.<locals>.placeholder  s   ú€ Ø×ÑÕDÔEØˆr   r   )rr   r:   rs   s   `` r   ÚmakePlaceholderrt     s   ù€ õð Ðr   c                   ó   — e Zd Zd„ Zd„ Zd„ Zy)ÚDeferredResolverc                 óH   — g | _         |j                  | j                  «       y r   )Úwaitingr+   ÚgotRealResolver)r   ÚresolverDeferreds     r   r   zDeferredResolver.__init__  s   € ØˆŒØ×$Ñ$ T×%9Ñ%9Õ:r   c                 ó�   — | j                   }|j                  | _        |j                  | _        |D ]  }|j                  |«       Œ y r   )rx   Ú__dict__Ú	__class__Úcallback)r   ÚresolverÚwr1   s       r   ry   z DeferredResolver.gotRealResolver  s@   € Ø�L‰LˆØ ×)Ñ)ˆŒØ!×+Ñ+ˆŒØò 	!ˆAØ�J‰J�xÕ ñ	!r   c                 óÎ   — |j                  d«      s|dv rF| j                  j                  t        j                  «       «       t        | j                  d   |«      S t        |«      ‚)NÚlookup)ÚgetHostByNamer-   éÿÿÿÿ)Ú
startswithrx   r^   r   ÚDeferredrt   ÚAttributeError)r   r:   s     r   Ú__getattr__zDeferredResolver.__getattr__%  sP   € Ø�?‰?˜8Ô$¨Ð0JÑ(JØ�L‰L×Ñ¤§¡Ó 0Ô1Ü" 4§<¡<°Ñ#3°TÓ:Ð:Ü˜TÓ"Ð"r   N)r   r   r   r   ry   rˆ   r   r   r   rv   rv     s   „ ò;ò!ó#r   rv   Nc                 ó$  ‡— t        d«      D �cg c]  }t        t        d«      |z   «      ‘Œ }}|D �cg c]  }| j                  d|z  «      ‘Œ }}t	        j
                  |d¬«      }ˆfd„}|j                  |«       t        |«      S c c}w c c}w )aÿ  
    Lookup the root nameserver addresses using the given resolver

    Return a Resolver which will eventually become a C{root.Resolver}
    instance that has references to all the root servers that we were able
    to look up.

    @param resolver: The resolver instance which will be used to
        lookup the root nameserver addresses.
    @type resolver: L{twisted.internet.interfaces.IResolverSimple}

    @param resolverFactory: An optional callable which returns a
        resolver instance. It will passed as the C{resolverFactory}
        argument to L{Resolver.__init__}.
    @type resolverFactory: callable

    @return: A L{DeferredResolver} which will be dynamically replaced
        with L{Resolver} when the root nameservers have been looked up.
    é   Úaz%s.root-servers.netT)ÚconsumeErrorsc                 óV   •— t        | D �cg c]  }|d   sŒ	|d   ‘Œ c}‰¬«      S c c}w )Nr   r4   )r   r#   r   )ÚresÚer#   s     €r   ÚbuildResolverz bootstrap.<locals>.buildResolverD  s-   ø€ ÜØ!$Ö-˜A¨¨!«�1�Q“4Ò-¸ô
ð 	
ùÚ-s   ‹
&–&)ÚrangeÚchrÚordrƒ   r   ÚDeferredListr+   rv   )r   r#   ÚiÚdomainsr1   ÚLr�   s    `     r   Ú	bootstrapr˜   ,  s…   ø€ ô( +0°«)Ö4 QŒs”3�s“8˜a‘<Õ Ð4€GÐ4ØDKÖL¸qˆ×	Ñ	Ð 5¸Ñ 9Õ	:ÐL€AÐLÜ×Ñ˜1¨DÔ1€Aô
ð
 ‡M�M�-Ô ä˜AÓÐùò 5ùÚLs
   �B³Br   )r   Útwisted.internetr   Útwisted.namesr   r   r   Útwisted.python.failurer   r	   r   r   rt   rv   r˜   r   r   r   ú<module>rœ      sK   ðñ
	õ #ß ,Ñ ,Ý *÷ñ ônˆv×"Ñ"ô nòb÷#ñ #ô&r   