Browse Source

[2310] added a new constructo of TreeNodeRRset so we can specify the TTL.

JINMEI Tatuya 12 years ago
parent
commit
5e9d101a16

+ 3 - 4
src/lib/datasrc/memory/treenode_rrset.cc

@@ -59,8 +59,7 @@ TreeNodeRRset::getName() const {
 const RRTTL&
 TreeNodeRRset::getTTL() const {
     if (ttl_ == NULL) {
-        util::InputBuffer ttl_buffer(rdataset_->getTTLData(),
-                                     sizeof(uint32_t));
+        util::InputBuffer ttl_buffer(ttl_data_, sizeof(uint32_t));
         ttl_ = new RRTTL(ttl_buffer);
     }
 
@@ -169,7 +168,7 @@ TreeNodeRRset::toWire(AbstractMessageRenderer& renderer) const {
     // Render the main (non RRSIG) RRs
     const size_t rendered_rdata_count =
         writeRRs(renderer, rdataset_->getRdataCount(), name_labels,
-                 rdataset_->type, rrclass_, rdataset_->getTTLData(), reader,
+                 rdataset_->type, rrclass_, ttl_data_, reader,
                  &RdataReader::iterateRdata);
     if (renderer.isTruncated()) {
         return (rendered_rdata_count);
@@ -180,7 +179,7 @@ TreeNodeRRset::toWire(AbstractMessageRenderer& renderer) const {
     // Render any RRSIGs, if we supposed to do so
     const size_t rendered_rrsig_count = dnssec_ok_ ?
         writeRRs(renderer, rrsig_count_, name_labels, RRType::RRSIG(),
-                 rrclass_, rdataset_->getTTLData(), reader,
+                 rrclass_, ttl_data_, reader,
                  &RdataReader::iterateSingleSig) : 0;
 
     return (rendered_rdata_count + rendered_rrsig_count);

+ 26 - 3
src/lib/datasrc/memory/treenode_rrset.h

@@ -112,12 +112,34 @@ public:
                   const RdataSet* rdataset, bool dnssec_ok) :
         node_(node), rdataset_(rdataset),
         rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
-        dnssec_ok_(dnssec_ok), name_(NULL), realname_(NULL), ttl_(NULL)
+        dnssec_ok_(dnssec_ok), name_(NULL), realname_(NULL),
+        ttl_data_(rdataset->getTTLData()), ttl_(NULL)
+    {}
+
+    /// \brief Constructor with a specific TTL.
+    ///
+    /// This constructor is mostly the same as the normal version, but takes
+    /// an extra parameter, \c ttl_data.  It's expected to point to a memory
+    /// region at least for 32 bits, and the corresponding 32-bit data will
+    /// be used as wire-format TTL value of the RRset, instead of the TTL
+    /// associated with \c rdataset.
+    ///
+    /// It's the caller's responsibility to guarantee the memory region is
+    /// valid and intact throughout the lifetime of the RRset.
+    ///
+    /// \throw None
+    TreeNodeRRset(const dns::RRClass& rrclass, const ZoneNode* node,
+                  const RdataSet* rdataset, bool dnssec_ok,
+                  const void* ttl_data) :
+        node_(node), rdataset_(rdataset),
+        rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
+        dnssec_ok_(dnssec_ok), name_(NULL), realname_(NULL),
+        ttl_data_(ttl_data), ttl_(NULL)
     {}
 
     /// \brief Constructor for wildcard-expanded owner name.
     ///
-    /// This constructor is mostly the same as the other version, but takes
+    /// This constructor is mostly the same as the normal version, but takes
     /// an extra parameter, \c realname.  It effectively overrides the owner
     /// name of the RRset; wherever the owner name is used (e.g., in the
     /// \c toWire() method), the specified name will be used instead of
@@ -133,7 +155,7 @@ public:
         node_(node), rdataset_(rdataset),
         rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
         dnssec_ok_(dnssec_ok), name_(NULL), realname_(new dns::Name(realname)),
-	ttl_(NULL)
+	ttl_data_(rdataset->getTTLData()), ttl_(NULL)
     {}
 
     virtual ~TreeNodeRRset() {
@@ -255,6 +277,7 @@ private:
     const bool dnssec_ok_;
     mutable dns::Name* name_;
     const dns::Name* const realname_;
+    const void* const ttl_data_;
     mutable dns::RRTTL* ttl_;
 };
 

+ 44 - 3
src/lib/datasrc/tests/memory/treenode_rrset_unittest.cc

@@ -194,8 +194,14 @@ checkBasicFields(const AbstractRRset& actual_rrset, const RdataSet* rdataset,
 // a temporary non-copyable object.
 boost::shared_ptr<TreeNodeRRset>
 createRRset(const RRClass& rrclass, const ZoneNode* node,
-            const RdataSet* rdataset, bool dnssec_ok)
+            const RdataSet* rdataset, bool dnssec_ok,
+            const void* ttl_data = NULL)
 {
+    if (ttl_data) {
+        return (boost::shared_ptr<TreeNodeRRset>(
+                    new TreeNodeRRset(rrclass, node, rdataset, dnssec_ok,
+                                      ttl_data)));
+    }
     return (boost::shared_ptr<TreeNodeRRset>(
                 new TreeNodeRRset(rrclass, node, rdataset, dnssec_ok)));
 }
@@ -243,6 +249,13 @@ TEST_F(TreeNodeRRsetTest, create) {
                                   true),
                      wildcard_rdataset_, match_name_, rrclass_, RRType::A(),
                      3600, 2, 1);
+
+    // Constructed with explicit TTL
+    const uint32_t ttl = 0;     // use 0 to avoid byte-order conversion
+    checkBasicFields(*createRRset(rrclass_, www_node_, a_rdataset_, true,
+                                  &ttl),
+                     a_rdataset_, www_name_, rrclass_, RRType::A(), 0, 2,
+                     1);
 }
 
 // The following two templated functions are helper to encapsulate the
@@ -337,6 +350,21 @@ TEST_F(TreeNodeRRsetTest, toWire) {
     }
 
     {
+        SCOPED_TRACE("with RRSIG, DNSSEC OK, explicit TTL");
+        const uint32_t ttl = 0;
+        const TreeNodeRRset rrset(rrclass_, www_node_, a_rdataset_, true,
+                                  &ttl);
+        checkToWireResult(expected_renderer, actual_renderer, rrset,
+                          www_name_,
+                          textToRRset("www.example.com. 0 IN A 192.0.2.1\n"
+                                      "www.example.com. 0 IN A 192.0.2.2"),
+                          textToRRset("www.example.com. 0 IN RRSIG "
+                                      "A 5 2 3600 20120814220826 "
+                                      "20120715220826 1234 example.com. FAKE"),
+                          true);
+    }
+
+    {
         SCOPED_TRACE("with RRSIG, DNSSEC not OK");
         const TreeNodeRRset rrset(rrclass_, www_node_, a_rdataset_, false);
         checkToWireResult(expected_renderer, actual_renderer, rrset,
@@ -396,7 +424,7 @@ TEST_F(TreeNodeRRsetTest, toWire) {
         const TreeNodeRRset rrset(rrclass_, www_node_, rrsig_only_rdataset_,
                                   true);
         checkToWireResult(expected_renderer, actual_renderer, rrset,
-                          www_name_, ConstRRsetPtr(), txt_rrsig_rrset_,true);
+                          www_name_, ConstRRsetPtr(), txt_rrsig_rrset_, true);
     }
 
     {
@@ -407,7 +435,7 @@ TEST_F(TreeNodeRRsetTest, toWire) {
         const TreeNodeRRset rrset(rrclass_, www_node_, rrsig_only_rdataset_,
                                   false);
         checkToWireResult(expected_renderer, actual_renderer, rrset,
-                          www_name_, ConstRRsetPtr(), txt_rrsig_rrset_,false);
+                          www_name_, ConstRRsetPtr(), txt_rrsig_rrset_, false);
     }
 }
 
@@ -522,6 +550,14 @@ TEST_F(TreeNodeRRsetTest, toText) {
     // Constructed with RRSIG, and it should be visible.
     checkToText(*createRRset(rrclass_, www_node_, a_rdataset_, true),
                 a_rrset_, a_rrsig_rrset_);
+    // Same as the previous, but with explicit TTL.
+    const uint32_t ttl = 0;
+    checkToText(*createRRset(rrclass_, www_node_, a_rdataset_, true, &ttl),
+                textToRRset("www.example.com. 0 IN A 192.0.2.1\n"
+                            "www.example.com. 0 IN A 192.0.2.2"),
+                textToRRset("www.example.com. 0 IN RRSIG A 5 2 3600 "
+                            "20120814220826 20120715220826 1234 example.com. "
+                            "FAKE"));
     // Constructed with RRSIG, and it should be invisible.
     checkToText(*createRRset(rrclass_, www_node_, a_rdataset_, false),
                 a_rrset_, ConstRRsetPtr());
@@ -556,6 +592,11 @@ TEST_F(TreeNodeRRsetTest, isSameKind) {
     EXPECT_TRUE(rrset.isSameKind(*createRRset(rrclass_, www_node_,
                                               a_rdataset_, true)));
 
+    // Similar to the previous, but with explicit (different TTL) => still same
+    const uint32_t ttl = 0;
+    EXPECT_TRUE(rrset.isSameKind(*createRRset(rrclass_, www_node_,
+                                              a_rdataset_, true, &ttl)));
+
     // Same name (node), different type (rdataset) => not same kind
     EXPECT_FALSE(rrset.isSameKind(*createRRset(rrclass_, www_node_,
                                                aaaa_rdataset_, true)));