}
}
+void
+Query::addNXDOMAINProofByNSEC3(ZoneFinder& finder) {
+ // Firstly get the NSEC3 proves for Closest Encloser Proof
+ // See section 7.2.1 of RFC 5155.
+ // Since this is a Name Error case both closest and next proofs should
+ // be available (see addNXRRsetProof).
+ const ZoneFinder::FindNSEC3Result fresult1 = finder.findNSEC3(qname_,
+ true);
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ fresult1.closest_proof),
+ dnssec_);
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ fresult1.next_proof),
+ dnssec_);
+
+ // Next, construct the wildcard name at the closest encloser, i.e.,
+ // '*' followed by the closest encloser, and add NSEC3 for it.
+ const Name wildname(Name("*").concatenate(
+ qname_.split(qname_.getLabelCount() -
+ fresult1.closest_labels)));
+ const ZoneFinder::FindNSEC3Result fresult2 =
+ finder.findNSEC3(wildname, false);
+ if (fresult2.matched) {
+ isc_throw(BadNSEC3, "Matching NSEC3 found for nonexistent domain "
+ << wildname);
+ }
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ fresult2.closest_proof),
+ dnssec_);
+}
+
void
- Query::addWildcardProof(ZoneFinder& finder) {
- // The query name shouldn't exist in the zone if there were no wildcard
- // substitution. Confirm that by specifying NO_WILDCARD. It should result
- // in NXDOMAIN and an NSEC RR that proves it should be returned.
- const ZoneFinder::FindResult fresult =
- finder.find(qname_, RRType::NSEC(),
- dnssec_opt_ | ZoneFinder::NO_WILDCARD);
- if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
- fresult.rrset->getRdataCount() == 0) {
- isc_throw(BadNSEC, "Unexpected result for wildcard proof");
+ Query::addWildcardProof(ZoneFinder& finder,
+ const ZoneFinder::FindResult& db_result)
+ {
+ if (db_result.isNSECSigned()) {
+ // Case for RFC4035 Section 3.1.3.3.
+ //
+ // The query name shouldn't exist in the zone if there were no wildcard
+ // substitution. Confirm that by specifying NO_WILDCARD. It should
+ // result in NXDOMAIN and an NSEC RR that proves it should be returned.
+ const ZoneFinder::FindResult fresult =
+ finder.find(qname_, RRType::NSEC(),
+ dnssec_opt_ | ZoneFinder::NO_WILDCARD);
+ if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
+ fresult.rrset->getRdataCount() == 0) {
+ isc_throw(BadNSEC,
+ "Unexpected NSEC result for wildcard proof");
+ }
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ fresult.rrset),
+ dnssec_);
+ } else if (db_result.isNSEC3Signed()) {
+ // Case for RFC5155 Section 7.2.6.
+ //
+ // Note that the closest encloser must be the immediate ancestor
+ // of the matching wildcard, so NSEC3 for its next closer is what
+ // we are expected to provided per the RFC (if this assumption isn't
+ // met the zone is broken anyway).
+ const ZoneFinder::FindNSEC3Result NSEC3Result(
+ finder.findNSEC3(qname_, true));
+ // Note that at this point next_proof must not be NULL unless it's
+ // a run time collision (or zone/findNSEC3() is broken). The
+ // unexpected case will be caught in addRRset() and result in SERVFAIL.
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<AbstractRRset>(
+ NSEC3Result.next_proof), dnssec_);
}
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(fresult.rrset),
- dnssec_);
}
void
/// Add NSEC RRs that prove an NXDOMAIN result.
///
/// This corresponds to Section 3.1.3.2 of RFC 4035.
- void addNXDOMAINProof(isc::datasrc::ZoneFinder& finder,
- isc::dns::ConstRRsetPtr nsec);
+ void addNXDOMAINProofByNSEC(isc::datasrc::ZoneFinder& finder,
+ isc::dns::ConstRRsetPtr nsec);
+
+ /// Add NSEC3 RRs that prove an NXDOMAIN result.
+ ///
+ /// This corresponds to Section 7.2.2 of RFC 5155.
+ void addNXDOMAINProofByNSEC3(isc::datasrc::ZoneFinder& finder);
- /// Add NSEC RRs that prove a wildcard answer is the best one.
+ /// Add NSEC or NSEC3 RRs that prove a wildcard answer is the best one.
///
- /// This corresponds to Section 3.1.3.3 of RFC 4035.
- void addWildcardProof(isc::datasrc::ZoneFinder& finder);
+ /// This corresponds to Section 3.1.3.3 of RFC 4035 and Section 7.2.6
+ /// of RFC5155.
+ void addWildcardProof(
+ isc::datasrc::ZoneFinder& finder,
+ const isc::datasrc::ZoneFinder::FindResult& dbResult);
/// \brief Adds one NSEC RR proved no matched QNAME,one NSEC RR proved no
/// matched <QNAME,QTYPE> through wildcard extension.