Browse Source

[1551] allow adding NSEC before CNAME for the same name

JINMEI Tatuya 13 years ago
parent
commit
85c2888f2f
2 changed files with 30 additions and 11 deletions
  1. 5 5
      src/lib/datasrc/memory_datasrc.cc
  2. 25 6
      src/lib/datasrc/tests/memory_datasrc_unittest.cc

+ 5 - 5
src/lib/datasrc/memory_datasrc.cc

@@ -179,12 +179,12 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
     void contextCheck(const ConstRRsetPtr& rrset,
                       const DomainPtr& domain) const {
         // Ensure CNAME and other type of RR don't coexist for the same
-        // owner name.
+        // owner name except with NSEC, which is the only RR that can coexist
+        // with CNAME (and also RRSIG, which is handled separately)
         if (rrset->getType() == RRType::CNAME()) {
-            // TODO: this check will become incorrect when we support DNSSEC
-            // (depending on how we support DNSSEC).  We should revisit it
-            // at that point.
-            if (!domain->empty()) {
+            if (!domain->empty() &&
+                (domain->size() > 1 ||
+                 (domain->begin()->second->getType() != RRType::NSEC()))) {
                 LOG_ERROR(logger, DATASRC_MEM_CNAME_TO_NONEMPTY).
                     arg(rrset->getName());
                 isc_throw(AddError, "CNAME can't be added with other data for "

+ 25 - 6
src/lib/datasrc/tests/memory_datasrc_unittest.cc

@@ -559,16 +559,35 @@ TEST_F(InMemoryZoneFinderTest, addOtherThenCNAME) {
     EXPECT_THROW(zone_finder_.add(rr_cname_), InMemoryZoneFinder::AddError);
 }
 
-TEST_F(InMemoryZoneFinderTest, addCNAMEThenDNSSECRecords) {
+TEST_F(InMemoryZoneFinderTest, addCNAMEAndDNSSECRecords) {
     // CNAME and RRSIG can coexist
     EXPECT_EQ(SUCCESS, zone_finder_.add(rr_cname_));
-    zone_finder_.add(textToRRset("cname.example.org. 300 IN RRSIG CNAME 5 3 "
-                                 "3600 20000101000000 20000201000000 12345 "
-                                 "example.org. FAKEFAKEFAKE"));
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname.example.org. 300 IN RRSIG CNAME 5 3 "
+                              "3600 20000101000000 20000201000000 12345 "
+                              "example.org. FAKEFAKEFAKE")));
 
     // Same for NSEC
-    zone_finder_.add(textToRRset("cname.example.org. 300 IN NSEC "
-                                 "dname.example.org. CNAME RRSIG NSEC"));
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname.example.org. 300 IN NSEC "
+                              "dname.example.org. CNAME RRSIG NSEC")));
+
+    // Same as above, but adding NSEC first.
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname2.example.org. 300 IN NSEC "
+                              "dname.example.org. CNAME RRSIG NSEC")));
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname2.example.org. 300 IN CNAME c.example.")));
+
+    // If there's another type of RRset with NSEC, it should still fail.
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname3.example.org. 300 IN A 192.0.2.1")));
+    EXPECT_EQ(SUCCESS, zone_finder_.add(
+                  textToRRset("cname3.example.org. 300 IN NSEC "
+                              "dname.example.org. CNAME RRSIG NSEC")));
+    EXPECT_THROW(zone_finder_.add(textToRRset("cname3.example.org. 300 "
+                                              "IN CNAME c.example.")),
+                 InMemoryZoneFinder::AddError);
 }
 
 TEST_F(InMemoryZoneFinderTest, findCNAME) {