From: Remi Gacogne Date: Mon, 2 Mar 2020 16:17:46 +0000 (+0100) Subject: rec: Keep Proxy Protocol values between queries on the same connection X-Git-Tag: dnsdist-1.5.0-alpha1~12^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f00de7d21314bab22a5c9e8dbce063a981a5afe3;p=thirdparty%2Fpdns.git rec: Keep Proxy Protocol values between queries on the same connection --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index cef83b0cea..c65a62a146 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -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; diff --git a/regression-tests.recursor-dnssec/test_ProxyProtocol.py b/regression-tests.recursor-dnssec/test_ProxyProtocol.py index ee521ea76a..fcc489b2bd 100644 --- a/regression-tests.recursor-dnssec/test_ProxyProtocol.py +++ b/regression-tests.recursor-dnssec/test_ProxyProtocol.py @@ -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'