Skip to content

Commit 2de5989

Browse files
committed
Factor code responsible for the NSEC{,3} QType bitmap computation.
Signed-off-by: Miod Vallat <miod.vallat@powerdns.com>
1 parent 8c55e89 commit 2de5989

2 files changed

Lines changed: 95 additions & 115 deletions

File tree

pdns/packethandler.cc

Lines changed: 93 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -672,173 +672,151 @@ vector<ComboAddress> PacketHandler::getIPAddressFor(const DNSName &target, const
672672
return ret;
673673
}
674674

675-
void PacketHandler::emitNSEC(std::unique_ptr<DNSPacket>& r, const DNSName& name, const DNSName& next, int mode)
675+
// Common part to NSEC and NSEC3 to compute the QType bitmap in the NSEC
676+
// or NSEC3 response, part 1.
677+
void PacketHandler::computeNSECbitmap1(NSECBitmap& bitmap)
676678
{
677-
NSECRecordContent nrc;
678-
nrc.d_next = next;
679-
680-
nrc.set(QType::NSEC);
681-
nrc.set(QType::RRSIG);
682-
if(d_sd.qname() == name) {
683-
nrc.set(QType::SOA); // 1dfd8ad SOA can live outside the records table
684-
if(!isPresigned()) {
685-
auto keyset = d_dk.getKeys(d_sd.zonename);
686-
for(const auto& value: keyset) {
687-
if (value.second.published) {
688-
nrc.set(QType::DNSKEY);
689-
string publishCDNSKEY;
690-
d_dk.getPublishCDNSKEY(d_sd.zonename, publishCDNSKEY);
691-
if (! publishCDNSKEY.empty())
692-
nrc.set(QType::CDNSKEY);
693-
string publishCDS;
694-
d_dk.getPublishCDS(d_sd.zonename, publishCDS);
695-
if (! publishCDS.empty())
696-
nrc.set(QType::CDS);
697-
break;
679+
bitmap.set(QType::SOA); // 1dfd8ad SOA can live outside the records table
680+
if (!isPresigned()) {
681+
auto keyset = d_dk.getKeys(d_sd.zonename);
682+
for (const auto& value: keyset) {
683+
if (value.second.published) {
684+
bitmap.set(QType::DNSKEY);
685+
string publishCDNSKEY;
686+
d_dk.getPublishCDNSKEY(d_sd.zonename, publishCDNSKEY);
687+
if (!publishCDNSKEY.empty()) {
688+
bitmap.set(QType::CDNSKEY);
689+
}
690+
string publishCDS;
691+
d_dk.getPublishCDS(d_sd.zonename, publishCDS);
692+
if (!publishCDS.empty()) {
693+
bitmap.set(QType::CDS);
698694
}
695+
break;
699696
}
700697
}
701698
}
699+
}
702700

703-
DNSZoneRecord rr;
701+
// Common part to NSEC and NSEC3 to compute the QType bitmap in the NSEC
702+
// or NSEC3 response, part 2.
703+
domainid_t PacketHandler::computeNSECbitmap2(NSECBitmap& bitmap, const DNSName& name, bool includeENT)
704+
{
705+
DNSZoneRecord rec;
704706
#ifdef HAVE_LUA_RECORDS
705707
bool first{true};
706708
bool doLua{false};
707709
#endif
708710

709711
B.lookup(QType(QType::ANY), name, d_sd.domain_id);
710-
while(B.get(rr)) {
712+
while (B.get(rec)) {
711713
#ifdef HAVE_LUA_RECORDS
712-
if (rr.dr.d_type == QType::LUA && first && !isPresigned()) {
714+
if (rec.dr.d_type == QType::LUA && first && !isPresigned()) {
713715
first = false;
714716
doLua = doLuaRecords();
715717
}
716718

717-
if (rr.dr.d_type == QType::LUA && doLua) {
718-
nrc.set(getRR<LUARecordContent>(rr.dr)->d_type);
719+
if (rec.dr.d_type == QType::LUA && doLua) {
720+
bitmap.set(getRR<LUARecordContent>(rec.dr)->d_type);
721+
continue;
719722
}
720-
else
721723
#endif
722-
if (d_doExpandALIAS && rr.dr.d_type == QType::ALIAS) {
724+
725+
if (d_doExpandALIAS && rec.dr.d_type == QType::ALIAS) {
723726
// Set the A and AAAA in the NSEC bitmap so aggressive NSEC
724727
// does not falsely deny the type for this name.
725728
// This does NOT add the ALIAS to the bitmap, as that record cannot
726729
// be requested.
727730
if (!isPresigned()) {
728-
nrc.set(QType::A);
729-
nrc.set(QType::AAAA);
731+
bitmap.set(QType::A);
732+
bitmap.set(QType::AAAA);
730733
}
731734
}
732-
else if((rr.dr.d_type == QType::DNSKEY || rr.dr.d_type == QType::CDS || rr.dr.d_type == QType::CDNSKEY) && !isPresigned() && !::arg().mustDo("direct-dnskey")) {
735+
else if((rec.dr.d_type == QType::DNSKEY || rec.dr.d_type == QType::CDS || rec.dr.d_type == QType::CDNSKEY) && !isPresigned() && !::arg().mustDo("direct-dnskey")) {
733736
continue;
734737
}
735-
else if(rr.dr.d_type == QType::NS || rr.auth) {
736-
nrc.set(rr.dr.d_type);
738+
else if (rec.dr.d_type == QType::NS || rec.auth) {
739+
// skip empty non-terminals unless explicitly requested
740+
if (rec.dr.d_type != QType::ENT || includeENT) {
741+
bitmap.set(rec.dr.d_type);
742+
}
737743
}
738744
}
739745

740-
rr.dr.d_name = name;
741-
rr.dr.d_ttl = d_sd.getNegativeTTL();
742-
rr.dr.d_type = QType::NSEC;
743-
rr.dr.setContent(std::make_shared<NSECRecordContent>(std::move(nrc)));
744-
rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
745-
rr.auth = true;
746+
// Callers need a proper domain id value to put in the NSEC or NSEC3 record
747+
// they're building, for the sake of addRRSigs() later.
748+
return rec.domain_id;
749+
}
746750

747-
r->addRecord(std::move(rr));
751+
void PacketHandler::emitNSEC(std::unique_ptr<DNSPacket>& r, const DNSName& name, const DNSName& next, int mode)
752+
{
753+
NSECBitmap bitmap;
754+
if (d_sd.qname() == name) {
755+
computeNSECbitmap1(bitmap);
756+
}
757+
758+
DNSZoneRecord rec;
759+
rec.domain_id = computeNSECbitmap2(bitmap, name, true);
760+
761+
NSECRecordContent nrc;
762+
nrc.d_next = next;
763+
nrc.set(bitmap);
764+
nrc.set(QType::NSEC);
765+
nrc.set(QType::RRSIG);
766+
767+
rec.dr.d_name = name;
768+
rec.dr.d_ttl = d_sd.getNegativeTTL();
769+
rec.dr.d_type = QType::NSEC;
770+
rec.dr.setContent(std::make_shared<NSECRecordContent>(std::move(nrc)));
771+
rec.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
772+
rec.auth = true;
773+
774+
r->addRecord(std::move(rec));
748775
}
749776

750777
void PacketHandler::emitNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const NSEC3PARAMRecordContent& ns3prc, const DNSName& name, const string& namehash, const string& nexthash, int mode) // NOLINT(readability-identifier-length)
751778
{
752-
NSEC3RecordContent n3rc;
753-
n3rc.d_algorithm = ns3prc.d_algorithm;
754-
n3rc.d_flags = ns3prc.d_flags;
755-
n3rc.d_iterations = ns3prc.d_iterations;
756-
n3rc.d_salt = ns3prc.d_salt;
757-
n3rc.d_nexthash = nexthash;
758-
759-
DNSZoneRecord rr;
779+
NSECBitmap bitmap;
780+
DNSZoneRecord rec;
760781

761-
if(!name.empty()) {
782+
if (!name.empty()) {
762783
if (d_sd.qname() == name) {
763-
n3rc.set(QType::SOA); // 1dfd8ad SOA can live outside the records table
764-
n3rc.set(QType::NSEC3PARAM);
765-
if(!isPresigned()) {
766-
auto keyset = d_dk.getKeys(d_sd.zonename);
767-
for(const auto& value: keyset) {
768-
if (value.second.published) {
769-
n3rc.set(QType::DNSKEY);
770-
string publishCDNSKEY;
771-
d_dk.getPublishCDNSKEY(d_sd.zonename, publishCDNSKEY);
772-
if (! publishCDNSKEY.empty())
773-
n3rc.set(QType::CDNSKEY);
774-
string publishCDS;
775-
d_dk.getPublishCDS(d_sd.zonename, publishCDS);
776-
if (! publishCDS.empty())
777-
n3rc.set(QType::CDS);
778-
break;
779-
}
780-
}
781-
}
782-
} else if(mode == 6) {
784+
bitmap.set(QType::NSEC3PARAM);
785+
computeNSECbitmap1(bitmap);
786+
bitmap.set(QType::SOA); // 1dfd8ad SOA can live outside the records table
787+
} else if (mode == 6) {
783788
if (p.qtype.getCode() != QType::CDS) {
784-
n3rc.set(QType::CDS);
789+
bitmap.set(QType::CDS);
785790
}
786791
if (p.qtype.getCode() != QType::CDNSKEY) {
787-
n3rc.set(QType::CDNSKEY);
792+
bitmap.set(QType::CDNSKEY);
788793
}
789794
}
790795

791-
#ifdef HAVE_LUA_RECORDS
792-
bool first{true};
793-
bool doLua{false};
794-
#endif
795-
796-
B.lookup(QType(QType::ANY), name, d_sd.domain_id);
797-
while(B.get(rr)) {
798-
#ifdef HAVE_LUA_RECORDS
799-
if (rr.dr.d_type == QType::LUA && first && !isPresigned()) {
800-
first = false;
801-
doLua = doLuaRecords();
802-
}
803-
804-
if (rr.dr.d_type == QType::LUA && doLua) {
805-
n3rc.set(getRR<LUARecordContent>(rr.dr)->d_type);
806-
}
807-
else
808-
#endif
809-
if (d_doExpandALIAS && rr.dr.d_type == QType::ALIAS) {
810-
// Set the A and AAAA in the NSEC3 bitmap so aggressive NSEC
811-
// does not falsely deny the type for this name.
812-
// This does NOT add the ALIAS to the bitmap, as that record cannot
813-
// be requested.
814-
if (!isPresigned()) {
815-
n3rc.set(QType::A);
816-
n3rc.set(QType::AAAA);
817-
}
818-
}
819-
else if((rr.dr.d_type == QType::DNSKEY || rr.dr.d_type == QType::CDS || rr.dr.d_type == QType::CDNSKEY) && !isPresigned() && !::arg().mustDo("direct-dnskey")) {
820-
continue;
821-
}
822-
else if(rr.dr.d_type && (rr.dr.d_type == QType::NS || rr.auth)) {
823-
// skip empty non-terminals
824-
n3rc.set(rr.dr.d_type);
825-
}
826-
}
796+
rec.domain_id = computeNSECbitmap2(bitmap, name, false); // skip empty non-terminals
827797
}
828798

799+
NSEC3RecordContent n3rc;
800+
n3rc.d_algorithm = ns3prc.d_algorithm;
801+
n3rc.d_flags = ns3prc.d_flags;
802+
n3rc.d_iterations = ns3prc.d_iterations;
803+
n3rc.d_salt = ns3prc.d_salt;
804+
n3rc.d_nexthash = nexthash;
805+
806+
n3rc.set(bitmap);
829807
const auto numberOfTypesSet = n3rc.numberOfTypesSet();
830808
if (numberOfTypesSet != 0 && !(numberOfTypesSet == 1 && n3rc.isSet(QType::NS))) {
831809
n3rc.set(QType::RRSIG);
832810
}
833811

834-
rr.dr.d_name = DNSName(toBase32Hex(namehash))+d_sd.qname();
835-
rr.dr.d_ttl = d_sd.getNegativeTTL();
836-
rr.dr.d_type=QType::NSEC3;
837-
rr.dr.setContent(std::make_shared<NSEC3RecordContent>(std::move(n3rc)));
838-
rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
839-
rr.auth = true;
812+
rec.dr.d_name = DNSName(toBase32Hex(namehash))+d_sd.qname();
813+
rec.dr.d_ttl = d_sd.getNegativeTTL();
814+
rec.dr.d_type=QType::NSEC3;
815+
rec.dr.setContent(std::make_shared<NSEC3RecordContent>(std::move(n3rc)));
816+
rec.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
817+
rec.auth = true;
840818

841-
r->addRecord(std::move(rr));
819+
r->addRecord(std::move(rec));
842820
}
843821

844822
/*

pdns/packethandler.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ private:
8888
void addNSEC(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, int mode);
8989
bool getNSEC3Hashes(bool narrow, const std::string& hashed, bool decrement, DNSName& unhashed, std::string& before, std::string& after, int mode=0);
9090
void addNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
91+
void computeNSECbitmap1(NSECBitmap& bitmap);
92+
domainid_t computeNSECbitmap2(NSECBitmap& bitmap, const DNSName& name, bool includeENT);
9193
void emitNSEC(std::unique_ptr<DNSPacket>& r, const DNSName& name, const DNSName& next, int mode);
9294
void emitNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const NSEC3PARAMRecordContent &ns3prc, const DNSName& name, const string& namehash, const string& nexthash, int mode);
9395
int processUpdate(DNSPacket& p);

0 commit comments

Comments
 (0)