Browse Source

[1310] Add unit test about two NSEC RRs which proved no matched
QNAME and via wildcard expansion no matched <QNAME,QTYPE>

xiejiagui 13 years ago
parent
commit
1f6edd11fb
3 changed files with 68 additions and 36 deletions
  1. 8 14
      src/bin/auth/query.cc
  2. 9 3
      src/bin/auth/query.h
  3. 51 19
      src/bin/auth/tests/query_unittest.cc

+ 8 - 14
src/bin/auth/query.cc

@@ -187,13 +187,15 @@ 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.
+    // There should be one NSEC RR which was found in the zone to prove
+	// that there is not matched <QNAME,QTYPE> via wildcard expansion.
     if (nsec->getRdataCount() == 0) {
-	    isc_throw(BadNSEC, "NSEC for NXRRSET is empty");
+	    isc_throw(BadNSEC, "NSEC for WILDCARD_NXRRSET is empty");
 	    return;
 	}
+    // Add this NSEC RR to authority section.
+	response_.addRRset(Message::SECTION_AUTHORITY,
+                      boost::const_pointer_cast<RRset>(nsec), dnssec_);
 	
 	const ZoneFinder::FindResult fresult =
         finder.find(qname_, RRType::NSEC(), NULL,
@@ -204,19 +206,11 @@ Query::addWildcardNxrrsetProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
         return;
     }
    
-    if (nsec->getName() == fresult.rrset->getName()) {
-		// one NSEC RR proves wildcard_nxrrset and no matched QNAME.
+    if (nsec->getName() != fresult.rrset->getName()) {
+		// one NSEC RR proves wildcard_nxrrset that 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_);
 	}
 }
 

+ 9 - 3
src/bin/auth/query.h

@@ -82,11 +82,17 @@ 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.
-    ///
+    /// \brief Adds one NSEC RR proved no matched QNAME,one NSEC RR proved no
+	///	matched <QNAME,QTYPE> through wildcard extension.
+	///
+	///	Add NSEC RRs that prove an WILDCARD_NXRRSET result.
     /// This corresponds to Section 3.1.3.4 of RFC 4035.
+	///	\param finder The ZoneFinder through which the authority data for the
+	///	query is to be found.
+	///	\param nsec The RRset (NSEC RR) which proved that there is no matched 
+	///	<QNAME,QTTYPE>.
     void addWildcardNxrrsetProof(isc::datasrc::ZoneFinder& finder,
-                          isc::dns::ConstRRsetPtr nsec);
+                         		 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.

+ 51 - 19
src/bin/auth/tests/query_unittest.cc

@@ -100,6 +100,15 @@ const char* const cnamewild_txt =
     "*.cnamewild.example.com. 3600 IN CNAME www.example.org.\n";
 const char* const nsec_cnamewild_txt = "*.cnamewild.example.com. "
     "3600 IN NSEC delegation.example.com. CNAME NSEC RRSIG\n";
+// Wildcard_nxrrset
+const char* const wild_txt_nxrrset =
+	"*.uwild.example.com. 3600 IN A 192.0.2.9\n";
+const char* const nsec_wild_txt_nxrrset =
+	"*.uwild.example.com. 3600 IN NSEC www.uwild.example.com. A NSEC RRSIG\n";
+const char* const wild_txt_next =
+	"www.uwild.example.com. 3600 IN A 192.0.2.11\n";
+const char* const nsec_wild_txt_next =
+	"www.uwild.example.com. 3600 IN NSEC *.wild.example.com. A NSEC RRSIG\n";
 // Used in NXDOMAIN proof test.  We are going to test some unusual case where
 // the best possible wildcard is below the "next domain" of the NSEC RR that
 // proves the NXDOMAIN, i.e.,
@@ -178,7 +187,9 @@ public:
             other_zone_rrs << no_txt << nz_txt <<
             nsec_apex_txt << nsec_mx_txt << nsec_no_txt << nsec_nz_txt <<
             nsec_nxdomain_txt << nsec_www_txt << nonsec_a_txt <<
