Browse Source

[trac507] implemented the harder part of empty node support

Actually, it turns out to be much simpler than originally thought on top
of the RBTreeNodeChain extensions made on this branch so far.
JINMEI Tatuya 14 years ago
parent
commit
ab989937ae
2 changed files with 22 additions and 5 deletions
  1. 11 5
      src/lib/datasrc/memory_datasrc.cc
  2. 11 0
      src/lib/datasrc/tests/memory_datasrc_unittest.cc

+ 11 - 5
src/lib/datasrc/memory_datasrc.cc

@@ -199,10 +199,16 @@ struct MemoryZone::MemoryZoneImpl {
                 if (state.zonecut_node_ != NULL) {
                     return (FindResult(DELEGATION, state.rrset_));
                 }
-                // TODO: we should also cover empty non-terminal cases, which
-                // will require non trivial code and is deferred for later
-                // development.  For now, we regard any partial match that
-                // didn't hit a zone cut as "not found".
+
+                // If the RBTree search stopped at a node for a super domain
+                // of the search name, it means the search name exists in
+                // the zone but is empty.  Treat it as NXRRSET.
+                if (node_path.getLastComparisonResult().getRelation() ==
+                    NameComparisonResult::SUPERDOMAIN) {
+                    return (FindResult(NXRRSET, ConstRRsetPtr()));
+                }
+
+                // fall through
             case DomainTree::NOTFOUND:
                 return (FindResult(NXDOMAIN, ConstRRsetPtr()));
             case DomainTree::EXACTMATCH: // This one is OK, handle it
@@ -210,7 +216,7 @@ struct MemoryZone::MemoryZoneImpl {
             default:
                 assert(0);
         }
-        assert(node);
+        assert(node != NULL);
 
         // If there is an exact match but the node is empty, it's equivalent
         // to NXRRSET.

+ 11 - 0
src/lib/datasrc/tests/memory_datasrc_unittest.cc

@@ -401,6 +401,17 @@ TEST_F(MemoryZoneTest, emptyNode) {
     // empty node matching, easy case: the node for 'baz' exists with
     // no data.
     findTest(Name("baz.example.org"), RRType::A(), Zone::NXRRSET);
+
+    // empty node matching, a trickier case: the node for 'foo' is part of
+    // "x.foo", which should be considered an empty node.
+    findTest(Name("foo.example.org"), RRType::A(), Zone::NXRRSET);
+
+    // "org" is contained in "example.org", but it shouldn't be treated as
+    // NXRRSET because it's out of zone.
+    // Note: basically we don't expect such a query to be performed (the common
+    // operation is to identify the best matching zone first then perform
+    // search it), but we shouldn't be confused even in the unexpected case.
+    findTest(Name("org"), RRType::A(), Zone::NXDOMAIN);
 }
 
 TEST_F(MemoryZoneTest, load) {