From: Xie Jiagui Date: Thu, 16 Feb 2012 02:05:46 +0000 (+0800) Subject: [1580] Add new comments to NSEC3 proves for NXDOMAIN,and fix the X-Git-Tag: trac2351_base~247^2~4^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5af17f43de48dd58fe87b85d974a554ac0136b83;p=thirdparty%2Fkea.git [1580] Add new comments to NSEC3 proves for NXDOMAIN,and fix the construction of wildcard domain name. --- diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc index 2cb645c9f1..cfb0ccb618 100644 --- a/src/bin/auth/query.cc +++ b/src/bin/auth/query.cc @@ -171,48 +171,52 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) { // is broken, 'nsec3' should be a valid NSEC3 RR. Likewise, the call to // findNSEC3() in this method should result an FindNSEC3Result that proves // the Closest Encloser Proof and non existent of matching wildcard. -// If these assumptions aren't met due to a buggy data source implementation -// or a broken zone, we'll let underlying libdns++ modules throw an exception, -// which would result in either an SERVFAIL response or just ignoring the -// query. We at least prevent a complete crash due to such broken behavior. +// Firstly, the call to findNSEC3() set the recursive to true in order to +// get the an NSEC3 RR that matches the closest (provable) encloser and +// an NSEC3 RR that covers the "next closer" name to the closest encloser. +// This corresponds to Section 7.2.1 of RFC 5155. +// Then,construct the wildcard domain, call to findNSEC3() set the recursive +// to false to get the prove that the wildcard that could have matched QNAME +// also does not exist. void Query::addNSEC3NXDOMAINProof(ZoneFinder& finder) { // Firstly get the NSEC3 proves for Closest Encloser Proof + // See section 7.2.1 of RFC 5155. const ZoneFinder::FindNSEC3Result fresult1 = finder.findNSEC3(qname_, true); - if (fresult1.closest_proof->getRdataCount() == 0) { - isc_throw(BadNSEC3, "NSEC3 for NXDOMAIN proving that matches the " + if (!fresult1.closest_proof) { + isc_throw(BadNSEC3, "NSEC3 RR for NXDOMAIN proving that matches the " "closest encloser is empty."); } // Add the NSEC3 proving that matches the closest (provable) encloser. response_.addRRset(Message::SECTION_AUTHORITY, boost::const_pointer_cast( - fresult1.closest_proof), + fresult1.closest_proof), dnssec_); - // Add the NSEC3 RR that covers the "next closer" name to the closest - // encloser - if (fresult1.next_proof) { - response_.addRRset(Message::SECTION_AUTHORITY, - boost::const_pointer_cast( - fresult1.next_proof), - dnssec_); + if (!fresult1.next_proof) { + isc_throw(BadNSEC3, "NSEC3 RR for NXDOMAIN proving that covers the " + "next closer to the closest encloser is empty."); } + // Add the NSEC3 RR that covers the "next closer" name to the closest + // encloser. + response_.addRRset(Message::SECTION_AUTHORITY, + boost::const_pointer_cast( + fresult1.next_proof), + dnssec_); // Next, identify the best possible wildcard name that would match // the query name. It's the longer common suffix with the qname - // between the owner or the next domain of the NSEC that proves NXDOMAIN, - // prefixed by the wildcard label, "*". - const Name wildname(Name("*").concatenate(qname_.split(1))); + // between the owner and the 'matched' domain of the NSEC3 that + // proves NXDOMAIN,prefixed by the wildcard label, "*". + const Name wildname(Name("*").concatenate( + qname_.split(qname_.getLabelCount() - fresult1.closest_labels))); const ZoneFinder::FindNSEC3Result fresult2 = finder.findNSEC3(wildname, false); - if (fresult2.closest_proof->getRdataCount() == 0) { + if (!fresult2.closest_proof) { isc_throw(BadNSEC3, "NSEC3 for NXDOMAIN covering the wildcard " "RR at the closest encloser is empty."); } - // Add the (no-) wildcard proof only when it's different from the NSEC - // that proves NXDOMAIN; sometimes they can be the same. - // Note: name comparison is relatively expensive. When we are at the - // stage of performance optimization, we should consider optimizing this - // for some optimized data source implementations. + // Add the wildcard proof only when it's different from the NSEC3 RR + // that covers the "next closer" name to the closest encloser. if (fresult1.next_proof->getName() != fresult2.closest_proof->getName()) { response_.addRRset(Message::SECTION_AUTHORITY, boost::const_pointer_cast(