
    \d0                         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dS )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dS )_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                     d S N )selfargss     2lib/python3.11/site-packages/twisted/names/root.pymessageReceivedz _DummyController.messageReceived   s        N)__name__
__module____qualname____doc__r   r   r   r   r	   r	      s-             r   r	   c                   8    e Zd ZdZd
dZd Zd Zd Zd Zd	 Z	dS )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                            |            || _        || _        || _        |ddlm} || _        dS )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__+   sW    * 	$$T***
-"HHHHHH /r   c                 $    d | j         D             S )z
        Return a list of two-tuples representing the addresses of the root
        servers, as defined by C{self.hints}.
        c                 *    g | ]}|t           j        fS r   )r   PORT).0ips     r   
<listcomp>z#Resolver._roots.<locals>.<listcomp>M   s    4442SX444r   )r   )r   s    r   _rootszResolver._rootsH   s    
 544444r   c                     |                      || j                  }|                    |g|          }|r|                    |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   sT    2 !!'4=!IIJJw(( 	+MM!/***r   c                     |d}|                      t          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}.
        N)         -   )_discoverAuthorityr   Queryr+   r   )r   nameclstyper2   s        r   _lookupzResolver._lookupn   sJ     ? %G&&IdD#&&w@T
 
 	
r   c                     |dk    r!t          t          j        d                    S |                     |||d          }|                    | 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 resultFr8   )r   r   ResolverErrorr6   r/   _discoveredAuthority)r   r1   r-   r2   queriesLeftr5   s         r   r<   zResolver._discoverAuthority|   sd    . !5./STTUUUKKw77	d/qQQQr   c                     |j         t          j        k    r0t                                |j                   |                    S i |j        D ]0}                    |j        g                               |           1fd}t                      }j        }d}		 |
                    |           |	 ||j        j                  }	|	}|j        k    rnŉ                     t          j        t          |          j        j                                                             }
fd}|
                    |           |
S |	j        j        k    r|j        |j        |j        fS |	j        j        |v rt+          j        d          |	j        j        }i }|j        D ]=}|j        t          j        k    r&|j                                        ||j        j        <   >g }g }|j        D ]i}|j        t          j        k    rR|j        j        j        }||v r(|                    ||         t          j        f           T|                    |           j|r                     |          S |rQ                     |d                   }
d }|
                    |           |
                     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 }                     | g           D ]3}|j        |k    r&|j        |k    r|c S |j        t          j        k    r|}4|S r   )getr?   r@   r   CNAME)r>   r@   r?   cnamerecordrecordss        r   findAnswerOrCNamez8Resolver._discoveredAuthority.<locals>.findAnswerOrCName   sd    E!++dB// ' ':$${d**%	11 & Lr   NTc                 F    | \  }}}|                     d           |||fS Nr   )insert)resultsanswers	authority
additionalpreviouss       r   
cbResolvedz1Resolver._discoveredAuthority.<locals>.cbResolved   s0    9@6Jq(333 'J??r   zCycle in CNAME processingr   c                 L    | \  }}}|d         j                                         S rO   )payload
dottedQuad)rQ   rR   rS   rT   s       r   getOneAddressz4Resolver._discoveredAuthority.<locals>.getOneAddress   s'    18.Jqz)44666r   c                 T                         | t          j        fgdz
            S )Nr8   )r<   r   r'   )hintrE   r1   r   r2   s    r   <lambda>z/Resolver._discoveredAuthority.<locals>.<lambda>  s.    T44T38,-wa  r   z/Stuck at response without answers or delegation)rCoder   OKr   exceptionForCoderR   
