]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Properly record the incoming flags on a timeout 12529/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 10 Feb 2023 09:33:34 +0000 (10:33 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 10 Feb 2023 10:10:14 +0000 (11:10 +0100)
pdns/dnsdistdist/dnsdist-backend.cc
regression-tests.dnsdist/test_Advanced.py

index 35dc76f59ce0826379d8c6f313f1086f6c5fbcb9..5868de01656bb3df4f8b1ec1fab642de19fd4347 100644 (file)
@@ -346,6 +346,8 @@ void DownstreamState::handleUDPTimeout(IDState& ids)
     struct dnsheader fake;
     memset(&fake, 0, sizeof(fake));
     fake.id = ids.internal.origID;
+    uint16_t* flags = getFlagsFromDNSHeader(&fake);
+    *flags = ids.internal.origFlags;
 
     g_rings.insertResponse(ts, ids.internal.origRemote, ids.internal.qname, ids.internal.qtype, std::numeric_limits<unsigned int>::max(), 0, fake, d_config.remote, getProtocol());
   }
index 643a25c3aa56e20addf265305a13ccc4c48c90ba..9797ed461fb070d971be9b20e80ad80b2ad460ca 100644 (file)
@@ -662,3 +662,70 @@ class TestChangeName(DNSDistTest):
             receivedQuery.id = query.id
             self.assertEqual(receivedQuery, changedQuery)
             self.assertEqual(receivedResponse, expectedResponse)
+
+class TestFlagsOnTimeout(DNSDistTest):
+
+    _consoleKey = DNSDistTest.generateConsoleKey()
+    _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
+    _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
+    _config_template = """
+    setKey("%s")
+    controlSocket("127.0.0.1:%s")
+    -- this server is not going to answer, resulting in a timeout
+    newServer{address="192.0.2.1:%s"}:setUp()
+    """
+
+    def testFlags(self):
+        """
+        Advanced: Test that we record the correct incoming flags on a timeout
+        """
+        name = 'timeout-flags.advanced.tests.powerdns.com.'
+
+        # first with RD=1
+        query = dns.message.make_query(name, 'A', 'IN')
+        query.id = 42
+        query.flags |= dns.flags.RD
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertFalse(receivedResponse)
+
+        # then with RD=0
+        query = dns.message.make_query(name, 'A', 'IN')
+        query.id = 84
+        query.flags &= ~dns.flags.RD
+
+        (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+        self.assertFalse(receivedResponse)
+
+        # make sure that the timeouts have been detected and recorded
+        for _ in range(3):
+            content = self.sendConsoleCommand("grepq('')")
+            lines = content.splitlines()
+            if len(lines) == 5:
+                break
+            # and otherwise sleep for a short while
+            time.sleep(1)
+
+        print(lines)
+        self.assertEqual(len(lines), 5)
+        # header line
+        self.assertIn('TC RD AA', lines[0])
+
+        queries = {}
+        timeouts = {}
+
+        for line in lines[1:]:
+            self.assertIn('DoUDP', line)
+            if 'T.O' in line:
+                queryID = int(line.split()[4])
+                timeouts[queryID] = line
+            else:
+                queryID = int(line.split()[3])
+                queries[queryID] = line
+            if queryID == 42:
+                self.assertIn('RD', line)
+            else:
+                self.assertNotIn('RD', line)
+
+        self.assertEqual(len(timeouts), 2)
+        self.assertEqual(len(queries), 2)