]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add test for duplicate SOA record in the dns64/NODATA case 14380/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 21 Jun 2024 14:31:24 +0000 (16:31 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 25 Jun 2024 12:11:41 +0000 (14:11 +0200)
(cherry picked from commit 84702509275d1d57fab944c27f9970e4cf8dccec)

pdns/recursordist/pdns_recursor.cc
regression-tests.recursor-dnssec/recursortests.py
regression-tests.recursor-dnssec/test_DNS64.py

index a9fd0875940497abb09d3cb476faaa93c448cfaa..0907830675024e714cd3f13249e57fd95653c060 100644 (file)
@@ -754,18 +754,18 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector<DNSReco
     // Remove double SOA records
     std::set<DNSName> seenSOAs;
     ret.erase(std::remove_if(
-                             ret.begin(),
-                             ret.end(),
-                             [&seenSOAs](DNSRecord& record) {
-                               if (record.d_type == QType::SOA) {
-                                 if (seenSOAs.count(record.d_name) > 0) {
-                                   // We've had this SOA before, remove it
-                                   return true;
-                                 }
-                                 seenSOAs.insert(record.d_name);
-                               }
-                               return false;
-                             }),
+                ret.begin(),
+                ret.end(),
+                [&seenSOAs](DNSRecord& record) {
+                  if (record.d_type == QType::SOA) {
+                    if (seenSOAs.count(record.d_name) > 0) {
+                      // We've had this SOA before, remove it
+                      return true;
+                    }
+                    seenSOAs.insert(record.d_name);
+                  }
+                  return false;
+                }),
               ret.end());
   }
   t_Counters.at(rec::Counter::dns64prefixanswers)++;
index cf883fb4ee1dfbfcbdd9b8e85fa3910853305d4e..9292c6130f58530a2da2881f49e8fbc363e897fe 100644 (file)
@@ -745,7 +745,7 @@ distributor-threads={threads}""".format(confdir=confdir,
         return message
 
     @classmethod
-    def sendTCPQuery(cls, query, timeout=2.0):
+    def sendTCPQuery(cls, query, timeout=2.0, decode=True, fwparams=dict()):
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         if timeout:
             sock.settimeout(timeout)
@@ -771,7 +771,9 @@ distributor-threads={threads}""".format(confdir=confdir,
 
         message = None
         if data:
-            message = dns.message.from_wire(data)
+            if not decode:
+                return data
+            message = dns.message.from_wire(data, **fwparams)
         return message
 
     @classmethod
index abf6fdb23ac20f726ab1a04693af5514869bbadc..3b1e671ff99353d9deb660ff15ef33d1ff8c8c5f 100644 (file)
@@ -32,9 +32,11 @@ class DNS64RecursorTest(RecursorTest):
 @ 3600 IN SOA {soa}
 www 3600 IN A 192.0.2.42
 www 3600 IN TXT "does exist"
+txt 3600 IN TXT "a and aaaa do not exist"
 aaaa 3600 IN AAAA 2001:db8::1
 cname 3600 IN CNAME cname2.example.dns64.
 cname2 3600 IN CNAME www.example.dns64.
+cname3 3600 IN CNAME txt.example.dns64.
 formerr 3600 IN A 192.0.2.43
 """.format(soa=cls._SOA))
 
@@ -107,6 +109,22 @@ formerr 3600 IN A 192.0.2.43
             for expected in expectedResults:
                 self.assertRRsetInAnswer(res, expected)
 
+    # there is a CNAME from the name to a name that is NODATA for both A and AAAA
+    # so we should get a NODATA with a single SOA record (#14362)
+    def testCNAMEToNoData(self):
+        qname = 'cname3.example.dns64.'
+
+        expectedAnswer = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'CNAME', 'txt.example.dns64.')
+        query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
+        for method in ("sendUDPQuery", "sendTCPQuery"):
+            sender = getattr(self, method)
+            res = sender(query, 2.0, True, {"one_rr_per_rrset": True}) # we want to detect dups
+            self.assertRcodeEqual(res, dns.rcode.NOERROR)
+            self.assertEqual(len(res.answer), 1)
+            self.assertEqual(len(res.authority), 1)
+            self.assertRRsetInAnswer(res, expectedAnswer)
+            self.assertAuthorityHasSOA(res)
+
     # this type (AAAA) does not exist for this name and there is no A record either, we should get a NXDomain
     def testNXD(self):
         qname = 'nxd.example.dns64.'
@@ -117,6 +135,18 @@ formerr 3600 IN A 192.0.2.43
             res = sender(query)
             self.assertRcodeEqual(res, dns.rcode.NXDOMAIN)
 
+    # this type (AAAA) does not exist for this name and there is no A record either, we should get a NODATA as TXT does exist
+    def testNoData(self):
+        qname = 'txt.example.dns64.'
+
+        query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
+        for method in ("sendUDPQuery", "sendTCPQuery"):
+            sender = getattr(self, method)
+            res = sender(query, 2.0, True, {"one_rr_per_rrset": True}) # we want to detect dups
+            self.assertRcodeEqual(res, dns.rcode.NOERROR)
+            self.assertEqual(len(res.answer), 0)
+            self.assertEqual(len(res.authority), 1)
+
     # there is an AAAA record, we should get it
     def testExistingAAAA(self):
         qname = 'aaaa.example.dns64.'