Browse Source

Implement MemoryZone::find

It does not handle CNAME and DNAME yet.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac447@3960 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
30c2e8884f
1 changed files with 66 additions and 6 deletions
  1. 66 6
      src/lib/datasrc/memory_datasrc.cc

+ 66 - 6
src/lib/datasrc/memory_datasrc.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <map>
+#include <iostream>
 #include <boost/shared_ptr.hpp>
 
 #include <dns/name.h>
@@ -57,6 +58,7 @@ struct MemoryZone::MemoryZoneImpl {
     typedef RBTree<Domain> DomainTree;
     typedef RBNode<Domain> DomainNode;
     // The actual zone data
+    // (address by relative names to the origin_)
     DomainTree domains_;
 
     /*
@@ -86,17 +88,16 @@ struct MemoryZone::MemoryZoneImpl {
      * Implementation of longer methods. We put them here, because the
      * access is without the impl_-> and it will get inlined anyway.
      */
-    // Implementation of MemyroyZone::add
+    // Implementation of MemoryZone::add
     result::Result add(const ConstRRsetPtr& rrset) {
         // Sanitize input
         if (!rrset) {
             isc_throw(NullRRset, "The rrset provided is NULL");
         }
         Name relative_name(getRelativeName(rrset->getName()));
-        // TODO We do not need to store the part above the zone cut
         // Get the node
         DomainNode* node;
-        switch (domains_.insert(rrset->getName(), &node)) {
+        switch (domains_.insert(relative_name, &node)) {
             // Just check it returns reasonable results
             case DomainTree::SUCCEED:
             case DomainTree::ALREADYEXIST:
@@ -129,6 +130,66 @@ struct MemoryZone::MemoryZoneImpl {
             return (result::EXIST);
         }
     }
+
+    // Implementation of MemoryZone::find
+    FindResult find(const Name& full_name, RRType type) const {
+        try {
+            // Get the relative name
+            Name relative_name(getRelativeName(full_name));
+            // What we return when we succeed.
+            bool delegation(false);
+            // Get the node
+            DomainNode* node;
+            switch (domains_.find(relative_name, &node)) {
+                case DomainTree::PARTIALMATCH:
+                    // We change to looking for a NS record in the node
+                    delegation = true;
+                    type = RRType::NS();
+                    break; // And handle it the usual way
+                case DomainTree::NOTFOUND:
+                    return (FindResult(NXDOMAIN, ConstRRsetPtr()));
+                case DomainTree::EXACTMATCH: // This one is OK, handle it
+                    break;
+                default:
+                    isc_throw(AssertError,
+                        "RBTree<Domain>::find returned unexpected result");
+            }
+            if (!node) {
+                isc_throw(AssertError,
+                    "RBTree<Domain>::find gave NULL node when not returning"
+                    "NOTFOUND");
+            }
+            if (node->isEmpty()) {
+                isc_throw(AssertError,
+                    "RBTree<Domain>::find gave empty node");
+            }
+
+            Domain::const_iterator found(node->getData()->find(type));
+            if (found != node->getData()->end()) {
+                // Good, it is here
+                // Return either SUCCESS or DELEGATION
+                return (FindResult(delegation ? DELEGATION : SUCCESS,
+                    found->second));
+            } else {
+                /*
+                 * TODO Look for CNAME and DNAME (it should be OK to do so when
+                 * the value is not found, as CNAME/DNAME domain should be
+                 * empty otherwise.)
+                 */
+                if (delegation) {
+                    // If we were trying a delegation, then we have NXDOMAIN
+                    return (FindResult(NXDOMAIN, ConstRRsetPtr()));
+                } else {
+                    return (FindResult(NXRRSET, ConstRRsetPtr()));
+                }
+            }
+        }
+        catch (const OutOfZone&) {
+            // We were asked for something that is not below our origin
+            // So it is not here for sure
+            return (FindResult(NXDOMAIN, ConstRRsetPtr()));
+        }
+    }
 };
 
 MemoryZone::MemoryZone(const RRClass& zone_class, const Name& origin) :
@@ -151,9 +212,8 @@ MemoryZone::getClass() const {
 }
 
 Zone::FindResult
-MemoryZone::find(const Name&, const RRType&) const {
-    // This is a tentative implementation that always returns NXDOMAIN.
-    return (FindResult(NXDOMAIN, RRsetPtr()));
+MemoryZone::find(const Name& name, const RRType& type) const {
+    return (impl_->find(name, type));
 }
 
 result::Result