From: Remi Gacogne Date: Sat, 11 Mar 2023 18:10:21 +0000 (+0100) Subject: dnsdist: Use the correct source address when harvesting failed X-Git-Tag: dnsdist-1.8.0-rc3~3^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f15f802a9a4489c3463ac8784fc53ec37ab9c288;p=thirdparty%2Fpdns.git dnsdist: Use the correct source address when harvesting failed --- diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 6dddd4fd50..36d279e043 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -174,7 +174,7 @@ static ssize_t sendfromto(int sock, const void* data, size_t len, int flags, con msgh.msg_name = (struct sockaddr*)&to; msgh.msg_namelen = to.getSocklen(); - if(from.sin4.sin_family) { + if (from.sin4.sin_family) { addCMsgSrcAddr(&msgh, &cbuf, &from, 0); } else { @@ -1612,6 +1612,7 @@ static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct which is used by rules and actions to at least the correct address family */ ids.origDest = cs.local; + ids.hopLocal.sin4.sin_family = 0; } std::vector proxyProtocolValues; diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index fc1f6eb7d9..16376c38fe 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -414,6 +414,52 @@ class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest): self.assertEqual(receivedQuery, query) self.assertEqual(receivedResponse, response) +class TestAdvancedGetLocalAddressOnNonDefaultLoopbackBind(DNSDistTest): + # this one is tricky: on the loopback interface we cannot harvest the destination + # address, so we exercise a different code path when we bind on a different address + # than the default 127.0.0.1 one + _config_template = """ + newServer{address="127.0.0.1:%s"} + addLocal('127.0.1.19:%d') + """ + _config_params = ['_testServerPort', '_dnsDistPort'] + _acl = ['127.0.0.1/32'] + _skipListeningOnCL = True + + def testAdvancedCheckSourceAddrOnNonDefaultLoopbackBind(self): + """ + Advanced: Check the source address used to reply on a non-default loopback bind + """ + name = 'source-addr-non-default-loopback.advanced.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.42') + response.answer.append(rrset) + + # a bit more tricky, UDP-only IPv4 + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.settimeout(1.0) + sock.connect(('127.0.1.19', self._dnsDistPort)) + self._toResponderQueue.put(response, True, 1.0) + try: + data = query.to_wire() + sock.send(data) + (data, remote) = sock.recvfrom(4096) + self.assertEquals(remote[0], '127.0.1.19') + except socket.timeout: + data = None + + self.assertTrue(data) + receivedResponse = dns.message.from_wire(data) + receivedQuery = self._fromResponderQueue.get(True, 1.0) + receivedQuery.id = query.id + self.assertEqual(receivedQuery, query) + self.assertEqual(receivedResponse, response) + class TestAdvancedAllowHeaderOnly(DNSDistTest): _config_template = """