From: Bob Halley Date: Wed, 27 May 2020 20:30:05 +0000 (-0700) Subject: further tighten resolve() default settings X-Git-Tag: v2.0.0rc1~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f952afd92b0aa75fd59f6cb187d76a4ae0dffd16;p=thirdparty%2Fdnspython.git further tighten resolve() default settings --- diff --git a/dns/resolver.py b/dns/resolver.py index 089021d3..20356685 100644 --- a/dns/resolver.py +++ b/dns/resolver.py @@ -987,13 +987,13 @@ class Resolver(object): if qname.is_absolute(): qnames_to_try.append(qname) else: - if len(qname) > 1: + 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)) - else: + elif search: qnames_to_try.append(qname.concatenate(self.domain)) return qnames_to_try @@ -1025,10 +1025,12 @@ class Resolver(object): *lifetime*, a ``float``, how many seconds a query should run before timing out. - *search*, a ``bool`` or ``None``, determines whether the search - list configured in the system's resolver configuration are - used. The default is ``None``, which causes the value of - the resolver's ``use_search_by_default`` attribute to be used. + *search*, a ``bool`` or ``None``, determines whether the + search list configured in the system's resolver configuration + are used for relative names, and whether the resolver's domain + may be added to relative names. The default is ``None``, + which causes the value of the resolver's + ``use_search_by_default`` attribute to be used. Raises ``dns.exception.Timeout`` if no answers could be found in the specified lifetime. diff --git a/dns/trio/resolver.py b/dns/trio/resolver.py index d2bc12be..f9cdfeac 100644 --- a/dns/trio/resolver.py +++ b/dns/trio/resolver.py @@ -62,10 +62,12 @@ class Resolver(dns.resolver.Resolver): *source_port*, an ``int``, the port from which to send the message. - *search*, a ``bool`` or ``None``, determines whether the search - list configured in the system's resolver configuration are - used. The default is ``None``, which causes the value of - the resolver's ``use_search_by_default`` attribute to be used. + *search*, a ``bool`` or ``None``, determines whether the + search list configured in the system's resolver configuration + are used for relative names, and whether the resolver's domain + may be added to relative names. The default is ``None``, + which causes the value of the resolver's + ``use_search_by_default`` attribute to be used. Raises ``dns.resolver.NXDOMAIN`` if the query name does not exist. diff --git a/tests/test_resolution.py b/tests/test_resolution.py index bb1c4b13..9b7afdfc 100644 --- a/tests/test_resolution.py +++ b/tests/test_resolution.py @@ -25,12 +25,12 @@ class ResolutionTestCase(unittest.TestCase): self.assertEqual(request.question[0].name, self.qname) self.assertEqual(request.question[0].rdtype, dns.rdatatype.A) - def test_next_request_rel(self): + def test_next_request_rel_with_search(self): qname = dns.name.from_text('www.dnspython.org', None) abs_qname_1 = dns.name.from_text('www.dnspython.org.example') self.resn = dns.resolver._Resolution(self.resolver, qname, 'A', 'IN', - False, True, False) + False, True, True) (request, answer) = self.resn.next_request() self.assertTrue(answer is None) self.assertEqual(request.question[0].name, self.qname) @@ -39,6 +39,23 @@ class ResolutionTestCase(unittest.TestCase): self.assertTrue(answer is None) self.assertEqual(request.question[0].name, abs_qname_1) self.assertEqual(request.question[0].rdtype, dns.rdatatype.A) + def bad(): + (request, answer) = self.resn.next_request() + self.assertRaises(dns.resolver.NXDOMAIN, bad) + + def test_next_request_rel_without_search(self): + qname = dns.name.from_text('www.dnspython.org', None) + abs_qname_1 = dns.name.from_text('www.dnspython.org.example') + self.resn = dns.resolver._Resolution(self.resolver, qname, + 'A', 'IN', + False, True, False) + (request, answer) = self.resn.next_request() + self.assertTrue(answer is None) + self.assertEqual(request.question[0].name, self.qname) + self.assertEqual(request.question[0].rdtype, dns.rdatatype.A) + def bad(): + (request, answer) = self.resn.next_request() + self.assertRaises(dns.resolver.NXDOMAIN, bad) def test_next_request_exhaust_causes_nxdomain(self): def bad(): @@ -98,12 +115,34 @@ class ResolutionTestCase(unittest.TestCase): self.assertTrue(request is None) self.assertTrue(answer is cache_answer) - def test_next_request_cached_nxdomain(self): - # use a relative qname so we have two qnames to try + def test_next_request_cached_nxdomain_without_search(self): + # use a relative qname qname = dns.name.from_text('www.dnspython.org', None) self.resn = dns.resolver._Resolution(self.resolver, qname, 'A', 'IN', False, True, False) + qname1 = dns.name.from_text('www.dnspython.org.') + # Arrange to get NXDOMAIN hits on it. + self.resolver.cache = dns.resolver.Cache() + q1 = dns.message.make_query(qname1, dns.rdatatype.A) + r1 = self.make_negative_response(q1, True) + cache_answer = dns.resolver.Answer(qname1, dns.rdatatype.ANY, + dns.rdataclass.IN, r1) + self.resolver.cache.put((qname1, dns.rdatatype.ANY, + dns.rdataclass.IN), cache_answer) + try: + (request, answer) = self.resn.next_request() + self.assertTrue(False) # should not happen! + except dns.resolver.NXDOMAIN as nx: + self.assertTrue(nx.response(qname1) is r1) + + def test_next_request_cached_nxdomain_with_search(self): + # use a relative qname so we have two qnames to try + qname = dns.name.from_text('www.dnspython.org', None) + # also enable search mode or we'll only see www.dnspython.org. + self.resn = dns.resolver._Resolution(self.resolver, qname, + 'A', 'IN', + False, True, True) qname1 = dns.name.from_text('www.dnspython.org.example.') qname2 = dns.name.from_text('www.dnspython.org.') # Arrange to get NXDOMAIN hits on both of those qnames. diff --git a/tests/test_resolver.py b/tests/test_resolver.py index ddaad3d7..0403510a 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -289,10 +289,10 @@ class BaseResolverTests(unittest.TestCase): ['www.dnspython.org', 'www.dnspython.net']]) qnames = res._get_qnames_to_try(qname, False) self.assertEqual(qnames, - [dns.name.from_text('www.example.')]) + [dns.name.from_text('www.')]) qnames = res._get_qnames_to_try(qname, None) self.assertEqual(qnames, - [dns.name.from_text('www.example.')]) + [dns.name.from_text('www.')]) # # Now change search default on resolver to True #