ϪfVbdZddlZddlmZddlmZmZddlmZGddejZ y)a` Async DNS server Future plans: - Better config file format maybe - Make sure to differentiate between different classes - notice truncation bit Important: No additional processing is done on some of the record types. This violates the most basic RFC and is just plain annoying for resolvers to deal with. Fix it. @author: Jp Calderone N)protocol)dnsresolve)logceZdZdZej ZdZejZ ddZ dZ dZ dZ dZdZej dddfd Zd Zd Zd Zd ZdZdZdZddZdZy)DNSServerFactorya Server factory and tracker for L{DNSProtocol} connections. This class also provides records for responses to DNS queries. @ivar cache: A L{Cache} instance whose C{cacheResult} method is called when a response is received from one of C{clients}. Defaults to L{None} if no caches are specified. See C{caches} of L{__init__} for more details. @type cache: L{Cache} or L{None} @ivar canRecurse: A flag indicating whether this server is capable of performing recursive DNS resolution. @type canRecurse: L{bool} @ivar resolver: A L{resolve.ResolverChain} containing an ordered list of C{authorities}, C{caches} and C{clients} to which queries will be dispatched. @type resolver: L{resolve.ResolverChain} @ivar verbose: See L{__init__} @ivar connections: A list of all the connected L{DNSProtocol} instances using this object as their controller. @type connections: C{list} of L{DNSProtocol} instances @ivar protocol: A callable used for building a DNS stream protocol. Called by L{DNSServerFactory.buildProtocol} and passed the L{DNSServerFactory} instance as the one and only positional argument. Defaults to L{dns.DNSProtocol}. @type protocol: L{IProtocolFactory} constructor @ivar _messageFactory: A response message constructor with an initializer signature matching L{dns.Message.__init__}. @type _messageFactory: C{callable} Ncg}||j|||j|||j|| |_tj||_||_|r |d|_g|_y)a @param authorities: Resolvers which provide authoritative answers. @type authorities: L{list} of L{IResolver} providers @param caches: Resolvers which provide cached non-authoritative answers. The first cache instance is assigned to C{DNSServerFactory.cache} and its C{cacheResult} method will be called when a response is received from one of C{clients}. @type caches: L{list} of L{Cache} instances @param clients: Resolvers which are capable of performing recursive DNS lookups. @type clients: L{list} of L{IResolver} providers @param verbose: An integer controlling the verbosity of logging of queries and responses. Default is C{0} which means no logging. Set to C{2} to enable logging of full query and response messages. @type verbose: L{int} N)extend canRecurser ResolverChainresolververbosecache connections)self authoritiescachesclientsr resolverss 6/usr/lib/python3/dist-packages/twisted/names/server.py__init__zDNSServerFactory.__init__Es(  "   [ )     V $     W %")k/--i8  DJcN|jdkDrtj|i|yy)z Log a message only if verbose logging is enabled. @param args: Positional arguments which will be passed to C{log.msg} @param kwargs: Keyword arguments which will be passed to C{log.msg} rN)rrmsg)rargskwargss r _verboseLogzDNSServerFactory._verboseLoghs& <1}. @param protocol: The DNS protocol instance to which to send the message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The DNS message to be sent. @type message: L{dns.Message} @param address: The address to which the message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None}  zReplying with no answersz Answers are z Authority is zAdditional is Nz Processed query in %0.3f seconds) rjoinanswersstrpayload authority additionalrr writeMessagertime timeReceived)rrmessageaddressasauthadds r sendReplyzDNSServerFactory.sendReplys!" <1}. @param response: Answer records, authority records and additional records @type response: L{tuple} of L{list} of L{dns.RRHeader} instances @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} )r8rBr0r3r4zLookup found %d record%sr-r;rN) rDrOKr>lenrr cacheResultqueries) rrJrr8r9ansr<r=ls rgotResolverResponsez$DNSServerFactory.gotResolverResponses:"T3,,3663$SV-  x73 Hs4y 3s8 + 3q!q&.S:NB6OOP ::! JJ " "7??1#5T37G H:rc:|jtjtjrtj}n%tj }t j||j||}|j||||jdy)a  A callback used by L{DNSServerFactory.handleQuery} for handling deferred errors from C{self.resolver.query}. Constructs a response message from the original query message by assigning a suitable error code to C{rCode}. An error message will be logged if C{DNSServerFactory.verbose} is C{>1}. @param failure: The reason for the failed resolution (as reported by C{self.resolver.query}). @type failure: L{Failure} @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} )r8rBz Lookup failedN) checkr DomainErrorAuthoritativeDomainErrorENAMEESERVERrerrrDr>r)rfailurerr8r9rBrJs rgotResolverErrorz!DNSServerFactory.gotResolverError*sm4 ==#*F*F GIIEKKE GGG ,,WE,J x73 )rc|jd}|jj|j|j|||j |j |||S)a` Called by L{DNSServerFactory.messageReceived} when a query message is received. Takes the first query from the received message and dispatches it to C{self.resolver.query}. Adds callbacks L{DNSServerFactory.gotResolverResponse} and L{DNSServerFactory.gotResolverError} to the resulting deferred. Note: Multiple queries in a single message are not supported because there is no standard way to respond with multiple rCodes, auth, etc. This is consistent with other DNS server implementations. See U{http://tools.ietf.org/html/draft-ietf-dnsext-edns1-03} for a proposed solution. @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} @return: A C{deferred} which fires with the resolved result or error of the first query in C{message}. @rtype: L{Deferred} r)rPrquery addCallbackrS addErrbackr\)rr8rr9r^s r handleQueryzDNSServerFactory.handleQueryOsXB" MM   & [118Wg N Z--x' J rc|tj|_|j||||j d|y)a# Called by L{DNSServerFactory.messageReceived} when an inverse query message is received. Replies with a I{Not Implemented} error by default. An error message will be logged if C{DNSServerFactory.verbose} is C{>1}. Override in a subclass. @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} zInverse query from NrENOTIMPrBr>rrr8rr9s rhandleInverseQueryz#DNSServerFactory.handleInverseQueryxs5.   x'2 .wk:;rc|tj|_|j||||j d|y)a Called by L{DNSServerFactory.messageReceived} when a status message is received. Replies with a I{Not Implemented} error by default. An error message will be logged if C{DNSServerFactory.verbose} is C{>1}. Override in a subclass. @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} zStatus request from Nrcres r handleStatuszDNSServerFactory.handleStatus5.   x'2 /{;1}. Override in a subclass. @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} zNotify message from Nrcres r handleNotifyzDNSServerFactory.handleNotifyrirctj|_|j||||j d|j |fzy)a0 Called by L{DNSServerFactory.messageReceived} when a message with unrecognised I{OPCODE} is received. Replies with a I{Not Implemented} error by default. An error message will be logged if C{DNSServerFactory.verbose} is C{>1}. Override in a subclass. @param protocol: The DNS protocol instance to which to send a response message. @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param message: The original DNS query message for which a response message will be constructed. @type message: L{dns.Message} @param address: The address to which the response message will be sent or L{None} if C{protocol} is a stream protocol. @type address: L{tuple} or L{None} zUnknown op code (%d) from %rN)rrdrBr>ropCoderes r handleOtherzDNSServerFactory.handleOthers<.   x'2 77>>7:SSTrc tj|_|jr |jdkDr3dj|jDcgc] }t |c}}nQdj|jDcgc],}t jj|jd.c}}t|s5tjd|xs|jjn6tj|d|xs|jj|j|||s)t j |_|j%|||y|j&t j(k(r|j+|||y|j&t j,k(r|j/|||y|j&t j0k(r|j3|||y|j&t j4k(r|j7|||y|j9|||ycc}wcc}w)a L{DNSServerFactory.messageReceived} is called by protocols which are under the control of this L{DNSServerFactory} whenever they receive a DNS query message or an unexpected / duplicate / late DNS response message. L{DNSServerFactory.allowQuery} is called with the received message, protocol and origin address. If it returns L{False}, a C{dns.EREFUSED} response is sent back to the client. Otherwise the received message is dispatched to one of L{DNSServerFactory.handleQuery}, L{DNSServerFactory.handleInverseQuery}, L{DNSServerFactory.handleStatus}, L{DNSServerFactory.handleNotify}, or L{DNSServerFactory.handleOther} depending on the I{OPCODE} of the received message. If C{DNSServerFactory.verbose} is C{>0} all received messages will be logged in more or less detail depending on the value of C{verbose}. @param message: The DNS message that was received. @type message: L{dns.Message} @param proto: The DNS protocol instance which received the message @type proto: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param address: The address from which the message was received. Only provided for messages received by datagram protocols. The origin of Messages received from stream protocols can be gleaned from the protocol C{transport} attribute. @type address: L{tuple} or L{None} r-r.UNKNOWNzEmpty query from z query from N)r6r7rr/rPr1r QUERY_TYPESgettyperNrr transportgetPeer allowQueryEREFUSEDrBr>rmOP_QUERYra OP_INVERSErf OP_STATUSrh OP_NOTIFYrkrn)rr8protor9qr;s rmessageReceivedz DNSServerFactory.messageReceiveds@ $yy{ <<||aHHgoo>c!f>?HHEL__US__((;Uq6+G,Pu7N7N7P+STU1#\'*NU__5L5L5N)QRSww7LLGM NN5'7 3 ^^s|| +   WeW 5 ^^s~~ -  # #GUG < ^^s}} ,   gug 6 ^^s}} ,   gug 6   WeW 5-?Vs I1I c,t|jS)a Called by L{DNSServerFactory.messageReceived} to decide whether to process a received message or to reply with C{dns.EREFUSED}. This default implementation permits anything but empty queries. Override in a subclass to implement alternative policies. @param message: The DNS message that was received. @type message: L{dns.Message} @param protocol: The DNS protocol instance which received the message @type protocol: L{dns.DNSDatagramProtocol} or L{dns.DNSProtocol} @param address: The address from which the message was received. Only provided for messages received by datagram protocols. The origin of Messages received from stream protocols can be gleaned from the protocol C{transport} attribute. @type address: L{tuple} or L{None} @return: L{True} if the received message contained one or more queries, else L{False}. @rtype: L{bool} )rNrPres rrvzDNSServerFactory.allowQuery s27??##r)NNNrr )__name__ __module__ __qualname____doc__r DNSProtocolrrMessagerErrr$r(r+r>rMrDrSr\rarfrhrkrnr~rvrrrrs"JH EkkO!F% **# L!VVTTdPd'IR#*J' R<6=6=6U6:6x$rr) rr6twisted.internetr twisted.namesrrtwisted.pythonr ServerFactoryrrrrrs,  %&^$x--^$r