Skip to content

Commit

Permalink
Merge pull request #14379 from omoerbeek/backport-14373-to-rec-5.0.x
Browse files Browse the repository at this point in the history
rec: Backport 14373 to rec 5.0.x:  Remove potential double SOA records if the target of a dns64 name is NODATA
  • Loading branch information
omoerbeek authored Jun 25, 2024
2 parents 0742b33 + 527fff7 commit 1d5e654
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
18 changes: 18 additions & 0 deletions pdns/recursordist/pdns_recursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,24 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector<DNSReco
}),
ret.end());
}
else {
// 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.end());
}
t_Counters.at(rec::Counter::dns64prefixanswers)++;
return rcode;
}
Expand Down
6 changes: 4 additions & 2 deletions regression-tests.recursor-dnssec/recursortests.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def sendUDPQuery(cls, query, timeout=2.0, decode=True, fwparams=dict()):
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)
Expand All @@ -831,7 +831,9 @@ def sendTCPQuery(cls, query, timeout=2.0):

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
Expand Down
30 changes: 30 additions & 0 deletions regression-tests.recursor-dnssec/test_DNS64.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ def generateRecursorConfig(cls, confdir):
@ 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))

Expand Down Expand Up @@ -107,6 +109,22 @@ def testCNAMEToA(self):
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.'
Expand All @@ -117,6 +135,18 @@ def testNXD(self):
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.'
Expand Down

0 comments on commit 1d5e654

Please sign in to comment.