Browse Source

[2267] cover the case separated RRSIGs of the same type are given.

JINMEI Tatuya 12 years ago
parent
commit
869d1d2049

+ 15 - 10
src/lib/datasrc/memory/memory_client.cc

@@ -502,20 +502,25 @@ public:
     void addFromLoad(const ConstRRsetPtr& rrset,
                      const Name& zone_name, ZoneData* zone_data)
     {
+        // If we see a new name, flush the temporary holders, adding the
+        // pairs of RRsets and RRSIGs of the previous name to the zone.
         if ((!node_rrsets_.empty() || !node_rrsigsets_.empty()) &&
             getCurrentName() != rrset->getName()) {
             flushNodeRRsets(zone_name, zone_data);
         }
-        if (rrset->getType() == RRType::RRSIG()) {
-            node_rrsigsets_.insert(NodeRRsetsVal(getCoveredType(rrset),
-                                                 rrset));
-        } else {
-            if (!node_rrsets_.insert(NodeRRsetsVal(rrset->getType(),
-                                                   rrset)).second) {
-                isc_throw(AddError,
-                          "Duplicate add of the same type of RRset: "
-                          << rrset->getName() << "/" << rrset->getType());
-            }
+
+        // Store this RRset until it can be added to the zone.  The current
+        // implementation requires RRs of the same RRset should be added at
+        // once, so we check the "duplicate" here.
+        const bool is_rrsig = rrset->getType() == RRType::RRSIG();
+        NodeRRsets& node_rrsets = is_rrsig ? node_rrsigsets_ : node_rrsets_;
+        const RRType& rrtype = is_rrsig ?
+            getCoveredType(rrset) : rrset->getType();
+        if (!node_rrsets.insert(NodeRRsetsVal(rrtype, rrset)).second) {
+            isc_throw(AddError,
+                      "Duplicate add of the same type of"
+                      << (is_rrsig ? " RRSIG" : "") << " RRset: "
+                      << rrset->getName() << "/" << rrtype);
         }
     }
     void flushNodeRRsets(const Name& zone_name, ZoneData* zone_data) {

+ 28 - 14
src/lib/datasrc/memory/tests/memory_client_unittest.cc

@@ -61,25 +61,31 @@ const char* rrset_data[] = {
     NULL
 };
 
-// Similar to the previous, but RRs of the same RRset are separated.
+// RRsets that emulate the "separate RRs" mode.
 const char* rrset_data_separated[] = {
     "example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. "
     "68 3600 300 3600000 3600",
+    "a.example.org. 3600 IN A 192.168.0.1", // these two belong to the same
+    "a.example.org. 3600 IN A 192.168.0.2", // RRset, but are separated.
+    NULL
+};
+
+// Similar to the previous one, but with separated RRSIGs
+const char* rrset_data_sigseparated[] = {
+    "example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. "
+    "68 3600 300 3600000 3600",
     "a.example.org. 3600 IN A 192.168.0.1",
-    "a.example.org. 3600 IN A 192.168.0.2",
-// This will trigger a bug in the implementation
-//     "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
-//     "40430 example.org. FAKEFAKE",
-    "a.example.org. 3600 IN MX 10 mail.example.org.",
-    "a.example.org. 3600 IN RRSIG MX 5 3 3600 20150420235959 20051021000000 "
-    "40430 example.org. FAKEFAKEFAKE",
+    "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
+    "40430 example.org. FAKEFAKE",
+    "a.example.org. 3600 IN RRSIG A 5 3 3600 20150420235959 20051021000000 "
+    "53535 example.org. FAKEFAKE",
     NULL
 };
 
 class MockIterator : public ZoneIterator {
 private:
-    MockIterator(bool separate_rrs) :
-        rrset_data_ptr_(separate_rrs ? rrset_data_separated : rrset_data)
+    MockIterator(const char** rrset_data_ptr) :
+        rrset_data_ptr_(rrset_data_ptr)
     {
     }
 
@@ -102,8 +108,8 @@ public:
         isc_throw(isc::NotImplemented, "Not implemented");
     }
 
-    static ZoneIteratorPtr makeIterator(bool separate_rrs = false) {
-        return (ZoneIteratorPtr(new MockIterator(separate_rrs)));
+    static ZoneIteratorPtr makeIterator(const char** rrset_data_ptr) {
+        return (ZoneIteratorPtr(new MockIterator(rrset_data_ptr)));
     }
 };
 
@@ -186,7 +192,8 @@ TEST_F(MemoryClientTest, load) {
 }
 
 TEST_F(MemoryClientTest, loadFromIterator) {
-    client_->load(Name("example.org"), *MockIterator::makeIterator());
+    client_->load(Name("example.org"),
+                  *MockIterator::makeIterator(rrset_data));
 
     ZoneIteratorPtr iterator(client_->getIterator(Name("example.org")));
 
@@ -217,7 +224,14 @@ TEST_F(MemoryClientTest, loadFromIterator) {
     // will fail because the resulting sequence doesn't meet assumptions of
     // the (current) in-memory implementation.
     EXPECT_THROW(client_->load(Name("example.org"),
-                               *MockIterator::makeIterator(true)),
+                               *MockIterator::makeIterator(
+                                   rrset_data_separated)),
+                 InMemoryClient::AddError);
+
+    // Similar to the previous case, but with separated RRSIGs.
+    EXPECT_THROW(client_->load(Name("example.org"),
+                               *MockIterator::makeIterator(
+                                   rrset_data_sigseparated)),
                  InMemoryClient::AddError);
 }