[svn] commit: r1977 - in /branches/trac192/src/lib: datasrc/ datasrc/tests/ dns/ dns/tests/

BIND 10 source code commits bind10-changes at lists.isc.org
Sat May 29 02:56:27 UTC 2010


Author: each
Date: Sat May 29 02:56:27 2010
New Revision: 1977

Log:
checkpoint: hooked hot cache into query logic.

Modified:
    branches/trac192/src/lib/datasrc/TODO
    branches/trac192/src/lib/datasrc/cache.cc
    branches/trac192/src/lib/datasrc/cache.h
    branches/trac192/src/lib/datasrc/data_source.cc
    branches/trac192/src/lib/datasrc/data_source.h
    branches/trac192/src/lib/datasrc/query.cc
    branches/trac192/src/lib/datasrc/query.h
    branches/trac192/src/lib/datasrc/tests/cache_unittest.cc
    branches/trac192/src/lib/datasrc/tests/sqlite3_unittest.cc
    branches/trac192/src/lib/datasrc/tests/static_unittest.cc
    branches/trac192/src/lib/dns/rrsetlist.cc
    branches/trac192/src/lib/dns/rrsetlist.h
    branches/trac192/src/lib/dns/tests/rrsetlist_unittest.cc

Modified: branches/trac192/src/lib/datasrc/TODO
==============================================================================
--- branches/trac192/src/lib/datasrc/TODO (original)
+++ branches/trac192/src/lib/datasrc/TODO Sat May 29 02:56:27 2010
@@ -17,3 +17,12 @@
 
 - add a fast lookup method (using a hash table or a std::map)
   to HotCache so retrieval isn't linear.
+
+
+TESTS:
+  - ncache (also need to expand so that ncache returns appropriate status,
+            i.e., name not found or type not found)
+  - DS query
+  - make sure cache insert overwrites existing records
+
+- examine rdclass==ANY queries.  do these make sense to support in any way?

Modified: branches/trac192/src/lib/datasrc/cache.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/cache.cc (original)
+++ branches/trac192/src/lib/datasrc/cache.cc Sat May 29 02:56:27 2010
@@ -25,24 +25,34 @@
 namespace datasrc {
 
 // CacheNode constructors
-CacheNode::CacheNode(const isc::dns::RRsetPtr rrset, time_t interval) :
-    qname(rrset->getName()), qclass(rrset->getClass()),
-    qtype(rrset->getType()), rrset_(rrset)
+CacheNode::CacheNode(const isc::dns::RRsetPtr rrset, uint32_t flags,
+                     time_t interval) :
+    qname(rrset->getName()), qclass(rrset->getClass()), qtype(rrset->getType())
 {
     time_t now = time(NULL);
     expiry_ = now + interval;
 
+    entry_ = CacheEntryPtr(new CacheEntry);
+    entry_->rrset = rrset;
+    entry_->flags = flags;
+
     prev = CacheNodePtr();
     next = CacheNodePtr();
 }
 
 CacheNode::CacheNode(const isc::dns::Name& name,
                      const isc::dns::RRClass& rrclass,
-                     const isc::dns::RRType& rrtype, const time_t interval) :
-    qname(name), qclass(rrclass), qtype(rrtype), rrset_(RRsetPtr())
+                     const isc::dns::RRType& rrtype,
+                     uint32_t flags,
+                     const time_t interval) :
+    qname(name), qclass(rrclass), qtype(rrtype)
 {
     time_t now = time(NULL);
     expiry_ = now + interval;
+
+    entry_ = CacheEntryPtr(new CacheEntry);
+    entry_->rrset = RRsetPtr();
+    entry_->flags = flags;
 
     prev = CacheNodePtr();
     next = CacheNodePtr();
@@ -71,29 +81,27 @@
     head = tail = CacheNodePtr();
 }
 
