
    h0                         S r SSKJr  SSKJrJrJr  SSKJr   " S S5      r	 " S S\R                  5      rS	 r " S
 S5      rSS jrg)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                       \ rS rSrSrS rSrg)_DummyController   z
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                     g N )selfargss     Y/root/1688_scrapy/alibaba-scraper/venv/lib/python3.13/site-packages/twisted/names/root.pymessageReceived _DummyController.messageReceived   s        r   N)__name__
__module____qualname____firstlineno____doc__r   __static_attributes__r   r   r   r	   r	      s    r   r	   c                   @    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
rg)Resolver    aS  
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                     [         R                  R                  U 5        Xl        X l        X0l        Uc  SSKJn  X@l        g)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    Resolver.__init__+   s7    * 	$$T*
-"H /r   c                 d    U R                    Vs/ s H  o[        R                  4PM     sn$ s  snf )zj
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   _rootsResolver._rootsH   s&    
 *.42SXX444s   -c                     U R                  X R                  S9nUR                  U/U5      nU(       a  UR                  UR                  5        U$ )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   queryr0   timeoutfilterrds          r   _queryResolver._queryO   sE    2 !!'==!IJJw(MM!//*r   c                     Uc  SnU R                  [        R                  " XU5      U R                  5       X@R                  5      $ )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typer5   s        r   _lookupResolver._lookupn   sA     ? %G&&IId#&w@T@T
 	
r   c                     US::  a  [        [        R                  " S5      5      $ U R                  XUS5      nUR	                  U R
                  XUS-
  5        U$ )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 resultFr<   )r   r   ResolverErrorr9   r2   _discoveredAuthority)r   r4   r0   r5   queriesLeftr8   s         r   r@   Resolver._discoverAuthority|   sT    . !5../STUUKK7	d//qQr   c                   ^ ^^^^^ UR                   [        R                  :w  a*  [        T R	                  UR                   5      " U5      5      $ 0 mUR
                   H.  nTR                  UR                  / 5      R                  U5        M0     U4S jn[        5       nTR                  nSn	 UR                  U5        U	mU" UTR                  TR                  5      n	U	c  UTR                  :X  a  OT R                  [        R                  " [        U5      TR                  TR                  5      T R!                  5       TT5      n
U4S jnU
R#                  U5        U
$ U	R                  TR                  :X  a#  UR
                  UR$                  UR&                  4$ U	R(                  R                  U;   a  [*        R,                  " S5      eU	R(                  R                  nGM9  0 nUR&                   HS  nUR                  [        R.                  :X  d  M#  UR(                  R1                  5       XR                  R                  '   MU     / n/ nUR$                   H  nUR                  [        R2                  :X  d  M#  UR(                  R                  R                  nUU;   a&  UR                  UU   [        R4                  45        Mo  UR                  U5        M     U(       a  T R                  TUTT5      $ U(       aC  T R7                  US   T5      n
S nU
R#                  U5        U
R#                  UUU U4S j5        U
$ [        [*        R,                  " S5      5      $ )	a  
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                    > S nTR                  U / 5       HK  nUR                  U:X  d  M  UR                  U:X  a  Us  $ UR                  [        R                  :X  d  MI  UnMM     U$ r   )getrC   rD   r   CNAME)rB   rD   rC   cnamerecordrecordss        r   findAnswerOrCName8Resolver._discoveredAuthority.<locals>.findAnswerOrCName   sV    E!++dB/::${{d*%		1 & 0 Lr   Nc                 :   > U u  pnUR                  ST5        XU4$ Nr   )insert)resultsanswers	authority
additionalpreviouss       r   
cbResolved1Resolver._discoveredAuthority.<locals>.cbResolved   s&    9@6Jq(3 'J??r   zCycle in CNAME processingr   c                 F    U u  pnUS   R                   R                  5       $ rV   )payload
dottedQuad)rX   rY   rZ   r[   s       r   getOneAddress4Resolver._discoveredAuthority.<locals>.getOneAddress   s%    18.Jqz))4466r   c                 T   > TR                  TU [        R                  4/TTS-
  5      $ )Nr<   )r@   r   r+   )hintrJ   r4   r   r5   s    r   <lambda>/Resolver._discoveredAuthority.<locals>.<lambda>  s)    T44T388,-war   z/Stuck at response without answers or delegation)rCoder   OKr   exceptionForCoderY   
setdefaultrB   appendsetaddrD   rC   r@   rA   strr-   r2   rZ   r[   r`   r   rH   Ara   NSr+   lookupAddress)r   responser4   r5   rJ   answerrS   seenrB   rQ   r8   r]   	addressesrrr!   trapsnsrb   r\   rR   s   ` ```             @@r   rI   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ww#%%*,***?*?*A	'',,' & $$Bww#&& ZZ__))?LL)B-!:;LL$ % **5%+NN""58W5A7 MM-(MM
 H##$UV r   )r"   r#   r%   r!   )
   NN)r   r   r   r   r   r    r-   r9   rE   r@   rI   r   r   r   r   r   r       s&    0:5>
<tr   r   c                    ^ ^ U U4S jnU$ )Nc                  :   >^ ^ TR                  U UU4S j5        T$ )Nc                 (   > [        U T5      " T0 TD6$ r   )getattr)r7   r   kwrB   s    r   rf   6makePlaceholder.<locals>.placeholder.<locals>.<lambda>  s    wq$'7'D'Dr   )r2   )r   r   deferredrB   s   ``r   placeholder$makePlaceholder.<locals>.placeholder  s    DEr   r   )r   rB   r   s   `` r   makePlaceholderr     s     r   c                   &    \ rS rSrS rS rS rSrg)DeferredResolveri  c                 H    / U l         UR                  U R                  5        g r   )waitingr2   gotRealResolver)r   resolverDeferreds     r   r    DeferredResolver.__init__  s    $$T%9%9:r   c                     U R                   nUR                  U l        UR                  U l        U H  nUR                  U5        M     g r   )r   __dict__	__class__callback)r   resolverwr8   s       r   r    DeferredResolver.gotRealResolver  s;    LL ))!++AJJx  r   c                     UR                  S5      (       d  US;   aG  U R                  R                  [        R                  " 5       5        [        U R                  S   U5      $ [        U5      e)Nlookup)getHostByNamer4   )
startswithr   rl   r   Deferredr   AttributeError)r   rB   s     r   __getattr__DeferredResolver.__getattr__%  sS    ??8$$0J(JLL 01"4<<#3T::T""r   )r   r   r   N)r   r   r   r   r    r   r   r   r   r   r   r   r     s    ;!#r   r   Nc                 ,  ^ [        S5       Vs/ s H  n[        [        S5      U-   5      PM     nnU Vs/ s H  o@R                  SU-  5      PM     nn[        R
                  " USS9nU4S jnUR                  U5        [        U5      $ s  snf s  snf )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                 `   > [        U  Vs/ s H  oS   (       d  M  US   PM     snTS9$ s  snf )Nr   r<   )r!   r(   r   )reser(   s     r   buildResolver bootstrap.<locals>.buildResolverD  s1    !$-A!41Q4-
 	
-s   +	+)rangechrordr   r   DeferredListr2   r   )r   r(   idomainsr8   Lr   s    `     r   	bootstrapr   ,  s    ( +0)4)Qs3s8a< )G4DKLGq		 5 9	:GAL1D1A

 MM- A 5Ls
   !BBr   )r   twisted.internetr   twisted.namesr   r   r   twisted.python.failurer   r	   r   r   r   r   r   r   r   r   <module>r      sK   
	 # , , * nv"" nb# #&r   