Browse Source

[2098] supported wildcard-expanded owner names

JINMEI Tatuya 12 years ago
parent
commit
a65a2f9e38

+ 49 - 2
src/lib/datasrc/memory/tests/treenode_rrset_unittest.cc

@@ -44,6 +44,7 @@ protected:
     TreeNodeRRsetTest() :
         rrclass_(RRClass::IN()),
         origin_name_("example.com"), www_name_("www.example.com"),
+        wildcard_name_("*.example.com"), match_name_("match.example.com"),
         ns_rrset_(textToRRset("example.com. 3600 IN NS ns.example.com.")),
         a_rrset_(textToRRset("www.example.com. 3600 IN A 192.0.2.1\n"
                              "www.example.com. 3600 IN A 192.0.2.2")),
@@ -62,6 +63,13 @@ protected:
         txt_rrsig_rrset_(textToRRset("www.example.com. 3600 IN RRSIG TXT 5 2"
                                      " 3600 20120814220826 20120715220826 "
                                      "1234 example.com. FAKE\n")),
+        wildmatch_rrset_(textToRRset(
+                             "match.example.com. 3600 IN A 192.0.2.1\n"
+                             "match.example.com. 3600 IN A 192.0.2.2")),
+        wildmatch_rrsig_rrset_(textToRRset(
+                                   "match.example.com. 3600 IN RRSIG "
+                                   "A 5 2 3600 20120814220826 20120715220826 "
+                                   "1234 example.com. FAKE")),
         zone_data_(NULL)
     {}
     void SetUp() {
@@ -92,6 +100,11 @@ protected:
                                                 ConstRRsetPtr(),
                                                 txt_rrsig_rrset_);
         aaaa_rdataset_->next = rrsig_only_rdataset_;
+
+        zone_data_->insertName(mem_sgmt_, wildcard_name_, &wildcard_node_);
+        wildcard_rdataset_ = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
+                                              a_rrsig_rrset_);
+        wildcard_node_->setData(wildcard_rdataset_);
     }
     void TearDown() {
         ZoneData::destroy(mem_sgmt_, zone_data_, rrclass_);
@@ -100,20 +113,23 @@ protected:
     }
 
     const RRClass rrclass_;
-    const Name origin_name_, www_name_;
+    const Name origin_name_, www_name_, wildcard_name_, match_name_;
     isc::util::MemorySegmentLocal mem_sgmt_;
     RdataEncoder encoder_;
     MessageRenderer renderer_, renderer_expected_;
     ConstRRsetPtr ns_rrset_, a_rrset_, aaaa_rrset_, dname_rrset_,
-        a_rrsig_rrset_, aaaa_rrsig_rrset_, txt_rrsig_rrset_;
+        a_rrsig_rrset_, aaaa_rrsig_rrset_, txt_rrsig_rrset_,
+        wildmatch_rrset_, wildmatch_rrsig_rrset_;
     ZoneData* zone_data_;
     ZoneNode* origin_node_;
     ZoneNode* www_node_;
+    ZoneNode* wildcard_node_;
     RdataSet* ns_rdataset_;
     RdataSet* dname_rdataset_;
     RdataSet* a_rdataset_;
     RdataSet* aaaa_rdataset_;
     RdataSet* rrsig_only_rdataset_;
+    RdataSet* wildcard_rdataset_; // for wildcard (type doesn't matter much)
 };
 
 // Check some trivial fields of a constructed TreeNodeRRset (passed as
@@ -154,6 +170,11 @@ TEST_F(TreeNodeRRsetTest, create) {
     checkBasicFields(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
                                    false),
                      www_name_, rrclass_, RRType::TXT(), 0, 0);
+    // Wildcard substitution
+    checkBasicFields(TreeNodeRRset(match_name_, rrclass_,
+                                   wildcard_node_, wildcard_rdataset_,
+                                   true),
+                     match_name_, rrclass_, RRType::A(), 2, 1);
 }
 
 // Templated if and when we support OutputBuffer version of toWire().
