]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Use the correct source address when harvesting failed 12641/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Sat, 11 Mar 2023 18:10:21 +0000 (19:10 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Sat, 11 Mar 2023 18:12:25 +0000 (19:12 +0100)
pdns/dnsdist.cc
regression-tests.dnsdist/test_Advanced.py

index 6dddd4fd5057b37b25837f02a1ba8ede0a1a5250..36d279e043e1dba523012e4b17767bc4cb480eba 100644 (file)
@@ -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<ProxyProtocolValue> proxyProtocolValues;
index fc1f6eb7d9a82319bee5aad6f84e48b1bde1b61c..16376c38fed6e263c2bea565187aa747845ffe40 100644 (file)
@@ -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 = """