From: Otto Moerbeek Date: Fri, 21 Jun 2024 14:31:24 +0000 (+0200) Subject: Add test for duplicate SOA record in the dns64/NODATA case X-Git-Tag: rec-5.2.0-alpha0~2^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F14373%2Fhead;p=thirdparty%2Fpdns.git Add test for duplicate SOA record in the dns64/NODATA case --- diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 2a121ce51a..6f9b2839a1 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -789,18 +789,18 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector 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)++; diff --git a/regression-tests.recursor-dnssec/recursortests.py b/regression-tests.recursor-dnssec/recursortests.py index 9ad7dfeca7..1385c12811 100644 --- a/regression-tests.recursor-dnssec/recursortests.py +++ b/regression-tests.recursor-dnssec/recursortests.py @@ -809,7 +809,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) @@ -835,7 +835,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 diff --git a/regression-tests.recursor-dnssec/test_DNS64.py b/regression-tests.recursor-dnssec/test_DNS64.py index abf6fdb23a..3b1e671ff9 100644 --- a/regression-tests.recursor-dnssec/test_DNS64.py +++ b/regression-tests.recursor-dnssec/test_DNS64.py @@ -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.'