-            wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt;
+            wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt <<
+            wild_txt_nxrrset<<nsec_wild_txt_nxrrset<<wild_txt_next<<
+            nsec_wild_txt_next;
 
 		masterLoad(zone_stream, origin_, rrclass_,
                    boost::bind(&MockZoneFinder::loadRRset, this, _1));
@@ -395,24 +406,28 @@ MockZoneFinder::find(const Name& name, const RRType& type,
     // hardcoded specific cases, ignoring other details such as canceling
     // due to the existence of closer name.
     if ((options & NO_WILDCARD) == 0) {
-        const Name wild_suffix("wild.example.com");
-        if (name.compare(wild_suffix).getRelation() ==
-            NameComparisonResult::SUBDOMAIN) {
-            domain = domains_.find(Name("*").concatenate(wild_suffix));
-            assert(domain != domains_.end());
-            RRsetStore::const_iterator found_rrset = domain->second.find(type);
-            if (found_rrset != domain->second.end()) {
-				return (FindResult(WILDCARD,
-                               substituteWild(*found_rrset->second, name)));
-			} else {
-				found_rrset = domain->second.find(RRType::NSEC());
-				assert(found_rrset != domain->second.end());
-				Name newName = Name("*").concatenate(wild_suffix);
-				return (FindResult(WILDCARD_NXRRSET,
-							   substituteWild(*found_rrset->second,newName)));
-			}
-
-        }
+        //const Name wild_suffix("wild.example.com");
+		const Name wild_suffix(name.split(1));
+		if (name.equals(Name("www.wild.example.com"))||
+		   name.equals(Name("www1.uwild.example.com"))) {
+        	if (name.compare(wild_suffix).getRelation() ==
+            	NameComparisonResult::SUBDOMAIN) {
+            	domain = domains_.find(Name("*").concatenate(wild_suffix));
+            	assert(domain != domains_.end());
+            	RRsetStore::const_iterator found_rrset = domain->second.find(type);
+            	if (found_rrset != domain->second.end()) {
+					return (FindResult(WILDCARD,
+                            substituteWild(*found_rrset->second, name)));
+				} else {
+					found_rrset = domain->second.find(RRType::NSEC());
+					assert(found_rrset != domain->second.end());
+					Name newName = Name("*").concatenate(wild_suffix);
+					return (FindResult(WILDCARD_NXRRSET,
+						   substituteWild(*found_rrset->second,newName)));
+				}
+
+       		 }
+		}
         const Name cnamewild_suffix("cnamewild.example.com");
         if (name.compare(cnamewild_suffix).getRelation() ==
             NameComparisonResult::SUBDOMAIN) {
@@ -946,6 +961,23 @@ TEST_F(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
                   NULL, mock_finder->getOrigin());
 }
 
+TEST_F(QueryTest, wildcardNxrrsetWithNSEC) {
+    // NXRRSET with DNSSEC proof.  We should have SOA, NSEC that proves the
+    // NXRRSET and their RRSIGs.
+    Query(memory_client, Name("www1.uwild.example.com"), RRType::TXT(), response,
+          true).process();
+    
+	responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
+                  (string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
+                   getCommonRRSIGText("SOA") + "\n" +
+                   string(nsec_wild_txt_nxrrset) + 
+                   string("*.uwild.example.com. 3600 IN RRSIG ") +
+                   getCommonRRSIGText("NSEC")+"\n" +
+				   string(nsec_wild_txt_next) +
+				   string("www.uwild.example.com. 3600 IN RRSIG ") +
+				   getCommonRRSIGText("NSEC") + "\n").c_str(),
+                  NULL, mock_finder->getOrigin());
+}
 /*
  * This tests that when there's no SOA and we need a negative answer. It should
  * throw in that case.