Browse Source

[1608] handle the case where additional refers to an empty non-terminal node.

JINMEI Tatuya 13 years ago
parent
commit
27ec89e237

+ 7 - 1
src/lib/datasrc/memory_datasrc.cc

@@ -309,6 +309,9 @@ insertRRsets(const AdditionalNodeInfo& additional,
              vector<ConstRRsetPtr>* result, bool glue_ok)
              vector<ConstRRsetPtr>* result, bool glue_ok)
 {
 {
     assert(additional.node_ != NULL);
     assert(additional.node_ != NULL);
+    if (additional.node_->isEmpty()) {
+        return;
+    }
     if (!glue_ok && additional.node_->getFlag(DOMAINFLAG_GLUE)) {
     if (!glue_ok && additional.node_->getFlag(DOMAINFLAG_GLUE)) {
         return;
         return;
     }
     }
@@ -1295,7 +1298,7 @@ addAdditional(RBNodeRRset* rrset, ZoneData* zone_data) {
         // child zone), mark the node as "GLUE", so we can selectively
         // child zone), mark the node as "GLUE", so we can selectively
         // include/exclude them when we use it.
         // include/exclude them when we use it.
 
 
-        // TODO: zone cut consideration (DNAME), empty node case, wildcard
+        // TODO: wildcard
         RBTreeNodeChain<Domain> node_path;
         RBTreeNodeChain<Domain> node_path;
         DomainNode* node = NULL;
         DomainNode* node = NULL;
         // The callback argument is a pair of bools: the first is a flag to
         // The callback argument is a pair of bools: the first is a flag to
@@ -1316,6 +1319,9 @@ addAdditional(RBNodeRRset* rrset, ZoneData* zone_data) {
                 // The node is under or at a zone cut; mark it as a glue.
                 // The node is under or at a zone cut; mark it as a glue.
                 node->setFlag(DOMAINFLAG_GLUE);
                 node->setFlag(DOMAINFLAG_GLUE);
             }
             }
+            // Note that node may be empty.  We should keep it in the list
+            // in case we dynamically update the tree and it becomes non empty
+            // (which is not supported yet)
             rrset->addAdditionalNode(node);
             rrset->addAdditionalNode(node);
         }
         }
     }
     }

+ 9 - 1
src/lib/datasrc/tests/testdata/contexttest.zone

@@ -1,7 +1,7 @@
 ;; test zone file used for ZoneFinderContext tests.
 ;; test zone file used for ZoneFinderContext tests.
 ;; RRSIGs are (obviouslly) faked ones for testing.
 ;; RRSIGs are (obviouslly) faked ones for testing.
 
 
-example.org. 3600 IN SOA	ns1.example.org. bugs.x.w.example.org. 41 3600 300 3600000 3600
+example.org. 3600 IN SOA	ns1.example.org. bugs.x.w.example.org. 52 3600 300 3600000 3600
 example.org.			      3600 IN NS	ns1.example.org.
 example.org.			      3600 IN NS	ns1.example.org.
 example.org.			      3600 IN NS	ns2.example.org.
 example.org.			      3600 IN NS	ns2.example.org.
 example.org.			      3600 IN MX	1 mx1.example.org.
 example.org.			      3600 IN MX	1 mx1.example.org.
@@ -49,6 +49,14 @@ ns.dname.example.org.		      3600 IN A		192.0.2.11
 dname.example.org.		      3600 IN A		192.0.2.12
 dname.example.org.		      3600 IN A		192.0.2.12
 ns.deepdname.example.org.	      3600 IN AAAA	2001:db8::9
 ns.deepdname.example.org.	      3600 IN AAAA	2001:db8::9
 
 
+;; delegation, one of its NS name is at an empty non terminal.
+d.example.org. 	      	      3600 IN NS	ns.empty.example.org.
+d.example.org. 	      	      3600 IN NS	ns1.example.org.
+;; by adding these two we can create an empty RB node for
+;; ns.empty.example.org in the in-memory zone
+foo.ns.empty.example.org.     3600 IN A		192.0.2.13
+bar.ns.empty.example.org.     3600 IN A		192.0.2.14
+
 ;; CNAME
 ;; CNAME
 alias.example.org. 3600 IN CNAME cname.example.org.
 alias.example.org. 3600 IN CNAME cname.example.org.
 
 

+ 13 - 0
src/lib/datasrc/tests/zone_finder_context_unittest.cc

@@ -248,6 +248,19 @@ TEST_P(ZoneFinderContextTest, getAdditionalDelegationWithDname) {
                 result_sets_.begin(), result_sets_.end());
                 result_sets_.begin(), result_sets_.end());
 }
 }
 
 
+TEST_P(ZoneFinderContextTest, getAdditionalDelegationWithEmptyName) {
+    // One of NS names is at an empty non terminal node.  It shouldn't cause
+    // any disruption.
+    ZoneFinderContextPtr ctx = finder_->find(Name("www.d.example.org"),
+                                             RRType::A());
+    EXPECT_EQ(ZoneFinder::DELEGATION, ctx->code);
+
+    ctx->getAdditional(REQUESTED_BOTH, result_sets_);
+    rrsetsCheck("ns1.example.org. 3600 IN A 192.0.2.1\n"
+                "ns1.example.org. 3600 IN AAAA 2001:db8::1\n",
+                result_sets_.begin(), result_sets_.end());
+}
+
 TEST_P(ZoneFinderContextTest, getAdditionalMX) {
 TEST_P(ZoneFinderContextTest, getAdditionalMX) {
     // Similar to the previous cases, but for MX addresses.  The test zone
     // Similar to the previous cases, but for MX addresses.  The test zone
     // contains MX name under a zone cut.  Its address shouldn't be returned.
     // contains MX name under a zone cut.  Its address shouldn't be returned.