]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add regression test for remote count when using proxy protocol 14340/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 17 Jun 2024 09:24:04 +0000 (11:24 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 17 Jun 2024 11:05:52 +0000 (13:05 +0200)
pdns/recursordist/rec-tcp.cc
regression-tests.recursor-dnssec/test_ProxyProtocol.py

index 661be32fbe1af46dec96737595573c262d77b801..386dd5060a8ee73b225f8f3fc710e30e1a68093a 100644 (file)
@@ -501,7 +501,7 @@ static void doProcessTCPQuestion(std::unique_ptr<DNSComboWriter>& comboWriter, s
   } // good query
 }
 
-static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var)
+static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var) // NOLINT(readability-function-cognitive-complexity)
 {
   auto conn = boost::any_cast<shared_ptr<TCPConnection>>(var);
 
@@ -700,6 +700,9 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara
     socklen_t len = sizeof(destaddr);
     getsockname(newsock, reinterpret_cast<sockaddr*>(&destaddr), &len); // if this fails, we're ok with it NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
     bool fromProxyProtocolSource = expectProxyProtocol(addr, destaddr);
+    if (!fromProxyProtocolSource && t_remotes) {
+      t_remotes->push_back(addr);
+    }
     ComboAddress mappedSource = addr;
     if (!fromProxyProtocolSource && t_proxyMapping) {
       if (const auto* iter = t_proxyMapping->lookup(addr)) {
index 5f100fe13eba3b6dd545dd081c1911f05a6995ad..78c88d025f8f79bd4e9e75a2b393c8dbd8d0c1e0 100644 (file)
@@ -4,6 +4,7 @@ import socket
 import struct
 import sys
 import time
+import requests
 
 try:
     range = xrange
@@ -34,6 +35,10 @@ class ProxyProtocolRecursorTest(RecursorTest):
 
 class ProxyProtocolAllowedRecursorTest(ProxyProtocolRecursorTest):
     _confdir = 'ProxyProtocol'
+    _wsPort = 8042
+    _wsTimeout = 2
+    _wsPassword = 'secretpassword'
+    _apiKey = 'secretapikey'
     _lua_dns_script_file = """
 
     function gettag(remote, ednssubnet, localip, qname, qtype, ednsoptions, tcp, proxyProtocolValues)
@@ -134,7 +139,29 @@ class ProxyProtocolAllowedRecursorTest(ProxyProtocolRecursorTest):
     proxy-protocol-from=127.0.0.1
     proxy-protocol-maximum-size=512
     allow-from=127.0.0.0/24, ::1/128, ::42/128
-""" % ()
+    webserver=yes
+    webserver-port=%d
+    webserver-address=127.0.0.1
+    webserver-password=%s
+api-key=%s
+
+""" % (_wsPort, _wsPassword, _apiKey)
+
+    def checkStats(self, expected127001):
+        headers = {'x-api-key': self._apiKey}
+        url = 'http://127.0.0.1:' + str(self._wsPort) + '/jsonstat?command=get-remote-ring&name=remotes'
+        r = requests.get(url, headers=headers, timeout=self._wsTimeout)
+        self.assertTrue(r)
+        self.assertEqual(r.status_code, 200)
+        self.assertTrue(r.json())
+        content = r.json()
+        # We allow all kind of entries, but 127.0.0.1 must have the given value, due to the
+        # testLocalProxyProtocol test, which actually does not set a source address.  If we see a
+        # higher value than expected, some ProxyProtocol clients were accounted as 127.0.0.1, which
+        # is not right as all other tests set a source addres other than 127.0.0.1
+        for entry in content['entries']:
+            if entry[1] == '127.0.0.1':
+                self.assertEqual(entry[0], expected127001)
 
     def testLocalProxyProtocol(self):
         qname = 'local.proxy-protocol.recursor-tests.powerdns.com.'
@@ -161,6 +188,7 @@ class ProxyProtocolAllowedRecursorTest(ProxyProtocolRecursorTest):
             res = dns.message.from_wire(data)
         self.assertRcodeEqual(res, dns.rcode.NOERROR)
         self.assertRRsetInAnswer(res, expected)
+        self.checkStats(1)
 
         # TCP
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -189,6 +217,7 @@ class ProxyProtocolAllowedRecursorTest(ProxyProtocolRecursorTest):
             res = dns.message.from_wire(data)
         self.assertRcodeEqual(res, dns.rcode.NOERROR)
         self.assertRRsetInAnswer(res, expected)
+        self.checkStats(2)
 
     def testInvalidMagicProxyProtocol(self):
         qname = 'invalid-magic.proxy-protocol.recursor-tests.powerdns.com.'