-RRsetPtr
-HotCache::retrieve(Name qname, RRClass qclass, RRType qtype) {
+
+CacheNodePtr
+HotCache::retrieve(Name n, RRClass c, RRType t) {
     CacheNodePtr node;
 
-    node = head;
-    do {
-        if (node->qtype == qtype && node->qclass == qclass &&
-            node->qname == qname)
-        {
+    for (node = head; node != CacheNodePtr(); node = node->next) {
+        if (node->qtype == t && node->qclass == c && node->qname == n) {
             break;
         }
-    } while (node = node->next);
+    }
 
     if (! node) {
-        return (RRsetPtr());
+        return (CacheNodePtr());
     }
 
     if (node->isValid()) {
         promote(node);
-        return (node->getRRset());
+        return (node);
     } else {
         remove(node);
-        return (RRsetPtr());
+        return (CacheNodePtr());
     }
 }
 
@@ -117,16 +125,22 @@
 }
 
 void
-HotCache::cache(RRsetPtr rrset, const time_t interval) {
-    CacheNodePtr node(new CacheNode(rrset, interval));
-    this->insert(node);
+HotCache::cache(RRsetPtr rrset, const uint32_t flags, const time_t interval) {
+    CacheNodePtr node(new CacheNode(rrset, flags, interval));
+    insert(node);
 }
 
 void
 HotCache::ncache(const Name& name, const RRClass &rrclass,
-                 const RRType& rrtype, const time_t interval) {
-    CacheNodePtr node(new CacheNode(name, rrclass, rrtype, interval));
-    this->insert(node);
+                 const RRType& rrtype, const uint32_t flags,
+                 const time_t interval)
+{
+    if (rrtype == RRType::ANY() || rrclass == RRClass::ANY()) {
+        return;
+    }
+
+    CacheNodePtr node(new CacheNode(name, rrclass, rrtype, flags, interval));
+    insert(node);
 }
 
 void

Modified: branches/trac192/src/lib/datasrc/cache.h
==============================================================================
--- branches/trac192/src/lib/datasrc/cache.h (original)
+++ branches/trac192/src/lib/datasrc/cache.h Sat May 29 02:56:27 2010
@@ -31,23 +31,35 @@
 namespace datasrc {
 
 class CacheNode;
+typedef boost::shared_ptr<CacheNode> CacheNodePtr;
+class CacheEntry;
+typedef boost::shared_ptr<CacheEntry> CacheEntryPtr;
 
-typedef boost::shared_ptr<CacheNode> CacheNodePtr;
+class CacheEntry {
+public:
+    isc::dns::RRsetPtr rrset;
+    uint32_t flags;
+};
 
 // A node in the data cache; keyed by qname/qclass/qtype, contains a
 // pointer to a single RRset.
 class CacheNode {
 public:
     // Constructors
-    CacheNode(const isc::dns::RRsetPtr rrset, time_t interval);
-    CacheNode(const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
-              const isc::dns::RRType& rrtype, const time_t interval);
+    CacheNode(const isc::dns::RRsetPtr rrset,
+              const uint32_t flags,
+              time_t interval);
+    CacheNode(const isc::dns::Name& name,
+              const isc::dns::RRClass& rrclass,
+              const isc::dns::RRType& rrtype,
+              const uint32_t flags,
+              const time_t interval);
 
     // Destructor
     ~CacheNode();
 
-    isc::dns::RRsetPtr getRRset() const { return (rrset_); }
-
+    isc::dns::RRsetPtr getRRset() const { return (entry_->rrset); }
+    uint32_t getFlags() const { return (entry_->flags); }
     bool isValid() const;
 
     // List pointers
@@ -62,7 +74,7 @@
 
 private:
     // The cached RRset data
-    const isc::dns::RRsetPtr rrset_;
+    CacheEntryPtr entry_;
 
     // When the record should be discarded
     time_t expiry_;
@@ -78,16 +90,21 @@
     ~HotCache();
 
     // Retrieve a record from the cache
-    isc::dns::RRsetPtr retrieve(isc::dns::Name qname,
-                                isc::dns::RRClass qclass,
-                                isc::dns::RRType qtype);
+    CacheNodePtr retrieve(isc::dns::Name qname,
+                          isc::dns::RRClass qclass,
+                          isc::dns::RRType qtype);
 
     // Positively cache an RRset
-    void cache(isc::dns::RRsetPtr rrset, const time_t interval);
+    void cache(isc::dns::RRsetPtr rrset,
+               const uint32_t flags,
+               const time_t interval = 30);
 
     // Negatively cache a name/class/type tuple
-    void ncache(const isc::dns::Name& name, const isc::dns::RRClass& rrclass,
-                const isc::dns::RRType& rrtype, const time_t interval);
+    void ncache(const isc::dns::Name& name,
+                const isc::dns::RRClass& rrclass,
+                const isc::dns::RRType& rrtype,
+                const uint32_t flags,
+                const time_t interval = 30);
 
     void setSlots(int slots);
     int getSlots() const;

Modified: branches/trac192/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/data_source.cc (original)
+++ branches/trac192/src/lib/datasrc/data_source.cc Sat May 29 02:56:27 2010
@@ -24,6 +24,10 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/foreach.hpp>
 
+#include <datasrc/cache.h>
+#include <datasrc/data_source.h>
+#include <datasrc/query.h>
+
 #include <dns/base32.h>
 #include <dns/buffer.h>
 #include <dns/message.h>
@@ -34,9 +38,6 @@
 #include <dns/sha1.h>
 
 #include <cc/data.h>
-
-#include "data_source.h"
-#include "query.h"
 
 #define RETERR(x) do { \
                       DataSrc::Result r = (x); \
@@ -125,6 +126,7 @@
         return;
     }
 
+    // Stop chasing CNAMES after 16 lookups, to prevent loops
     if (q.tooMany()) {
         return;
     }
@@ -139,31 +141,306 @@
 // Perform the query specified in a QueryTask object
 DataSrc::Result
 doQueryTask(QueryTask& task, NameMatch& zoneinfo, RRsetList& target) {
+    HotCache& cache = task.q.cache;
+    RRsetList rrsets;
+    RRsetPtr rrset;
+    CacheNodePtr cnode;
+    int count = 0;
+    uint32_t flags = 0;
+    bool found = false;
+
+    // First, we check the hot cache for the requested information.
+    switch (task.op) {
+    case QueryTask::SIMPLE_QUERY:       // Find exact RRset
+        if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
+            // ANY queries must be handled by the low-level data source
+            // or the results won't be guaranteed to be complete
+            break;
+        }
+
+        cnode  = cache.retrieve(task.qname, task.qclass, task.qtype);
+        if (!cnode) {
+            break;
+        }
+
+        rrset = cnode->getRRset();
+        flags = cnode->getFlags();
+
+        if (rrset) {
+            rrsets.addRRset(cnode->getRRset());
+            ++count;
+        } else {
+            ++count;
+        }
+
+        if (count == 1) {
+            task.flags = flags;
+            target.append(rrsets);
+            return (DataSrc::SUCCESS);
+        }
+        break;
+
+    case QueryTask::AUTH_QUERY:         // Find exact RRset or CNAME
+        if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
+            break;
+        }
+
+        cnode = cache.retrieve(task.qname, task.qclass, task.qtype);
+        if (!cnode || !cnode->getRRset() != 0) {
+            CacheNodePtr cnamenode = cache.retrieve(task.qname, task.qclass,
+                                                    RRType::CNAME());
+            if (cnamenode && cnamenode->getRRset()) {
+                cnode = cnamenode;
+            }
+        }
+        if (!cnode) {
+            break;
+        }
+
+        rrset = cnode->getRRset();
+        flags = cnode->getFlags();
+
+        if (rrset) {
+            rrsets.addRRset(rrset);
+            task.flags = flags;
+            ++count;
+        } else {
+            ++count;
+        }
+
+        if (count == 1) {
+            target.append(rrsets);
+            task.flags = flags;
+            return (DataSrc::SUCCESS);
+        }
+        break;
+
+    case QueryTask::GLUE_QUERY:         // Find addresses
+    case QueryTask::NOGLUE_QUERY:
+        // (XXX: need to figure out how to deal with noglue case)
+        cnode = cache.retrieve(task.qname, task.qclass, RRType::A());
+        if (cnode) {
+            rrset = cnode->getRRset();
+            flags = cnode->getFlags();
+            if (rrset) {
+                rrsets.addRRset(rrset);
+                found = true;
+                ++count;
+            } else {
+                ++count;
+            }
+        }
+
+        cnode = cache.retrieve(task.qname, task.qclass, RRType::AAAA());
+        if (cnode) {
+            rrset = cnode->getRRset();
+            flags |= cnode->getFlags();
+            if (rrset) {
+                rrsets.addRRset(rrset);
+                found = true;
+                ++count;
+            } else {
+                ++count;
+            }
+        }
+
+        if (count == 2) {
+            if (found) {
+                flags &= ~DataSrc::TYPE_NOT_FOUND;
+            }
+            task.flags = flags;
+            target.append(rrsets);
+            return (DataSrc::SUCCESS);
+        } 
+        break;
+
+
+    case QueryTask::REF_QUERY:          // Find NS, DS and/or DNAME
+        cnode = cache.retrieve(task.qname, task.qclass, RRType::NS());
+        if (cnode) {
+            rrset = cnode->getRRset();
+            flags = cnode->getFlags();
+            if (rrset) {
+                rrsets.addRRset(rrset);
+                found = true;
+                ++count;
+            } else {
+                ++count;
+            }
+        }
+
+        cnode = cache.retrieve(task.qname, task.qclass, RRType::DS());
+        if (cnode) {
+            rrset = cnode->getRRset();
+            flags |= cnode->getFlags();
+            if (rrset) {
+                rrsets.addRRset(rrset);
+                found = true;
+                ++count;
+            } else {
+                ++count;
+            }
+        }
+
+        cnode = cache.retrieve(task.qname, task.qclass, RRType::DNAME());
+        if (cnode) {
+            rrset = cnode->getRRset();
+            flags |= cnode->getFlags();
+            if (rrset) {
+                rrsets.addRRset(rrset);
+                found = true;
+                ++count;
+            } else {
+                ++count;
+            }
+        }
+
+        if (count == 3) {
+            if (found) {
+                flags &= ~DataSrc::TYPE_NOT_FOUND;
+                flags &= DataSrc::REFERRAL;
+            }
+            task.flags = flags;
+            target.append(rrsets);
+            return (DataSrc::SUCCESS);
+        } 
+        break;
+    }
+
+    // Requested data weren't in the cache (or were, but had expired),
+    // so now we proceed with the low-level data source lookup, and cache
+    // whatever we find.
     const DataSrc* ds = zoneinfo.datasrc();
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
 
     if (ds == NULL) {
-        task.flags = DataSrc::NO_SUCH_ZONE;
+        task.flags |= DataSrc::NO_SUCH_ZONE;
         return (DataSrc::SUCCESS);
     }
 
+    DataSrc::Result result;
     switch (task.op) {
+    case QueryTask::SIMPLE_QUERY:
+        result = ds->findExactRRset(task.qname, task.qclass, task.qtype,
+                                    target, task.flags, zonename);
+
+        if (result != DataSrc::SUCCESS) {
+            return (result);
+        }
+
+        if (task.qclass == RRClass::ANY()) {
+            // XXX: Currently, RRsetList::findRRset() doesn't handle
+            // ANY queries, and without that we can't cache the results,
+            // so we just return in that case.
+            return (result);
+        }
+
+        if (task.flags == 0) {
+            rrset = target.findRRset(task.qtype, task.qclass);
+            assert(rrset);
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, task.qtype, task.flags);
+        }
+
+        return (result);
+
     case QueryTask::AUTH_QUERY:
-        return (ds->findRRset(task.qname, task.qclass, task.qtype,
-                              target, task.flags, zonename));
-
-    case QueryTask::SIMPLE_QUERY:
-        return (ds->findExactRRset(task.qname, task.qclass, task.qtype,
-                                   target, task.flags, zonename));
+        result = ds->findRRset(task.qname, task.qclass, task.qtype,
+                               target, task.flags, zonename);
+
+        if (result != DataSrc::SUCCESS) {
+            return (result);
+        }
+
+        if (task.qclass == RRClass::ANY()) {
+            return (result);
+        }
+
+        if (task.qtype == RRType::ANY()) {
+            BOOST_FOREACH(RRsetPtr rr, target) {
+                cache.cache(rr, task.flags);
+            }
+        } else if (task.flags == 0) {
+            if (task.qtype != RRType::CNAME()) {
+                cache.ncache(task.qname, task.qclass, RRType::CNAME(),
+                             task.flags);
+            }
+            rrset = target.findRRset(task.qtype, task.qclass);
+            assert(rrset);
+            cache.cache(rrset, task.flags);
+        } else if ((task.flags & DataSrc::CNAME_FOUND) != 0) {
+            cache.ncache(task.qname, task.qclass, task.qtype, task.flags);
+            rrset = target.findRRset(RRType::CNAME(), task.qclass);
+            assert(rrset);
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, task.qtype, task.flags);
+        }
+
+        return (result);
 
     case QueryTask::GLUE_QUERY:
     case QueryTask::NOGLUE_QUERY:
-        return (ds->findAddrs(task.qname, task.qclass, target,
-                              task.flags, zonename));
+        result = ds->findAddrs(task.qname, task.qclass, target,
+                               task.flags, zonename);
+
+        if (result != DataSrc::SUCCESS) {
+            return (result);
+        }
+
+        if (task.qclass == RRClass::ANY()) {
+            return (result);
+        }
+
+        rrset = target.findRRset(RRType::A(), task.qclass);
+        if (rrset) {
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, RRType::A(), task.flags);
+        }
+
+        rrset = target.findRRset(RRType::AAAA(), task.qclass);
+        if (rrset) {
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, RRType::AAAA(), task.flags);
+        }
+
+        return (result);
 
     case QueryTask::REF_QUERY:
