]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Test both incoming DoH implementations in Async tests
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 27 Mar 2023 11:42:08 +0000 (13:42 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 7 Sep 2023 08:22:00 +0000 (10:22 +0200)
regression-tests.dnsdist/test_Async.py

index 8be405df6dde1c1d76996404356dab7b07388047..057bee47e9a7e04921df37c5065c1ffcbcae8c37 100644 (file)
@@ -86,6 +86,22 @@ asyncResponder.daemon = True
 asyncResponder.start()
 
 class AsyncTests(object):
+    _serverKey = 'server.key'
+    _serverCert = 'server.chain'
+    _serverName = 'tls.tests.dnsdist.org'
+    _caCert = 'ca.pem'
+    _tlsServerPort = pickAvailablePort()
+    _dohWithNGHTTP2ServerPort = pickAvailablePort()
+    _dohWithH2OServerPort = pickAvailablePort()
+    _dohWithNGHTTP2BaseURL = ("https://%s:%d/" % (_serverName, _dohWithNGHTTP2ServerPort))
+    _dohWithH2OBaseURL = ("https://%s:%d/" % (_serverName, _dohWithH2OServerPort))
+
+    def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True):
+        return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue)
+
+    def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True):
+        return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue)
+
     def testPass(self):
         """
         Async: Accept
@@ -101,23 +117,13 @@ class AsyncTests(object):
                                         '192.0.2.1')
             response.answer.append(rrset)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(response, receivedResponse)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
     def testPassCached(self):
         """
         Async: Accept (cached)
@@ -133,29 +139,21 @@ class AsyncTests(object):
                                     '192.0.2.1')
         response.answer.append(rrset)
 
-        for method in ("sendUDPQuery", "sendTCPQuery"):
-            # first time to fill the cache
+        for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
             sender = getattr(self, method)
-            (receivedQuery, receivedResponse) = sender(query, response)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
+            if method != 'sendDOTQueryWrapper' and method != 'sendDOHWithH2OQueryWrapper':
+                # first time to fill the cache
+                # disabled for DoT since it was already filled via TCP
+                (receivedQuery, receivedResponse) = sender(query, response)
+                receivedQuery.id = query.id
+                self.assertEqual(query, receivedQuery)
+                self.assertEqual(response, receivedResponse)
+
             # second time from the cache
             sender = getattr(self, method)
             (_, receivedResponse) = sender(query, response=None, useQueue=False)
             self.assertEqual(response, receivedResponse)
 
-        (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, useQueue=False, caFile=self._caCert)
-        self.assertEqual(response, receivedResponse)
-
-        (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-        receivedQuery.id = query.id
-        self.assertEqual(query, receivedQuery)
-        self.assertEqual(response, receivedResponse)
-
-        (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, useQueue=False, caFile=self._caCert)
-        self.assertEqual(response, receivedResponse)
-
     def testTimeoutThenAccept(self):
         """
         Async: Timeout then accept
@@ -171,23 +169,13 @@ class AsyncTests(object):
                                         '192.0.2.1')
             response.answer.append(rrset)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(response, receivedResponse)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
     def testAcceptThenTimeout(self):
         """
         Async: Accept then timeout
@@ -203,23 +191,13 @@ class AsyncTests(object):
                                         '192.0.2.1')
             response.answer.append(rrset)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(response, receivedResponse)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(response, receivedResponse)
-
     def testAcceptThenRefuse(self):
         """
         Async: Accept then refuse
@@ -239,23 +217,13 @@ class AsyncTests(object):
             expectedResponse.flags |= dns.flags.RA
             expectedResponse.set_rcode(dns.rcode.REFUSED)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(expectedResponse, receivedResponse)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(expectedResponse, receivedResponse)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(expectedResponse, receivedResponse)
-
     def testAcceptThenCustom(self):
         """
         Async: Accept then custom
@@ -278,23 +246,13 @@ class AsyncTests(object):
             expectedResponse.flags |= dns.flags.RA
             expectedResponse.set_rcode(dns.rcode.FORMERR)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(expectedResponse, receivedResponse)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(expectedResponse, receivedResponse)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(expectedResponse, receivedResponse)
