@@ -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
750774void 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/*
0 commit comments