]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
further tighten resolve() default settings
authorBob Halley <halley@dnspython.org>
Wed, 27 May 2020 20:30:05 +0000 (13:30 -0700)
committerBob Halley <halley@dnspython.org>
Wed, 27 May 2020 20:30:05 +0000 (13:30 -0700)
dns/resolver.py
dns/trio/resolver.py
tests/test_resolution.py
tests/test_resolver.py

index 089021d3d390972a9b1880bda40959dfcc0929f9..20356685f0cd62e2f4dcb1e99b4ebaae37632a74 100644 (file)
@@ -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.
index d2bc12be60a8425f3788e0d040081e0ddd1b5960..f9cdfeacc0176f3264a37ff6ef5443a482183735 100644 (file)
@@ -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.
 
index bb1c4b136619296889ba61b060daf874867b85d8..9b7afdfcb21254964c29e76899137928ca0caa32 100644 (file)
@@ -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.
index ddaad3d738118b5dbbd56aaf5c7b53afa8f2db6e..0403510a9e21c15420562c9d969bcbbf68dee1c0 100644 (file)
@@ -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
         #