From: Remi Gacogne Date: Mon, 27 Mar 2023 11:42:08 +0000 (+0200) Subject: dnsdist: Test both incoming DoH implementations in Async tests X-Git-Tag: rec-5.0.0-alpha1~19^2~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1cc232f973648d911f8f3265b95889904be47d69;p=thirdparty%2Fpdns.git dnsdist: Test both incoming DoH implementations in Async tests --- diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index 8be405df6d..057bee47e9 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -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