@@ -236,6 +257,24 @@ TEST_F(TreeNodeRRsetTest, toWire) {
     }
 
     {
+        SCOPED_TRACE("wildcard with RRSIG");
+        checkToWireResult(expected_renderer, actual_renderer,
+                          TreeNodeRRset(match_name_, rrclass_, wildcard_node_,
+                                        wildcard_rdataset_, true),
+                          origin_name_, wildmatch_rrset_,
+                          wildmatch_rrsig_rrset_, true);
+    }
+
+    {
+        SCOPED_TRACE("wildcard without RRSIG");
+        checkToWireResult(expected_renderer, actual_renderer,
+                          TreeNodeRRset(match_name_, rrclass_, wildcard_node_,
+                                        wildcard_rdataset_, false),
+                          origin_name_, wildmatch_rrset_,
+                          wildmatch_rrsig_rrset_, false);
+    }
+
+    {
         // Very unusual case: the set only contains RRSIG (already rare)
         // and it's requested to be dumped to wire (can only happen in
         // ANY or type-RRSIG queries, which are rare also).  But can still
@@ -407,6 +446,14 @@ TEST_F(TreeNodeRRsetTest, toText) {
     // Constructed without RRSIG, and it should be visible
     checkToText(TreeNodeRRset(rrclass_, origin_node_, ns_rdataset_, false),
                 ns_rrset_, ConstRRsetPtr());
+    // Wildcard expanded name with RRSIG
+    checkToText(TreeNodeRRset(match_name_, rrclass_, wildcard_node_,
+                              wildcard_rdataset_, true),
+                wildmatch_rrset_, wildmatch_rrsig_rrset_);
+    // Wildcard expanded name without RRSIG
+    checkToText(TreeNodeRRset(match_name_, rrclass_, wildcard_node_,
+                              wildcard_rdataset_, false),
+                wildmatch_rrset_, ConstRRsetPtr());
     // RRSIG case
     checkToText(TreeNodeRRset(rrclass_, www_node_, rrsig_only_rdataset_,
                               true),

+ 18 - 5
src/lib/datasrc/memory/treenode_rrset.cc

@@ -40,13 +40,26 @@ namespace isc {
 namespace datasrc {
 namespace memory {
 
+TreeNodeRRset::TreeNodeRRset(const dns::Name& realname, dns::RRClass rrclass,
+                             const ZoneNode* node, const RdataSet* rdataset,
+                             bool dnssec_ok) :
+    node_(node), rdataset_(rdataset),
+    rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
+    dnssec_ok_(dnssec_ok), name_(NULL)
+{
+    const LabelSequence labels(realname);
+    const size_t labels_storangelen = labels.getSerializedLength();
+    realname_buf_ = new uint8_t[labels_storangelen];
+    labels.serialize(realname_buf_, labels_storangelen);
+}
+
 const Name&
 TreeNodeRRset::getName() const {
     if (name_ == NULL) {
         uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
-        const LabelSequence node_labels = node_->getAbsoluteLabels(labels_buf);
+        const LabelSequence name_labels = getOwnerLabels(labels_buf);
         size_t data_len;
-        const uint8_t* data = node_labels.getData(&data_len);
+        const uint8_t* data = name_labels.getData(&data_len);
         util::InputBuffer buffer(data, data_len);
         name_ = new Name(buffer);
     }
@@ -169,11 +182,11 @@ TreeNodeRRset::toWire(AbstractMessageRenderer& renderer) const {
 
     // Get the owner name of the RRset in the form of LabelSequence.
     uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
-    const LabelSequence node_labels = node_->getAbsoluteLabels(labels_buf);
+    const LabelSequence name_labels = getOwnerLabels(labels_buf);
 
     // Render the main (non RRSIG) RRs
     const size_t rendered_rdata_count =
-        writeRRs(renderer, rdataset_->getRdataCount(), node_labels,
+        writeRRs(renderer, rdataset_->getRdataCount(), name_labels,
                  rdataset_->type, rrclass_, rdataset_->getTTLData(), reader,
                  &RdataReader::iterateRdata);
     if (renderer.isTruncated()) {
@@ -184,7 +197,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_, node_labels, RRType::RRSIG(),
+        writeRRs(renderer, rrsig_count_, name_labels, RRType::RRSIG(),
                  rrclass_, rdataset_->getTTLData(), reader,
                  &RdataReader::iterateSingleSig) : 0;
 

+ 15 - 1
src/lib/datasrc/memory/treenode_rrset.h

@@ -61,10 +61,15 @@ public:
                   const RdataSet* rdataset, bool dnssec_ok) :
         node_(node), rdataset_(rdataset),
         rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
-        dnssec_ok_(dnssec_ok), name_(NULL)
+        dnssec_ok_(dnssec_ok), name_(NULL), realname_buf_(NULL)
     {}
 
+    TreeNodeRRset(const dns::Name& realname, dns::RRClass rrclass,
+                  const ZoneNode* node, const RdataSet* rdataset,
+                  bool dnssec_ok);
+
     virtual ~TreeNodeRRset() {
+        delete[] realname_buf_;
         delete name_;
     }
 
@@ -116,6 +121,14 @@ private:
     dns::RdataIteratorPtr getSigRdataIterator() const;
     dns::RdataIteratorPtr getRdataIteratorInternal(bool is_rrsig,
                                                    size_t count) const;
+    dns::LabelSequence getOwnerLabels(
+        uint8_t labels_buf[dns::LabelSequence::MAX_SERIALIZED_LENGTH]) const
+    {
+        if (realname_buf_ != NULL) {
+            return (dns::LabelSequence(realname_buf_));
+        }
+        return (node_->getAbsoluteLabels(labels_buf));
+    }
 
     const ZoneNode* node_;
     const RdataSet* rdataset_;
@@ -123,6 +136,7 @@ private:
     const dns::RRClass rrclass_;
     const bool dnssec_ok_;
     mutable dns::Name* name_;
+    uint8_t* realname_buf_;
 };
 
 } // namespace memory