-
     def testAcceptThenDrop(self):
         """
         Async: Accept then drop
@@ -310,23 +268,13 @@ class AsyncTests(object):
                                         '192.0.2.1')
             response.answer.append(rrset)
 
-            for method in ("sendUDPQuery", "sendTCPQuery"):
+            for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
                 sender = getattr(self, method)
                 (receivedQuery, receivedResponse) = sender(query, response)
                 receivedQuery.id = query.id
                 self.assertEqual(query, receivedQuery)
                 self.assertEqual(receivedResponse, None)
 
-            (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(receivedResponse, None)
-
-            (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert)
-            receivedQuery.id = query.id
-            self.assertEqual(query, receivedQuery)
-            self.assertEqual(receivedResponse, None)
-
     def testRefused(self):
         """
         Async: Refused
@@ -338,18 +286,12 @@ class AsyncTests(object):
         expectedResponse.flags |= dns.flags.RA
         expectedResponse.set_rcode(dns.rcode.REFUSED)
 
-        for method in ("sendUDPQuery", "sendTCPQuery"):
+        for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
             sender = getattr(self, method)
             (_, receivedResponse) = sender(query, response=None, useQueue=False)
             self.assertTrue(receivedResponse)
             self.assertEqual(expectedResponse, receivedResponse)
 
-        (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(expectedResponse, receivedResponse)
-
-        (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(expectedResponse, receivedResponse)
-
     def testDrop(self):
         """
         Async: Drop
@@ -357,17 +299,11 @@ class AsyncTests(object):
         name = 'drop.async.tests.powerdns.com.'
         query = dns.message.make_query(name, 'A', 'IN')
 
-        for method in ("sendUDPQuery", "sendTCPQuery"):
+        for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
             sender = getattr(self, method)
             (_, receivedResponse) = sender(query, response=None, useQueue=False)
             self.assertEqual(receivedResponse, None)
 
-        (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(receivedResponse, None)
-
-        (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(receivedResponse, None)
-
     def testCustom(self):
         """
         Async: Custom answer
@@ -379,77 +315,66 @@ class AsyncTests(object):
         expectedResponse.flags |= dns.flags.RA
         expectedResponse.set_rcode(dns.rcode.FORMERR)
 
-        for method in ("sendUDPQuery", "sendTCPQuery"):
+        for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
             sender = getattr(self, method)
             (_, receivedResponse) = sender(query, response=None, useQueue=False)
             self.assertTrue(receivedResponse)
             self.assertEqual(expectedResponse, receivedResponse)
 
-        (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(expectedResponse, receivedResponse)
-
-        (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False)
-        self.assertEqual(expectedResponse, receivedResponse)
-
     def testTruncation(self):
         """
         Async: DoH query, timeout then truncated answer over UDP, then valid over TCP and accept
         """
         # the query is first forwarded over UDP, leading to a TC=1 answer from the
         # backend, then over TCP
-        name = 'timeout-then-accept.tc.async.tests.powerdns.com.'
-        query = dns.message.make_query(name, 'A', 'IN')
-        query.id = 42
-        expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096)
-        expectedQuery.id = 42
-        response = dns.message.make_response(query)
-        rrset = dns.rrset.from_text(name,
-                                    3600,
-                                    dns.rdataclass.IN,
-                                    dns.rdatatype.A,
-                                    '127.0.0.1')
-        response.answer.append(rrset)
 
-        # first response is a TC=1
-        tcResponse = dns.message.make_response(query)
-        tcResponse.flags |= dns.flags.TC
-        self._toResponderQueue.put(tcResponse, True, 2.0)
-
-        (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, caFile=self._caCert, response=response)
-        # first query, received by the responder over UDP
-        self.assertTrue(receivedQuery)
-        receivedQuery.id = expectedQuery.id
-        self.assertEqual(expectedQuery, receivedQuery)
-        self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery)
-
-        # check the response
-        self.assertTrue(receivedResponse)
-        self.assertEqual(response, receivedResponse)
-
-        # check the second query, received by the responder over TCP
-        receivedQuery = self._fromResponderQueue.get(True, 2.0)
-        self.assertTrue(receivedQuery)
-        receivedQuery.id = expectedQuery.id
-        self.assertEqual(expectedQuery, receivedQuery)
-        self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery)
+        for method in ("sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"):
+            sender = getattr(self, method)
+            name = 'timeout-then-accept.' + method + '.tc.async.tests.powerdns.com.'
+            query = dns.message.make_query(name, 'A', 'IN')
+            query.id = 42
+            expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096)
+            expectedQuery.id = 42
+            response = dns.message.make_response(query)
+            rrset = dns.rrset.from_text(name,
+                                        3600,
+                                        dns.rdataclass.IN,
+                                        dns.rdatatype.A,
+                                        '127.0.0.1')
+            response.answer.append(rrset)
+
+            # first response is a TC=1
+            tcResponse = dns.message.make_response(query)
+            tcResponse.flags |= dns.flags.TC
+            self._toResponderQueue.put(tcResponse, True, 2.0)
 