setdefaultr>   appendsetaddr@   r?   r<   r=   strr+   r/   rS   rT   rX   r   rC   ArY   NSr'   lookupAddress)r   responser1   r2   rE   answerrM   seenr>   rK   r5   rV   	addressesrrr   trapsnsrZ   rU   rL   s   ` ```             @@r   rD   zResolver._discoveredAuthority   sQ   . >SV##@400@@JJKKK & 	? 	?Fv{B//66v>>>>
	 
	 
	 
	 
	 uuz"	+HHTNNNH&&tUZCCF~5:%%  //	#d))UZCC#	 A@ @ @ @ @
 MM*---H
** ((*<h>QRR >&$..-.IJJJ~*E"	+J 	% 	B 	BBw#%*,**?*?*A*A	"','$ 	% 	%Bw#&  Z_)??LL)B-!:;;;;LL$$$ 	**5%+NNN 	""58W55A7 7 7 MM-(((MM        
 H#$UVV  r   )r   NN)
r   r   r   r   r   r+   r6   rA   r<   rD   r   r   r   r   r       s         0 0 0 0:5 5 5  >
 
 
  <t t t t tr   r   c                       fd}|S )Nc                  @                           fd           S )Nc                 0     t          |           i S r   )getattr)r4   r   kwr>   s    r   r]   z6makePlaceholder.<locals>.placeholder.<locals>.<lambda>  s!    '7wq$'7'7'D'D'D r   )r/   )r   rt   deferredr>   s   ``r   placeholderz$makePlaceholder.<locals>.placeholder  s.    DDDDDDEEEr   r   )ru   r>   rv   s   `` r   makePlaceholderrw     s*          r   c                        e Zd Zd Zd Zd ZdS )DeferredResolverc                 H    g | _         |                    | j                   d S r   )waitingr/   gotRealResolver)r   resolverDeferreds     r   r   zDeferredResolver.__init__  s&    $$T%9:::::r   c                 x    | j         }|j        | _        |j        | _        |D ]}|                    |           d S r   )r{   __dict__	__class__callback)r   resolverwr5   s       r   r|   z DeferredResolver.gotRealResolver  sK    L )!+ 	! 	!AJJx    	! 	!r   c                     |                     d          s|dv rF| j                            t          j                               t          | j        d         |          S t          |          )Nlookup)getHostByNamer1   )
startswithr{   rb   r   Deferredrw   AttributeError)r   r>   s     r   __getattr__zDeferredResolver.__getattr__%  sd    ??8$$ 	;0J(J(JL 0 0111"4<#3T:::T"""r   N)r   r   r   r   r|   r   r   r   r   ry   ry     sA        ; ; ;! ! !# # # # #r   ry   Nc                      d t          d          D             } fd|D             }t          j        |d          }fd}|                    |           t	          |          S )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.
    c                 L    g | ]!}t          t          d           |z             "S )a)chrord)r(   is     r   r*   zbootstrap.<locals>.<listcomp>@  s*    444Qs3s88a<  444r      c                 @    g | ]}                     d |z            S )z%s.root-servers.net)r   )r(   r5   r   s     r   r*   zbootstrap.<locals>.<listcomp>A  s-    LLLq		 5 9	:	:LLLr   T)consumeErrorsc                 :    t          d | D                       S )Nc                 .    g | ]}|d          
|d         S )r   r8   r   )r(   es     r   r*   z4bootstrap.<locals>.buildResolver.<locals>.<listcomp>F  s%    ---A!-1Q4---r   )r   r$   r   )resr$   s    r   buildResolverz bootstrap.<locals>.buildResolverD  s-    -----
 
 
 	
r   )ranger   DeferredListr/   ry   )r   r$   domainsLr5   r   s   ``    r   	bootstrapr   ,  s    ( 54%))444GLLLLGLLLA1D111A
 
 
 
 

 MM-   Ar   r   )r   twisted.internetr   twisted.namesr   r   r   twisted.python.failurer   r	   r   r   rw   ry   r   r   r   r   <module>r      s  
	 	 # " " " " " , , , , , , , , , , * * * * * *       n n n n nv" n n nb  # # # # # # # #&     r   