Browse Source

[1310] Add dupicate check for NSEC RR.

xiejiagui 13 years ago
parent
commit
8279efec0d
3 changed files with 46 additions and 9 deletions
  1. 38 6
      src/bin/auth/query.cc
  2. 6 0
      src/bin/auth/query.h
  3. 2 3
      src/bin/auth/tests/query_unittest.cc

+ 38 - 6
src/bin/auth/query.cc

@@ -186,6 +186,41 @@ Query::addWildcardProof(ZoneFinder& finder) {
 }
 
 void
+Query::addWildcardNxrrsetProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
+    // 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.
+    if (nsec->getRdataCount() == 0) {
+	    isc_throw(BadNSEC, "NSEC for NXRRSET is empty");
+	    return;
+	}
+	
+	const ZoneFinder::FindResult fresult =
+        finder.find(qname_, RRType::NSEC(), NULL,
+                    dnssec_opt_ | ZoneFinder::NO_WILDCARD);
+    if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
+        fresult.rrset->getRdataCount() == 0) {
+        isc_throw(BadNSEC, "Unexpected result for no match QNAME proof");
+        return;
+    }
+   
+    if (nsec->getName() == fresult.rrset->getName()) {
+		// one NSEC RR proves wildcard_nxrrset and no matched QNAME.
+        response_.addRRset(Message::SECTION_AUTHORITY,
+                           boost::const_pointer_cast<RRset>(fresult.rrset),
+                           dnssec_);
+    } else {
+    	// add NSEC RR that proves wildcard_nxrrset.
+		response_.addRRset(Message::SECTION_AUTHORITY,
+                       boost::const_pointer_cast<RRset>(nsec), dnssec_);
+		// add NSEC RR that proves no matched QNAME.
+		response_.addRRset(Message::SECTION_AUTHORITY,
+                       boost::const_pointer_cast<RRset>(fresult.rrset),
+                       dnssec_);
+	}
+}
+
+void
 Query::addAuthAdditional(ZoneFinder& finder) {
     // Fill in authority and addtional sections.
     ZoneFinder::FindResult ns_result = finder.find(finder.getOrigin(),
@@ -356,12 +391,9 @@ Query::process() {
                 }
                 break;
 			case ZoneFinder::WILDCARD_NXRRSET:
-				addSOA(*result.zone_finder);
-				if(dnssec_ && db_result.rrset) {
-				   response_.addRRset(Message::SECTION_AUTHORITY,
-				   					  boost::const_pointer_cast<RRset>(
-									       db_result.rrset),
-									  dnssec_);
+                addSOA(*result.zone_finder);
+                if (dnssec_ && db_result.rrset) {
+					addWildcardNxrrsetProof(zfinder,db_result.rrset);
 				}
 				break;
             default:

+ 6 - 0
src/bin/auth/query.h

@@ -82,6 +82,12 @@ private:
     /// This corresponds to Section 3.1.3.3 of RFC 4035.
     void addWildcardProof(isc::datasrc::ZoneFinder& finder);
 
+    /// Add NSEC RRs that prove an WILDCARD_NXRRSET result.
+    ///
+    /// This corresponds to Section 3.1.3.4 of RFC 4035.
+    void addWildcardNxrrsetProof(isc::datasrc::ZoneFinder& finder,
+                          isc::dns::ConstRRsetPtr nsec);
+
     /// \brief Look up additional data (i.e., address records for the names
     /// included in NS or MX records) and add them to the additional section.
     ///

+ 2 - 3
src/bin/auth/tests/query_unittest.cc

@@ -116,7 +116,6 @@ const char* const nsec_mx_txt =
     "mx.example.com. 3600 IN NSEC ).no.example.com. MX NSEC RRSIG\n";
 const char* const nsec_no_txt =
     ").no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG\n";
-
 // We'll also test the case where a single NSEC proves both NXDOMAIN and the
 // non existence of wildcard.  The following records will be used for that
 // test.
@@ -181,7 +180,7 @@ public:
             nsec_nxdomain_txt << nsec_www_txt << nonsec_a_txt <<
             wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt;
 
-        masterLoad(zone_stream, origin_, rrclass_,
+		masterLoad(zone_stream, origin_, rrclass_,
                    boost::bind(&MockZoneFinder::loadRRset, this, _1));
 
         empty_nsec_rrset_ = ConstRRsetPtr(new RRset(Name::ROOT_NAME(),
@@ -932,7 +931,7 @@ TEST_F(QueryTest, badWildcardProof3) {
                  Query::BadNSEC);
 }
 
-TEST_F(QueryTest, wildcardNxrrsetWithNSEC1) {
+TEST_F(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
     // NXRRSET with DNSSEC proof.  We should have SOA, NSEC that proves the
     // NXRRSET and their RRSIGs.
     Query(memory_client, Name("www.wild.example.com"), RRType::TXT(), response,