Browse Source

[1068] Throw an exception if an RRset is being added/deleted with RRSIG RRset.
Also updated doc and tests accordingly.

JINMEI Tatuya 13 years ago
parent
commit
230df58472
3 changed files with 32 additions and 0 deletions
  1. 10 0
      src/lib/datasrc/database.cc
  2. 12 0
      src/lib/datasrc/tests/database_unittest.cc
  3. 10 0
      src/lib/datasrc/zone.h

+ 10 - 0
src/lib/datasrc/database.cc

@@ -675,6 +675,11 @@ DatabaseUpdater::addRRset(const RRset& rrset) {
                   << "added to " << zone_name_ << "/" << zone_class_ << ": "
                   << rrset.toText());
     }
+    if (rrset.getRRsig()) {
+        isc_throw(DataSourceError, "An RRset with RRSIG is being added to "
+                  << zone_name_ << "/" << zone_class_ << ": "
+                  << rrset.toText());
+    }
 
     RdataIteratorPtr it = rrset.getRdataIterator();
     if (it->isLast()) {
@@ -716,6 +721,11 @@ DatabaseUpdater::deleteRRset(const RRset& rrset) {
                   << "deleted from " << zone_name_ << "/" << zone_class_
                   << ": " << rrset.toText());
     }
+    if (rrset.getRRsig()) {
+        isc_throw(DataSourceError, "An RRset with RRSIG is being deleted from "
+                  << zone_name_ << "/" << zone_class_ << ": "
+                  << rrset.toText());
+    }
 
     RdataIteratorPtr it = rrset.getRdataIterator();
     if (it->isLast()) {

+ 12 - 0
src/lib/datasrc/tests/database_unittest.cc

@@ -1772,6 +1772,12 @@ TEST_F(DatabaseClientTest, addEmptyRRset) {
     EXPECT_THROW(updater_->addRRset(*rrset_), DataSourceError);
 }
 
+TEST_F(DatabaseClientTest, addRRsetWithRRSIG) {
+    updater_ = client_->getUpdater(zname_, false);
+    rrset_->addRRsig(*rrsigset_);
+    EXPECT_THROW(updater_->addRRset(*rrset_), DataSourceError);
+}
+
 TEST_F(DatabaseClientTest, addAfterCommit) {
    updater_ = client_->getUpdater(zname_, false);
    updater_->commit();
@@ -1951,4 +1957,10 @@ TEST_F(DatabaseClientTest, deleteEmptyRRset) {
     rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
     EXPECT_THROW(updater_->deleteRRset(*rrset_), DataSourceError);
 }
+
+TEST_F(DatabaseClientTest, deleteRRsetWithRRSIG) {
+    updater_ = client_->getUpdater(zname_, false);
+    rrset_->addRRsig(*rrsigset_);
+    EXPECT_THROW(updater_->deleteRRset(*rrset_), DataSourceError);
+}
 }

+ 10 - 0
src/lib/datasrc/zone.h

@@ -279,6 +279,8 @@ public:
     /// It performs minimum level of validation on the specified RRset:
     /// - Whether the RR class is identical to that for the zone to be updated
     /// - Whether the RRset is not empty, i.e., it has at least one RDATA
+    /// - Whether the RRset is not associated with an RRSIG, i.e.,
+    ///   whether \c getRRsig() on the RRset returns a NULL pointer.
     ///
     /// and otherwise does not check any oddity.  For example, it doesn't
     /// check whether the owner name of the specified RRset is a subdomain
@@ -289,6 +291,12 @@ public:
     /// the existing data beforehand using the \c ZoneFinder returned by
     /// \c getFinder().
     ///
+    /// The validation requirement on the associated RRSIG is temporary.
+    /// If we find it more reasonable and useful to allow adding a pair of
+    /// RRset and its RRSIG RRset as we gain experiences with the interface,
+    /// we may remove this restriction.  Until then we explicitly check it
+    /// to prevent accidental misuse.
+    ///
     /// Conceptually, on successful call to this method, the zone will have
     /// the specified RRset, and if there is already an RRset of the same
     /// name and RR type, these two sets will be "merged".  "Merged" means
@@ -368,6 +376,8 @@ public:
     /// RRset:
     /// - Whether the RR class is identical to that for the zone to be updated
     /// - Whether the RRset is not empty, i.e., it has at least one RDATA
+    /// - Whether the RRset is not associated with an RRSIG, i.e.,
+    ///   whether \c getRRsig() on the RRset returns a NULL pointer.
     ///
     /// This method must not be called once commit() is performed.  If it
     /// calls after \c commit() the implementation must throw a