From: Robert Estelle Date: Thu, 9 Oct 2014 21:51:21 +0000 (-0400) Subject: Support per-nameserver port setting. X-Git-Tag: v1.13.0~24^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55d1abc74c6360d4ae96a8b59e999ba5dc5997ad;p=thirdparty%2Fdnspython.git Support per-nameserver port setting. --- diff --git a/dns/resolver.py b/dns/resolver.py index b16f05d3..ba301f89 100644 --- a/dns/resolver.py +++ b/dns/resolver.py @@ -463,8 +463,8 @@ class Resolver(object): @ivar domain: The domain of this host @type domain: dns.name.Name object @ivar nameservers: A list of nameservers to query. Each nameserver is - a string which contains the IP address of a nameserver. - @type nameservers: list of strings + a tuple containing the IP address and port of of a nameserver. + @type nameservers: list of (str, int) tuples. @ivar search: The search list. If the query name is a relative name, the resolver will construct an absolute query name by appending the search names one by one to the query name. @@ -527,7 +527,6 @@ class Resolver(object): self.domain = dns.name.root self.nameservers = [] self.search = [] - self.port = 53 self.timeout = 2.0 self.lifetime = 30.0 self.keyring = None @@ -551,7 +550,7 @@ class Resolver(object): except IOError: # /etc/resolv.conf doesn't exist, can't be read, etc. # We'll just use the default resolver configuration. - self.nameservers = ['127.0.0.1'] + self.nameservers = [('127.0.0.1', 53)] return want_close = True else: @@ -564,7 +563,7 @@ class Resolver(object): if len(tokens) == 0: continue if tokens[0] == 'nameserver': - self.nameservers.append(tokens[1]) + self.nameservers.append((tokens[1], 53)) elif tokens[0] == 'domain': self.domain = dns.name.from_text(tokens[1]) elif tokens[0] == 'search': @@ -577,7 +576,7 @@ class Resolver(object): if want_close: f.close() if len(self.nameservers) == 0: - self.nameservers.append('127.0.0.1') + self.nameservers.append(('127.0.0.1', 53)) def _determine_split_char(self, entry): # @@ -599,9 +598,9 @@ class Resolver(object): # we call str() on nameservers to convert it from unicode to ascii nameservers = str(nameservers) split_char = self._determine_split_char(nameservers) - ns_list = nameservers.split(split_char) + ns_list = [(ns, 53) for ns in nameservers.split(split_char)] for ns in ns_list: - if not ns in self.nameservers: + if ns not in self.nameservers: self.nameservers.append(ns) def _config_win32_domain(self, domain): @@ -853,18 +852,18 @@ class Resolver(object): while response is None: if len(nameservers) == 0: raise NoNameservers(request=request, errors=errors) - for nameserver in nameservers[:]: + for nameserver, port in nameservers[:]: timeout = self._compute_timeout(start) try: tcp_attempt = tcp if tcp: response = dns.query.tcp(request, nameserver, - timeout, self.port, + timeout, port, source=source, source_port=source_port) else: response = dns.query.udp(request, nameserver, - timeout, self.port, + timeout, port, source=source, source_port=source_port) if response.flags & dns.flags.TC: @@ -872,7 +871,7 @@ class Resolver(object): tcp_attempt = True timeout = self._compute_timeout(start) response = dns.query.tcp(request, nameserver, - timeout, self.port, + timeout, port, source=source, source_port=source_port) except (socket.error, dns.exception.Timeout) as ex: @@ -880,7 +879,7 @@ class Resolver(object): # Communication failure or timeout. Go to the # next server # - errors.append((nameserver, tcp_attempt, self.port, ex, + errors.append((nameserver, tcp_attempt, port, ex, response)) response = None continue @@ -888,7 +887,7 @@ class Resolver(object): # # Who knows? Keep going. # - errors.append((nameserver, tcp_attempt, self.port, ex, + errors.append((nameserver, tcp_attempt, port, ex, response)) response = None continue @@ -898,8 +897,8 @@ class Resolver(object): # saying. Take it out of the mix and # continue. # - nameservers.remove(nameserver) - errors.append((nameserver, tcp_attempt, self.port, ex, + nameservers.remove((nameserver, port)) + errors.append((nameserver, tcp_attempt, port, ex, response)) response = None continue @@ -910,15 +909,15 @@ class Resolver(object): # they're supposed to!). Take it out of the # mix and continue. # - nameservers.remove(nameserver) - errors.append((nameserver, tcp_attempt, self.port, ex, + nameservers.remove((nameserver, port)) + errors.append((nameserver, tcp_attempt, port, ex, response)) response = None continue rcode = response.rcode() if rcode == dns.rcode.YXDOMAIN: ex = YXDOMAIN() - errors.append((nameserver, tcp_attempt, self.port, ex, + errors.append((nameserver, tcp_attempt, port, ex, response)) raise ex if rcode == dns.rcode.NOERROR or \ @@ -930,8 +929,8 @@ class Resolver(object): # the rcode isn't SERVFAIL. # if rcode != dns.rcode.SERVFAIL or not self.retry_servfail: - nameservers.remove(nameserver) - errors.append((nameserver, tcp_attempt, self.port, + nameservers.remove((nameserver, port)) + errors.append((nameserver, tcp_attempt, port, dns.rcode.to_text(rcode), response)) response = None if not response is None: diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 6be955b7..dfc85ddc 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -57,7 +57,8 @@ class BaseResolverTests(object): def testRead(self): f = cStringIO.StringIO(resolv_conf) r = dns.resolver.Resolver(f) - self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and + self.failUnless(r.nameservers == [('10.0.0.1', 53), + ('10.0.0.2', 53)] and r.domain == dns.name.from_text('foo')) def testCacheExpiration(self):