]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Keep Proxy Protocol values between queries on the same connection
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 2 Mar 2020 16:17:46 +0000 (17:17 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 17 Mar 2020 13:12:56 +0000 (14:12 +0100)
pdns/pdns_recursor.cc
regression-tests.recursor-dnssec/test_ProxyProtocol.py

index cef83b0ceaf3b8a30c78f147d18ce929da0444c4..c65a62a14673b9fde8d16becf69e4ec588dd4ec4 100644 (file)
@@ -2161,7 +2161,9 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
       getsockname(conn->getFD(), (sockaddr*)&dest, &len); // if this fails, we're ok with it
       dc->setLocal(dest);
       dc->setDestination(conn->d_destination);
-      dc->d_proxyProtocolValues = std::move(conn->proxyProtocolValues);
+      /* we can't move this if we want to be able to access the values in
+         all queries sent over this connection */
+      dc->d_proxyProtocolValues = conn->proxyProtocolValues;
       DNSName qname;
       uint16_t qtype=0;
       uint16_t qclass=0;
index ee521ea76a0b74f4de0eead8a9f362fa227bbac8..fcc489b2bd2bee8bbee8b5d807ae1219a89b5eac 100644 (file)
@@ -5,6 +5,11 @@ import struct
 import sys
 import time
 
+try:
+    range = xrange
+except NameError:
+    pass
+
 from recursortests import RecursorTest
 from proxyprotocol import ProxyProtocol
 
@@ -449,6 +454,51 @@ class ProxyProtocolAllowedRecursorTest(ProxyProtocolRecursorTest):
             res = sender(query, True, '2001:db8::1', '2001:db8::ff', 0, 65535, [ [0, b'foo' ], [ 255, b'bar'] ])
             self.assertEqual(res, None)
 
+    def testIPv6ProxyProtocolSeveralQueriesOverTCP(self):
+        qname = 'several-queries-tcp.proxy-protocol.recursor-tests.powerdns.com.'
+        expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'A', '192.0.2.1')
+
+        query = dns.message.make_query(qname, 'A', want_dnssec=True)
+        queryPayload = query.to_wire()
+        ppPayload = ProxyProtocol.getPayload(False, True, True, '::42', '2001:db8::ff', 0, 65535, [ [0, b'foo' ], [ 255, b'bar'] ])
+        payload = ppPayload + queryPayload
+
+        # TCP
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(2.0)
+        sock.connect(("127.0.0.1", self._recursorPort))
+
+        sock.send(ppPayload)
+
+        count = 0
+        for idx in range(5):
+            try:
+                sock.send(struct.pack("!H", len(queryPayload)))
+                sock.send(queryPayload)
+
+                data = sock.recv(2)
+                if data:
+                    (datalen,) = struct.unpack("!H", data)
+                    data = sock.recv(datalen)
+            except socket.timeout as e:
+                print("Timeout: %s" % (str(e)))
+                data = None
+                break
+            except socket.error as e:
+                print("Network error: %s" % (str(e)))
+                data = None
+                break
+
+            res = None
+            if data:
+                res = dns.message.from_wire(data)
+            self.assertRcodeEqual(res, dns.rcode.NOERROR)
+            self.assertRRsetInAnswer(res, expected)
+            count = count + 1
+
+        self.assertEqual(count, 5)
+        sock.close()
+
 class ProxyProtocolAllowedFFIRecursorTest(ProxyProtocolAllowedRecursorTest):
     # same tests than ProxyProtocolAllowedRecursorTest but with the Lua FFI interface instead of the regular one
     _confdir = 'ProxyProtocolFFI'