o b0@stdZddlmZddlmZmZmZddlmZGdddZ Gdddej Z d d Z Gd d d Z dddZd 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)commondnserror)Failurec@seZdZdZddZdS)_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. cGsdSN)selfargsr r 4/usr/lib/python3/dist-packages/twisted/names/root.pymessageReceivedsz _DummyController.messageReceivedN)__name__ __module__ __qualname____doc__r r r r r rs rc@sBeZdZdZdddZddZdd Zd d Zd d ZddZ dS)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__} NcCs<tj|||_||_||_|durddlm}||_dS)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 Nrr) r ResolverBase__init__hints_maximumQueries_reactortwisted.names.clientr_resolverFactory)r rmaximumQueriesreactorresolverFactoryr r r r+s   zResolver.__init__cCsdd|jDS)z Return a list of two-tuples representing the addresses of the root servers, as defined by C{self.hints}. cSsg|]}|tjfqSr )rPORT).0ipr r r Msz#Resolver._roots..)r)r r r r _rootsHszResolver._rootscCs2|j||jd}||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)rrqueryUDP addCallback filterAnswers)r queryr$timeoutfilterrdr r r _queryOs  zResolver._querycCs,|durd}|t||||||jS)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) -)_discoverAuthorityrQueryr#r)r nameclstyper)r r r _lookupns zResolver._lookupcCs@|dkr ttdS||||d}||j|||d|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. rz"Query limit reached without resultFr.)rr ResolverErrorr-r&_discoveredAuthority)r r(r$r) queriesLeftr,r r r r2|s zResolver._discoverAuthoritycs|jtjkrt|j|Si|jD] }|jg|qfdd}t }j}d} | || ||j j } | durj|jkrJn> tt|j j } fdd} | | | S| j j krx|j|j|jfS| jj|vrtd| jj}q1i} |jD]} | j tjkr| j| | jj<qg}g}|jD]!} | j tjkr| jjj}|| vr|| |tjfq||q|r҈ |S|r|d} d d }| || fd d | Sttd 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. csFd}|gD]}|j|kr |j|kr|S|jtjkr |}q|Sr)getr5r6rCNAME)r4r6r5cnamerecord)recordsr r findAnswerOrCNames   z8Resolver._discoveredAuthority..findAnswerOrCNameNTcs |\}}}|d|||fSNr)insertresultsanswers authority additional)previousr r cbResolveds   z1Resolver._discoveredAuthority..cbResolvedzCycle in CNAME processingrcSs|\}}}|djSrA)payload dottedQuadrCr r r getOneAddresss z4Resolver._discoveredAuthority..getOneAddresscs|tjfgdS)Nr.)r2rr)hint)r:r(r r)r r sz/Resolver._discoveredAuthority..z/Stuck at response without answers or delegation)rCoderOKrexceptionForCoderE setdefaultr4appendsetaddr6r5r2r3strr#r&rFrGrJrr8ArKNSr lookupAddress)r responser(r)r:answerr@seenr4r>r,rI addressesrrrtrapsnsrLr )rHr:r(r?r r)r r9st          %       zResolver._discoveredAuthority)rNN) rrrrrr#r-r7r2r9r r r r r s  rcsfdd}|S)NcsfddS)Ncst|iSr)getattr)r+)r kwr4r r rNsz6makePlaceholder..placeholder..)r&r rbdeferredr4rcr placeholdersz$makePlaceholder..placeholderr )rer4rfr rdr makePlaceholdersrgc@s$eZdZddZddZddZdS)DeferredResolvercCsg|_||jdSr)waitingr&gotRealResolver)r resolverDeferredr r r rszDeferredResolver.__init__cCs.|j}|j|_|j|_|D]}||q dSr)ri__dict__ __class__callback)r resolverwr,r r r rjs  z DeferredResolver.gotRealResolvercCs:|ds |dvr|jtt|jd|St|)Nlookup) getHostByNamer() startswithrirSrDeferredrgAttributeError)r r4r r r __getattr__%szDeferredResolver.__getattr__N)rrrrrjrwr r r r rhs rhNcsPddtdD}fdd|D}tj|dd}fdd}||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. cSsg|] }ttd|qS)a)chrord)r ir r r r"@zbootstrap.. csg|] }d|qS)z%s.root-servers.net)rr)r r,)ror r r"AsT) consumeErrorscstdd|DdS)NcSsg|] }|dr|dqS)rr.r )r er r r r"Fr|z4bootstrap..buildResolver..)rrr)res)rr r buildResolverDsz bootstrap..buildResolver)ranger DeferredListr&rh)rordomainsLr,rr )rorr bootstrap,s   rr)rtwisted.internetr twisted.namesrrrtwisted.python.failurerrrrrgrhrr r r r s   r