
    Ϫf0                         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$    
 *.42SXX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JJw(MM!//*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&&IIdD#&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KK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!++dB/ '::${{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qz))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T388,-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   . >>SVV#@400@JKK && 	?Fv{{B/66v>	?
	 uzzHHTNH&tUZZCF~5::%  //		#d)UZZC#	A@
 MM*-H

* (((*<*<h>Q>QRR >>&&$.--.IJJ~~**E J 	%% 	BBww#%%*,***?*?*A	"'',,'	B $$ 	%Bww#&& ZZ__))?LL)B-!:;LL$	% **5%+NN""58W5A7 MM-(MM
 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    '7wq$'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@    LL ))!++ 	!AJJx 	!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LL 01"4<<#3T::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!1Q4-
 	
-s   
&&)rangechrordr   r   DeferredListr+   rv   )r   r#   idomainsr1   Lr   s    `     r   	bootstrapr   ,  s    ( +0)4Qs3s8a< 4G4DKLq		 5 9	:LAL1D1A

 MM- 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   