Twisted dns not working

I would like to know why the following does not work.

from twisted internet import defer, reactor from twisted.python.failure import Failure import twisted.names.client def do_lookup(do_lookup): d = twisted.names.client.getHostByName(domain) d.addBoth(lookup_done) def lookup_done(result): print 'result:', result reactor.stop() domain = 'twistedmatrix.com' reactor.callLater(0, do_lookup, domain) reactor.run() 

Results in:

 result: [Failure instance: Traceback (failure with no frames): <class 'twisted.names.error.ResolverError'>: Stuck at response without answers or delegation ] 
+4
source share
3 answers

Correct your example to the following, so that it is syntactically correct:

 from twisted.internet import reactor import twisted.names.client def do_lookup(domain): d = twisted.names.client.getHostByName(domain) d.addBoth(lookup_done) def lookup_done(result): print 'result:', result reactor.stop() domain = 'twistedmatrix.com' reactor.callLater(0, do_lookup, domain) reactor.run() 

I get:

 $ python so-example.py result: 66.35.39.65 

So, to answer your question: your local DNS infrastructure is broken, not twisted.names. Or there may be a mistake. You will need to track it further.

+3
source

At the time of this writing, this fails on Windows because it uses an invalid path for the Windows host file (in twisted.names.client.createResolver It uses 'c: \ windows \ hosts'. This was fine for windows 98 and Me (link here ), but it doesn’t work out with a β€œmodern” version like XP.

Today it should probably use something like:

 hosts = os.path.join( os.environ.get('systemroot','C:\\Windows'), r'system32\drivers\etc\hosts' ) 

I think this only partially solves the problem (or maybe it's a red herring).

Now this will only work for the names actually specified in this hosts file. Most likely, it should be some kind of registry query for the DNS server, and then a query to actually search for the DNS name.

This recipe looks promising for getting the actual DNS server.

+5
source

I understood something why the explicit client.createResolver(servers) did not work on our corporate Windows machines. Into the guts Twisted createResolver is an os-dependent branch:

 def createResolver(servers=None, resolvconf=None, hosts=None): ... from twisted.names import resolve, cache, root, hosts as hostsModule if platform.getType() == 'posix': if resolvconf is None: resolvconf = '/etc/resolv.conf' if hosts is None: hosts = '/etc/hosts' theResolver = Resolver(resolvconf, servers) hostResolver = hostsModule.Resolver(hosts) else: if hosts is None: hosts = r'c:\windows\hosts' from twisted.internet import reactor bootstrap = _ThreadedResolverImpl(reactor) hostResolver = hostsModule.Resolver(hosts) theResolver = root.bootstrap(bootstrap) L = [hostResolver, cache.CacheResolver(), theResolver] return resolve.ResolverChain(L) 

The first warning sign for Windows is that the servers argument is not used, so user DNS servers are ignored. It follows that _ThreadedResolverImpl (), which uses platform-specific code, is wrapped in root.bootstrap() before being added to the recognizer chain.

The purpose of root.bootstrap is to use the platform recognition tool to search for a.root-servers.net, b.root-servers.net, etc. using a synchronous Windows platform resolver (which works and returns IP addresses), and then make direct DNS queries against root servers. UDP packets running on root servers are then blocked by our corporate firewall - I see them in Wireshark.

By default, the call to getResolver () used by the names .client.getHostByName () calls directly createResolver() , which can again lead to this broken setting loaded by the working DNS setting. For most environments, I think that adding Resolver (with root or explicit servers) to ResolverChain along with _ThreadedResolverImpl as backup will work, except that the platform converter is a different interface.

Here's an example of asynchronously locating local DNS servers (by analyzing ipconfig output), and then installing a custom resolver to use them.

 import sys from twisted.python import log from twisted.names import root, hosts, resolve, cache, client from twisted.python.runtime import platform from twisted.internet import reactor from twisted.internet import utils import re def parseIpconfigDNSServers(output): servers = [] found = False for line in output.split('\n'): if 'DNS Servers . . . . . . . . . . . :' in line or (found and not '. . . .' in line): servers.append(line[38:].strip()) found = True else: found = False log.msg( 'Windows: Detected DNS servers %s' % (str(servers))) return servers if platform.getType() != 'posix': d = utils.getProcessOutput(os.path.join(os.environ['WINDIR'], 'system32', 'ipconfig.exe'), ["/all"]) d.addCallback(parseIpconfigDNSServers) d.addCallback(lambda r: client.Resolver(servers=[(h, 53) for h in r])) d.addErrback(log.msg) theResolver = root.DeferredResolver(d) client.theResolver = resolve.ResolverChain([cache.CacheResolver(), theResolver]) if __name__ == '__main__': log.startLogging(sys.stdout) def do_lookup(domain): d = client.getHostByName(domain) d.addBoth(log.msg) from twisted.internet import reactor reactor.callLater(0, do_lookup, 'example.com') reactor.run() 

I cleaned it and posted it here https://gist.github.com/shuckc/af7490e1c4a2652ca740

+1
source

All Articles