-@unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled')
-class TestAsyncFFI(DNSDistTest, AsyncTests):
+            # first query, received by the responder over UDP
+            (receivedQuery, receivedResponse) = sender(query, response=response)
+            self.assertTrue(receivedQuery)
+            receivedQuery.id = expectedQuery.id
+            self.assertEqual(expectedQuery, receivedQuery)
+            self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery)
 
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
-    _serverName = 'tls.tests.dnsdist.org'
-    _caCert = 'ca.pem'
-    _tlsServerPort = pickAvailablePort()
-    _dohServerPort = pickAvailablePort()
-    _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort))
+            # check the response
+            self.assertTrue(receivedResponse)
+            self.assertEqual(response, receivedResponse)
 
+            # check the second query, received by the responder over TCP
+            receivedQuery = self._fromResponderQueue.get(True, 2.0)
+            self.assertTrue(receivedQuery)
+            receivedQuery.id = expectedQuery.id
+            self.assertEqual(expectedQuery, receivedQuery)
+            self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery)
+
+@unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled')
+class TestAsyncFFI(DNSDistTest, AsyncTests):
     _config_template = """
-    newServer{address="127.0.0.1:%s", pool={'', 'cache'}}
-    newServer{address="127.0.0.1:%s", pool="tcp-only", tcpOnly=true }
+    newServer{address="127.0.0.1:%d", pool={'', 'cache'}}
+    newServer{address="127.0.0.1:%d", pool="tcp-only", tcpOnly=true }
 
-    addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" })
-    addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/"})
+    addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" })
+    addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"})
+    addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"})
 
     local ffi = require("ffi")
     local C = ffi.C
@@ -540,26 +465,18 @@ class TestAsyncFFI(DNSDistTest, AsyncTests):
     """
     _asyncResponderSocketPath = asyncResponderSocketPath
     _dnsdistSocketPath = dnsdistSocketPath
-    _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath']
+    _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath']
     _verboseMode = True
 
 @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled')
 class TestAsyncLua(DNSDistTest, AsyncTests):
-
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
-    _serverName = 'tls.tests.dnsdist.org'
-    _caCert = 'ca.pem'
-    _tlsServerPort = pickAvailablePort()
-    _dohServerPort = pickAvailablePort()
-    _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort))
-
     _config_template = """
-    newServer{address="127.0.0.1:%s", pool={'', 'cache'}}
-    newServer{address="127.0.0.1:%s", pool="tcp-only", tcpOnly=true }
+    newServer{address="127.0.0.1:%d", pool={'', 'cache'}}
+    newServer{address="127.0.0.1:%d", pool="tcp-only", tcpOnly=true }
 
-    addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" })
-    addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/"})
+    addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" })
+    addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"})
+    addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"})
 
     local filteringTagName = 'filtering'
     local filteringTagValue = 'pass'
@@ -648,5 +565,5 @@ class TestAsyncLua(DNSDistTest, AsyncTests):
     """
     _asyncResponderSocketPath = asyncResponderSocketPath
     _dnsdistSocketPath = dnsdistSocketPath
-    _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath']
+    _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath']
     _verboseMode = True