-        return (ds->findReferral(task.qname, task.qclass, target,
-                                 task.flags, zonename));
+        result = ds->findReferral(task.qname, task.qclass, target,
+                                 task.flags, zonename);
+
+        if (result != DataSrc::SUCCESS) {
+            return (result);
+        }
+
+        if (task.qclass == RRClass::ANY()) {
+            return (result);
+        }
+
+        rrset = target.findRRset(RRType::NS(), task.qclass);
+        if (rrset) {
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, RRType::NS(), task.flags);
+        }
+        rrset = target.findRRset(RRType::DS(), task.qclass);
+        if (rrset) {
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, RRType::DS(), task.flags);
+        }
+        rrset = target.findRRset(RRType::DNAME(), task.qclass);
+        if (rrset) {
+            cache.cache(rrset, task.flags);
+        } else {
+            cache.ncache(task.qname, task.qclass, RRType::DNAME(), task.flags);
+        }
+
+        return (result);
     }
 
     // Not reached
@@ -209,7 +486,7 @@
 // referrals.
 inline bool
 hasDelegation(Query& q, QueryTaskPtr task, NameMatch& zoneinfo) {
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
     if (zonename == NULL) {
         if (task->state == QueryTask::GETANSWER) {
             q.message().setRcode(Rcode::REFUSED());
@@ -277,7 +554,7 @@
     Message& m = q.message();
     RRsetList soa;
 
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
     QueryTask newtask(q, *zonename, RRType::SOA(), QueryTask::SIMPLE_QUERY);
     RETERR(doQueryTask(newtask, zoneinfo, soa));
     if (newtask.flags != 0) {
@@ -307,7 +584,7 @@
 inline DataSrc::Result
 getNsec3(Query& q, NameMatch& zoneinfo, string& hash, RRsetPtr& target) {
     const DataSrc* ds = zoneinfo.datasrc();
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
 
     if (ds == NULL) {
         q.message().setRcode(Rcode::SERVFAIL());
@@ -326,7 +603,7 @@
     DataSrc::Result result;
     RRsetList nsec3param;
 
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
     QueryTask newtask(q, *zonename, RRType::NSEC3PARAM(),
                       QueryTask::SIMPLE_QUERY); 
     result = doQueryTask(newtask, zoneinfo, nsec3param);
@@ -358,7 +635,7 @@
 inline DataSrc::Result
 proveNX(Query& q, QueryTaskPtr task, NameMatch& zoneinfo, const bool wildcard) {
     Message& m = q.message();
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
     ConstNsec3ParamPtr nsec3 = getNsec3Param(q, zoneinfo);
 
     if (nsec3 != NULL) {
@@ -452,7 +729,7 @@
         return (DataSrc::SUCCESS);
     }
 
-    Name* zonename = zoneinfo.zonename();
+    Name* zonename = zoneinfo.name();
     const int nlen = task->qname.getLabelCount();
     const int diff = nlen - zonename->getLabelCount();
     if (diff < 1) {
@@ -594,7 +871,7 @@
         // Query found a referral; let's find out if that was expected--
         // i.e., if an NS was at the zone apex, or if we were querying
         // specifically for, and found, a DS, NSEC, or DNAME record.
-        Name* zonename = zoneinfo.zonename();
+        Name* zonename = zoneinfo.name();
         if ((task->flags & REFERRAL) != 0 &&
             (zonename->getLabelCount() == task->qname.getLabelCount() ||
              ((task->qtype == RRType::NSEC() ||

Modified: branches/trac192/src/lib/datasrc/data_source.h
==============================================================================
--- branches/trac192/src/lib/datasrc/data_source.h (original)
+++ branches/trac192/src/lib/datasrc/data_source.h Sat May 29 02:56:27 2010
@@ -326,7 +326,7 @@
     const isc::dns::RRClass& qclass() const { return (qclass_); }
     const isc::dns::RRType& qtype() const { return (qtype_); }
 
-    isc::dns::Name* zonename() {
+    isc::dns::Name* name() {
         if (!closest_name_) {
             top_source_->findClosestEnclosure(*this);
         }

Modified: branches/trac192/src/lib/datasrc/query.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/query.cc (original)
+++ branches/trac192/src/lib/datasrc/query.cc Sat May 29 02:56:27 2010
@@ -88,6 +88,14 @@
 
 QueryTask::~QueryTask() {}
 
+// Initialize the static query cache, used by all instances of Query.
+//
+// NOTE: This object is guaranteed by the C++ specification to be
+// constructed before main() runs, but not necessarily before any
+// global variable's constructor.  For safety, it should never be
+// accessed by any constructor, not even Query::Query().
+HotCache Query::cache(0);
+
 Query::Query(Message& m, bool dnssec) :
     status_(PENDING), qname_(NULL), qclass_(NULL), qtype_(NULL),
     message_(&m), want_additional_(true), want_dnssec_(dnssec)

Modified: branches/trac192/src/lib/datasrc/query.h
==============================================================================
--- branches/trac192/src/lib/datasrc/query.h (original)
+++ branches/trac192/src/lib/datasrc/query.h Sat May 29 02:56:27 2010
@@ -19,6 +19,7 @@
 
 #include <boost/shared_ptr.hpp>
 
+#include <datasrc/cache.h>
 #include <datasrc/data_source.h>
 
 #include <dns/name.h>
@@ -217,6 +218,10 @@
     void setDatasrc(DataSrc* ds) { datasrc_ = ds; }
     DataSrc* datasrc() const { return datasrc_; }
 
+    // Query cache.  This is static; the same cache will be
+    // used by all instances of Query.
+    static HotCache cache;
+
 private:
     Status status_;
 

Modified: branches/trac192/src/lib/datasrc/tests/cache_unittest.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/tests/cache_unittest.cc (original)
+++ branches/trac192/src/lib/datasrc/tests/cache_unittest.cc Sat May 29 02:56:27 2010
@@ -57,9 +57,9 @@
 
         cache.setSlots(5);
 
-        cache.cache(a, 30);
-        cache.cache(b, 30);
-        cache.cache(c, 30);
+        cache.cache(a, 0, 30);
+        cache.cache(b, 0, 30);
+        cache.cache(c, 0, 30);
     }
 
     Name test_name;
@@ -79,11 +79,12 @@
     RRsetPtr aaaa(new RRset(Name("foo"), RRClass::IN(), RRType::AAAA(),
                             RRTTL(0)));
     aaaa->addRdata(in::AAAA("001:4f8:3:bb::5"));
-    cache.cache(aaaa, (time_t) 4);
+    cache.cache(aaaa, 0, (time_t) 4);
 
     EXPECT_EQ(4, cache.getCount());
 
-    RRsetPtr r = cache.retrieve(Name("foo"), RRClass::IN(), RRType::AAAA());
+    RRsetPtr r = cache.retrieve(Name("foo"), RRClass::IN(),
+                                RRType::AAAA())->getRRset();
     EXPECT_EQ(aaaa, r);
 }
 
@@ -93,37 +94,39 @@
 
     // Test repeatedly to ensure that all records remain accessible
     // even after being promoted to the top of the cache
-    r = cache.retrieve(test_name, RRClass::IN(), RRType::A());
+    r = cache.retrieve(test_name, RRClass::IN(), RRType::A())->getRRset();
     EXPECT_EQ(test_name, r->getName());
     EXPECT_EQ(RRClass::IN(), r->getClass());
     EXPECT_EQ(RRType::A(), r->getType());
 
-    r = cache.retrieve(test_nsname, RRClass::IN(), RRType::NS());
+    r = cache.retrieve(test_nsname, RRClass::IN(),
+                       RRType::NS())->getRRset();
     EXPECT_EQ(test_nsname, r->getName());
     EXPECT_EQ(RRClass::IN(), r->getClass());
     EXPECT_EQ(RRType::NS(), r->getType());
 
-    r = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT());
+    r = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT())->getRRset();
     EXPECT_EQ(test_ch, r->getName());
     EXPECT_EQ(RRClass::CH(), r->getClass());
     EXPECT_EQ(RRType::TXT(), r->getType());
 
-    r = cache.retrieve(test_nsname, RRClass::IN(), RRType::NS());
+    r = cache.retrieve(test_nsname, RRClass::IN(),
+                       RRType::NS())->getRRset();
     EXPECT_EQ(test_nsname, r->getName());
     EXPECT_EQ(RRClass::IN(), r->getClass());
     EXPECT_EQ(RRType::NS(), r->getType());
 
-    r = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT());
+    r = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT())->getRRset();
     EXPECT_EQ(test_ch, r->getName());
     EXPECT_EQ(RRClass::CH(), r->getClass());
     EXPECT_EQ(RRType::TXT(), r->getType());
 
-    r = cache.retrieve(test_name, RRClass::IN(), RRType::A());
+    r = cache.retrieve(test_name, RRClass::IN(), RRType::A())->getRRset();
     EXPECT_EQ(test_name, r->getName());
     EXPECT_EQ(RRClass::IN(), r->getClass());
     EXPECT_EQ(RRType::A(), r->getType());
 
-    r = cache.retrieve(test_name, RRClass::IN(), RRType::A());
+    r = cache.retrieve(test_name, RRClass::IN(), RRType::A())->getRRset();
     EXPECT_EQ(test_name, r->getName());
     EXPECT_EQ(RRClass::IN(), r->getClass());
     EXPECT_EQ(RRType::A(), r->getType());
@@ -131,31 +134,33 @@
 
 TEST_F(CacheTest, retrieveFail)
 {
-    RRsetPtr r;
-
-    r = cache.retrieve(Name("fake"), RRClass::IN(), RRType::A());
-    EXPECT_FALSE(r);
-
-    r = cache.retrieve(test_name, RRClass::CH(), RRType::A());
-    EXPECT_FALSE(r);
-
-    r = cache.retrieve(test_name, RRClass::IN(), RRType::DNSKEY());
-    EXPECT_FALSE(r);
+    CacheNodePtr c;
+
+    c = cache.retrieve(Name("fake"), RRClass::IN(), RRType::A());
+    EXPECT_FALSE(c);
+
+    c = cache.retrieve(test_name, RRClass::CH(), RRType::A());
+    EXPECT_FALSE(c);
+
+    c = cache.retrieve(test_name, RRClass::IN(), RRType::DNSKEY());
+    EXPECT_FALSE(c);
 }
 
 TEST_F(CacheTest, expire)
 {
+
     // Insert "foo" with a duration of 2 seconds; sleep 3.  The
     // record should not be returned from the cache even though it's
     // at the top of the cache.
     RRsetPtr aaaa(new RRset(Name("foo"), RRClass::IN(), RRType::AAAA(),
                             RRTTL(0)));
     aaaa->addRdata(in::AAAA("001:4f8:3:bb::5"));
-    cache.cache(aaaa, (time_t) 2);
+    cache.cache(aaaa, 0, (time_t) 2);
 
     sleep(3);
-    RRsetPtr r = cache.retrieve(Name("foo"), RRClass::IN(), RRType::AAAA());
-    EXPECT_FALSE(r);
+    CacheNodePtr c = cache.retrieve(Name("foo"), RRClass::IN(),
+                                RRType::AAAA());
+    EXPECT_FALSE(c);
 };
 
 TEST_F(CacheTest, LRU)
@@ -163,38 +168,39 @@
     // Retrieve a record, cache four new records; with five slots
     // in the LRU queue this should remove all the previous records
     // except the last one retreived.
-    RRsetPtr r = cache.retrieve(test_nsname, RRClass::IN(), RRType::NS());
+    RRsetPtr r = cache.retrieve(test_nsname, RRClass::IN(),
+                                RRType::NS())->getRRset();
     EXPECT_EQ(3, cache.getCount());
 
     RRsetPtr one(new RRset(Name("one"), RRClass::IN(), RRType::TXT(),
                            RRTTL(0)));
     one->addRdata(generic::TXT("one"));
-    cache.cache(one, (time_t) 30);
+    cache.cache(one, 0, (time_t) 30);
     EXPECT_EQ(4, cache.getCount());
 
     RRsetPtr two(new RRset(Name("two"), RRClass::IN(), RRType::TXT(),
                            RRTTL(0)));
     two->addRdata(generic::TXT("two"));
-    cache.cache(two, (time_t) 30);
+    cache.cache(two, 0, (time_t) 30);
     EXPECT_EQ(5, cache.getCount());
 
     RRsetPtr three(new RRset(Name("three"), RRClass::IN(), RRType::TXT(),
                            RRTTL(0)));
     three->addRdata(generic::TXT("three"));
-    cache.cache(three, (time_t) 30);
+    cache.cache(three, 0, (time_t) 30);
     EXPECT_EQ(5, cache.getCount());
 
     RRsetPtr four(new RRset(Name("four"), RRClass::IN(), RRType::TXT(),
                            RRTTL(0)));
     four->addRdata(generic::TXT("four"));
-    cache.cache(four, (time_t) 30);
+    cache.cache(four, 0, (time_t) 30);
     EXPECT_EQ(5, cache.getCount());
 
-    r = cache.retrieve(test_name, RRClass::IN(), RRType::A());
-    EXPECT_FALSE(r);
-
-    r = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT());
-    EXPECT_FALSE(r);
-}
-
-}
+    CacheNodePtr c = cache.retrieve(test_name, RRClass::IN(), RRType::A());
+    EXPECT_FALSE(c);
+
+    c = cache.retrieve(test_ch, RRClass::CH(), RRType::TXT());
+    EXPECT_FALSE(c);
+}
+
+}

Modified: branches/trac192/src/lib/datasrc/tests/sqlite3_unittest.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/tests/sqlite3_unittest.cc (original)
+++ branches/trac192/src/lib/datasrc/tests/sqlite3_unittest.cc Sat May 29 02:56:27 2010
@@ -375,7 +375,7 @@
     EXPECT_EQ(DataSrc::SUCCESS, data_source.init(SQLITE_DBFILE_EXAMPLE2));
 
     NameMatch name_match(&data_source, www_name, rrclass);
-    EXPECT_EQ(NULL, name_match.zonename());
+    EXPECT_EQ(NULL, name_match.name());
     EXPECT_EQ(NULL, name_match.datasrc());
 }
 
@@ -413,7 +413,7 @@
 
 TEST_F(Sqlite3DataSourceTest, findClosestEnclosure) {
     NameMatch name_match(&data_source, www_name, rrclass);
-    EXPECT_EQ(zone_name, *name_match.zonename());
+    EXPECT_EQ(zone_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
@@ -422,7 +422,7 @@
     EXPECT_EQ(DataSrc::SUCCESS, data_source.init(SQLITE_DBFILE_EXAMPLE_ROOT));
 
     NameMatch name_match(&data_source, Name("org."), rrclass);
-    EXPECT_EQ(Name("."), *name_match.zonename());
+    EXPECT_EQ(Name("."), *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
@@ -430,19 +430,19 @@
     // The search name exists both in the parent and child zones, but
     // child has a better match.
     NameMatch name_match(&data_source, child_name, rrclass);
-    EXPECT_EQ(child_name, *name_match.zonename());
+    EXPECT_EQ(child_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 TEST_F(Sqlite3DataSourceTest, findClosestEnclosureNoMatch) {
     NameMatch name_match(&data_source, nomatch_name, rrclass);
-    EXPECT_EQ(NULL, name_match.zonename());
+    EXPECT_EQ(NULL, name_match.name());
     EXPECT_EQ(NULL, name_match.datasrc());
 }
 
 TEST_F(Sqlite3DataSourceTest, findClosestClassMismatch) {
     NameMatch name_match(&data_source, www_name, rrclass_notmatch);
-    EXPECT_EQ(NULL, name_match.zonename());
+    EXPECT_EQ(NULL, name_match.name());
     EXPECT_EQ(NULL, name_match.datasrc());
 }
 
@@ -450,7 +450,7 @@
 // the class exactly matches.
 TEST_F(Sqlite3DataSourceTest, findClosestClassAny) {
     NameMatch name_match(&data_source, www_name, RRClass::ANY());
-    EXPECT_EQ(zone_name, *name_match.zonename());
+    EXPECT_EQ(zone_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 

Modified: branches/trac192/src/lib/datasrc/tests/static_unittest.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/tests/static_unittest.cc (original)
+++ branches/trac192/src/lib/datasrc/tests/static_unittest.cc Sat May 29 02:56:27 2010
@@ -197,45 +197,45 @@
 
 TEST_F(StaticDataSourceTest, findClosestEnclosureForVersion) {
     NameMatch name_match(&data_source, version_name, rrclass);
-    EXPECT_EQ(version_name, *name_match.zonename());
+    EXPECT_EQ(version_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 // Class Any query should result in the same answer.
 TEST_F(StaticDataSourceTest, findClosestEnclosureForVersionClassAny) {
     NameMatch name_match(&data_source, version_name, RRClass::ANY());
-    EXPECT_EQ(version_name, *name_match.zonename());
+    EXPECT_EQ(version_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 // If class doesn't match the lookup should fail.
 TEST_F(StaticDataSourceTest, findClosestEnclosureForVersionClassMismatch) {
     NameMatch name_match(&data_source, version_name, RRClass::IN());
-    EXPECT_EQ(NULL, name_match.zonename());
+    EXPECT_EQ(NULL, name_match.name());
     EXPECT_EQ(NULL, name_match.datasrc());
 }
 
 TEST_F(StaticDataSourceTest, findClosestEnclosureForVersionPartial) {
     NameMatch name_match(&data_source, Name("foo").concatenate(version_name), rrclass);
-    EXPECT_EQ(version_name, *name_match.zonename());
+    EXPECT_EQ(version_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 TEST_F(StaticDataSourceTest, findClosestEnclosureForAuthors) {
     NameMatch name_match(&data_source, authors_name, rrclass);
-    EXPECT_EQ(authors_name, *name_match.zonename());
+    EXPECT_EQ(authors_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 TEST_F(StaticDataSourceTest, findClosestEnclosureForAuthorsPartial) {
     NameMatch name_match(&data_source, Name("foo").concatenate(authors_name), rrclass);
-    EXPECT_EQ(authors_name, *name_match.zonename());
+    EXPECT_EQ(authors_name, *name_match.name());
     EXPECT_EQ(&data_source, name_match.datasrc());
 }
 
 TEST_F(StaticDataSourceTest, findClosestEnclosureNoMatch) {
     NameMatch name_match(&data_source, nomatch_name, rrclass);
-    EXPECT_EQ(NULL, name_match.zonename());
+    EXPECT_EQ(NULL, name_match.name());
     EXPECT_EQ(NULL, name_match.datasrc());
 }
 

Modified: branches/trac192/src/lib/dns/rrsetlist.cc
==============================================================================
--- branches/trac192/src/lib/dns/rrsetlist.cc (original)
+++ branches/trac192/src/lib/dns/rrsetlist.cc Sat May 29 02:56:27 2010
@@ -41,6 +41,14 @@
     rrsets_.push_back(rrsetptr);
 }
 
+void
+RRsetList::append(RRsetList& source)
+{
+    BOOST_FOREACH(RRsetPtr rrset, source) {
+        addRRset(rrset);
+    }
+}
+
 RRsetPtr
 RRsetList::findRRset(const RRType& rrtype, const RRClass& rrclass)
 {

Modified: branches/trac192/src/lib/dns/rrsetlist.h
==============================================================================
--- branches/trac192/src/lib/dns/rrsetlist.h (original)
+++ branches/trac192/src/lib/dns/rrsetlist.h Sat May 29 02:56:27 2010
@@ -82,6 +82,7 @@
 public:
     RRsetList() {}
     void addRRset(RRsetPtr new_rrsetptr);
+    void append(RRsetList& source);
     RRsetPtr findRRset(const RRType& rrtype, const RRClass& rrclass);
 
     typedef RRsetListIterator<std::vector<RRsetPtr>::iterator,

Modified: branches/trac192/src/lib/dns/tests/rrsetlist_unittest.cc
==============================================================================
--- branches/trac192/src/lib/dns/tests/rrsetlist_unittest.cc (original)
+++ branches/trac192/src/lib/dns/tests/rrsetlist_unittest.cc Sat May 29 02:56:27 2010
@@ -48,6 +48,7 @@
 const generic::SOA rdata_soa(Name("ns.example.com"), Name("root.example.com"),
                              2010012601, 3600, 300, 3600000, 1200);
 const generic::CNAME rdata_cname("target.example.com");
+const generic::DNAME rdata_dname("dtarget.example.com");
 
 void
 RRsetListTest::setupList(RRsetList& list) {
@@ -84,6 +85,24 @@
     RRsetList list;
     setupList(list);
     EXPECT_EQ(list.size(), 5);
+}
+
+TEST_F(RRsetListTest, append) {
+    RRsetList list1;
+    setupList(list1);
+    RRsetList list2;
+    RRsetPtr dname(new RRset(Name("example.com"), RRClass::IN(),
+                             RRType::DNAME(), example_ttl));
+    dname->addRdata(rdata_dname);
+    list2.addRRset(dname);
+    list1.append(list2);
+    EXPECT_EQ(list2.size(), 1);
+    EXPECT_EQ(list1.size(), 6);
+
+    RRsetPtr rrset = list1.findRRset(RRType::DNAME(), RRClass::IN());
+    EXPECT_EQ(RRType::DNAME(), rrset->getType());
+
+    EXPECT_THROW(list1.append(list2), DuplicateRRset);
 }
 
 TEST_F(RRsetListTest, extraRRset) {




More information about the bind10-changes mailing list