Skip to content

Commit 93486f9

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 93486f9

2 files changed

Lines changed: 94 additions & 116 deletions

File tree

pdns/packethandler.cc

Lines changed: 92 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -672,173 +672,149 @@ 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);
698689
}
690+
string publishCDS;
691+
d_dk.getPublishCDS(d_sd.zonename, publishCDS);
692+
if (!publishCDS.empty()) {
693+
bitmap.set(QType::CDS);
694+
}
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+
void 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
}
745+
}
739746

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;
747+
void PacketHandler::emitNSEC(std::unique_ptr<DNSPacket>& r, const DNSName& name, const DNSName& next, int mode)
748+
{
749+
NSECBitmap bitmap;
750+
if (d_sd.qname() == name) {
751+
computeNSECbitmap1(bitmap);
752+
}
753+
computeNSECbitmap2(bitmap, name, true);
746754

747-
r->addRecord(std::move(rr));
755+
NSECRecordContent nrc;
756+
nrc.d_next = next;
757+
nrc.set(bitmap);
758+
nrc.set(QType::NSEC);
759+
nrc.set(QType::RRSIG);
760+
761+
DNSZoneRecord rec;
762+
rec.dr.d_name = name;
763+
rec.dr.d_ttl = d_sd.getNegativeTTL();
764+
rec.dr.d_type = QType::NSEC;
765+
rec.dr.setContent(std::make_shared<NSECRecordContent>(std::move(nrc)));
766+
rec.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
767+
rec.auth = true;
768+
// A proper value is required for the sake of addRRSigs() later.
769+
rec.domain_id = d_sd.domain_id;
770+
771+
r->addRecord(std::move(rec));
748772
}
749773

750774
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)
751775
{
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;
776+
NSECBitmap bitmap;
760777

761-
if(!name.empty()) {
778+
if (!name.empty()) {
762779
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) {
780+
bitmap.set(QType::NSEC3PARAM);
781+
computeNSECbitmap1(bitmap);
782+
bitmap.set(QType::SOA); // 1dfd8ad SOA can live outside the records table
783+
} else if (mode == 6) {
783784
if (p.qtype.getCode() != QType::CDS) {
784-
n3rc.set(QType::CDS);
785+
bitmap.set(QType::CDS);
785786
}
786787
if (p.qtype.getCode() != QType::CDNSKEY) {
787-
n3rc.set(QType::CDNSKEY);
788-
}
789-
}
790-
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);
788+
bitmap.set(QType::CDNSKEY);
825789
}
826790
}
791+
computeNSECbitmap2(bitmap, name, false); // skip empty non-terminals
827792
}
828793

794+
NSEC3RecordContent n3rc;
795+
n3rc.d_algorithm = ns3prc.d_algorithm;
796+
n3rc.d_flags = ns3prc.d_flags;
797+
n3rc.d_iterations = ns3prc.d_iterations;
798+
n3rc.d_salt = ns3prc.d_salt;
799+
n3rc.d_nexthash = nexthash;
800+
801+
n3rc.set(bitmap);
829802
const auto numberOfTypesSet = n3rc.numberOfTypesSet();
830803
if (numberOfTypesSet != 0 && !(numberOfTypesSet == 1 && n3rc.isSet(QType::NS))) {
831804
n3rc.set(QType::RRSIG);
832805
}
833806

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;
807+
DNSZoneRecord rec;
808+
rec.dr.d_name = DNSName(toBase32Hex(namehash))+d_sd.qname();
809+
rec.dr.d_ttl = d_sd.getNegativeTTL();
810+
rec.dr.d_type=QType::NSEC3;
811+
rec.dr.setContent(std::make_shared<NSEC3RecordContent>(std::move(n3rc)));
812+
rec.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
813+
rec.auth = true;
814+
// A proper value is required for the sake of addRRSigs() later.
815+
rec.domain_id = d_sd.domain_id;
840816

841-
r->addRecord(std::move(rr));
817+
r->addRecord(std::move(rec));
842818
}
843819

844820
/*

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+
void 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)