summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2020-07-27 17:19:11 -0700
committerBob Halley <halley@dnspython.org>2020-07-27 17:19:11 -0700
commit698e4f1c527601f2bf9ecd1d4de27cb389703ca8 (patch)
treed4bea2d1b567f05bf7c1d549aabae58604208231
parent239bb54b3ac4761921470d6f1962a05ccf69db00 (diff)
downloaddnspython-698e4f1c527601f2bf9ecd1d4de27cb389703ca8.tar.gz
Apply the resolver search list, domain, and ndots settings in the same way
that the BIND stub resolver library does.
-rw-r--r--dns/resolver.py42
-rw-r--r--tests/test_resolver.py24
2 files changed, 56 insertions, 10 deletions
diff --git a/dns/resolver.py b/dns/resolver.py
index 46ca30a..9600c8e 100644
--- a/dns/resolver.py
+++ b/dns/resolver.py
@@ -788,9 +788,15 @@ class Resolver:
self.nameservers.append(tokens[1])
elif tokens[0] == 'domain':
self.domain = dns.name.from_text(tokens[1])
+ # domain and search are exclusive
+ self.search = []
elif tokens[0] == 'search':
+ # the last search wins
+ self.search = []
for suffix in tokens[1:]:
self.search.append(dns.name.from_text(suffix))
+ # We don't set domain as it is not used if
+ # len(self.search) > 0
elif tokens[0] == 'options':
for opt in tokens[1:]:
if opt == 'rotate':
@@ -989,14 +995,34 @@ class Resolver:
if qname.is_absolute():
qnames_to_try.append(qname)
else:
- if len(qname) > 1 or not search:
- qnames_to_try.append(qname.concatenate(dns.name.root))
- if search and self.search:
- for suffix in self.search:
- if self.ndots is None or len(qname.labels) >= self.ndots:
- qnames_to_try.append(qname.concatenate(suffix))
- elif search:
- qnames_to_try.append(qname.concatenate(self.domain))
+ abs_qname = qname.concatenate(dns.name.root)
+ if search:
+ if len(self.search) > 0:
+ # There is a search list, so use it exclusively
+ search_list = self.search[:]
+ elif self.domain != dns.name.root and self.domain is not None:
+ # We have some notion of a domain that isn't the root, so
+ # use it as the search list.
+ search_list = [self.domain]
+ else:
+ search_list = []
+ # Figure out the effective ndots (default is 1)
+ if self.ndots is None:
+ ndots = 1
+ else:
+ ndots = self.ndots
+ for suffix in search_list:
+ qnames_to_try.append(qname + suffix)
+ if len(qname) > ndots:
+ # The name has at least ndots dots, so we should try an
+ # absolute query first.
+ qnames_to_try.insert(0, abs_qname)
+ else:
+ # The name has less than ndots dots, so we should search
+ # first, then try the absolute name.
+ qnames_to_try.append(abs_qname)
+ else:
+ qnames_to_try.append(abs_qname)
return qnames_to_try
def resolve(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
diff --git a/tests/test_resolver.py b/tests/test_resolver.py
index d61e8c9..4f5643d 100644
--- a/tests/test_resolver.py
+++ b/tests/test_resolver.py
@@ -514,7 +514,7 @@ class BaseResolverTests(unittest.TestCase):
qnames = res._get_qnames_to_try(qname, True)
self.assertEqual(qnames,
[dns.name.from_text(x) for x in
- ['www.dnspython.org', 'www.dnspython.net']])
+ ['www.dnspython.org', 'www.dnspython.net', 'www.']])
qnames = res._get_qnames_to_try(qname, False)
self.assertEqual(qnames,
[dns.name.from_text('www.')])
@@ -528,7 +528,27 @@ class BaseResolverTests(unittest.TestCase):
qnames = res._get_qnames_to_try(qname, None)
self.assertEqual(qnames,
[dns.name.from_text(x) for x in
- ['www.dnspython.org', 'www.dnspython.net']])
+ ['www.dnspython.org', 'www.dnspython.net', 'www.']])
+ #
+ # Now test ndots
+ #
+ qname = dns.name.from_text('a.b', None)
+ res.ndots = 1
+ qnames = res._get_qnames_to_try(qname, True)
+ self.assertEqual(qnames,
+ [dns.name.from_text(x) for x in
+ ['a.b', 'a.b.dnspython.org', 'a.b.dnspython.net']])
+ res.ndots = 2
+ qnames = res._get_qnames_to_try(qname, True)
+ self.assertEqual(qnames,
+ [dns.name.from_text(x) for x in
+ ['a.b.dnspython.org', 'a.b.dnspython.net', 'a.b']])
+ qname = dns.name.from_text('a.b.c', None)
+ qnames = res._get_qnames_to_try(qname, True)
+ self.assertEqual(qnames,
+ [dns.name.from_text(x) for x in
+ ['a.b.c', 'a.b.c.dnspython.org',
+ 'a.b.c.dnspython.net']])
def testSearchListsAbsolute(self):
res = dns.resolver.Resolver(configure=False)