From 607d1296b284309cb5e8c71966f2db070a2a5c06 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Fri, 18 Jun 2021 16:58:59 +0200 Subject: [PATCH] SVCB: Fix auto hints removing non-auto hints Closes #10258 --- pdns/packethandler.cc | 33 +++++++++------- regression-tests.auth-py/test_SVCB.py | 57 +++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 14 deletions(-) diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 6c568b583f..cfcef0f00e 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -528,26 +528,31 @@ void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr(rec->dr); DNSName target = rrc->getTarget().isRoot() ? rec->dr.d_name : rrc->getTarget(); - if (rrc->autoHint(SvcParam::ipv4hint) && s_SVCAutohints) { - auto hints = getIPAddressFor(target, QType::A); - if (hints.size() == 0) { - rrc->removeParam(SvcParam::ipv4hint); + + if (rrc->hasParam(SvcParam::ipv4hint) && rrc->autoHint(SvcParam::ipv4hint)) { + if (s_SVCAutohints) { + auto hints = getIPAddressFor(target, QType::A); + if (hints.size() == 0) { + rrc->removeParam(SvcParam::ipv4hint); + } else { + rrc->setHints(SvcParam::ipv4hint, hints); + } } else { - rrc->setHints(SvcParam::ipv4hint, hints); + rrc->removeParam(SvcParam::ipv4hint); } - } else { - rrc->removeParam(SvcParam::ipv4hint); } - if (rrc->autoHint(SvcParam::ipv6hint) && s_SVCAutohints) { - auto hints = getIPAddressFor(target, QType::AAAA); - if (hints.size() == 0) { - rrc->removeParam(SvcParam::ipv6hint); + if (rrc->hasParam(SvcParam::ipv6hint) && rrc->autoHint(SvcParam::ipv6hint)) { + if (s_SVCAutohints) { + auto hints = getIPAddressFor(target, QType::AAAA); + if (hints.size() == 0) { + rrc->removeParam(SvcParam::ipv6hint); + } else { + rrc->setHints(SvcParam::ipv6hint, hints); + } } else { - rrc->setHints(SvcParam::ipv6hint, hints); + rrc->removeParam(SvcParam::ipv6hint); } - } else { - rrc->removeParam(SvcParam::ipv6hint); } } diff --git a/regression-tests.auth-py/test_SVCB.py b/regression-tests.auth-py/test_SVCB.py index dda0c02d5a..7bb10ac4ce 100644 --- a/regression-tests.auth-py/test_SVCB.py +++ b/regression-tests.auth-py/test_SVCB.py @@ -24,6 +24,18 @@ no-a.example.org. 3600 IN AAAA 2001:db8::81 no-aaaa.example.org. 3600 IN HTTPS 1 . ipv4hint=auto ipv6hint=auto no-aaaa.example.org. 3600 IN A 192.0.2.81 + +auto-a.example.org. 3600 IN HTTPS 1 . ipv4hint=auto ipv6hint=2001:db8::81 +auto-a.example.org. 3600 IN A 192.0.2.80 +auto-a.example.org. 3600 IN AAAA 2001:db8::80 + +no-auto.example.org. 3600 IN HTTPS 1 . ipv4hint=192.0.2.81 ipv6hint=2001:db8::81 +no-auto.example.org. 3600 IN A 192.0.2.80 +no-auto.example.org. 3600 IN AAAA 2001:db8::80 + +auto-aaaa.example.org. 3600 IN HTTPS 1 . ipv4hint=192.0.2.81 ipv6hint=auto +auto-aaaa.example.org. 3600 IN A 192.0.2.80 +auto-aaaa.example.org. 3600 IN AAAA 2001:db8::80 """, } @@ -85,3 +97,48 @@ no-aaaa.example.org. 3600 IN A 192.0.2.81 self.assertRcodeEqual(res, dns.rcode.NOERROR) self.assertRRsetInAnswer(res, expected_ans) self.assertEqual(len(res.additional), 1) + + def testNoAuto(self): + """ + Ensure we send the actual hints, not generated ones + """ + query = dns.message.make_query('no-auto.example.org', 'HTTPS') + res = self.sendUDPQuery(query) + expected_ans = dns.rrset.from_text( + 'no-auto.example.org.', 3600, dns.rdataclass.IN, 'HTTPS', + '1 . ipv4hint="192.0.2.81" ipv6hint="2001:db8::81"' + ) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + print(res) + self.assertRRsetInAnswer(res, expected_ans) + self.assertEqual(len(res.additional), 2) + + def testAutoA(self): + """ + Ensure we send a generated A hint, but keep the existing AAAA hint + """ + query = dns.message.make_query('auto-a.example.org', 'HTTPS') + res = self.sendUDPQuery(query) + expected_ans = dns.rrset.from_text( + 'auto-a.example.org.', 3600, dns.rdataclass.IN, 'HTTPS', + '1 . ipv4hint="192.0.2.80" ipv6hint="2001:db8::81"' + ) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + print(res) + self.assertRRsetInAnswer(res, expected_ans) + self.assertEqual(len(res.additional), 2) + + def testAutoAAAA(self): + """ + Ensure we send a generated AAAA hint, but keep the existing A hint + """ + query = dns.message.make_query('auto-aaaa.example.org', 'HTTPS') + res = self.sendUDPQuery(query) + expected_ans = dns.rrset.from_text( + 'auto-aaaa.example.org.', 3600, dns.rdataclass.IN, 'HTTPS', + '1 . ipv4hint="192.0.2.81" ipv6hint="2001:db8::80"' + ) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + print(res) + self.assertRRsetInAnswer(res, expected_ans) + self.assertEqual(len(res.additional), 2) -- 2.47.2