[svn] commit: r1981 - in /branches/trac192/src/lib/datasrc: cache.cc cache.h data_source.cc data_source.h tests/datasrc_unittest.cc tests/test_datasrc.cc tests/testdata/q_example_dnskey

BIND 10 source code commits bind10-changes at lists.isc.org
Sat May 29 18:09:42 UTC 2010


Author: each
Date: Sat May 29 18:09:42 2010
New Revision: 1981

Log:
checkpoint:
 - discovered a problem when querying repeatedly for DNSKEY: the
   REFERRAL flag was causing it to be cached incorrectly.  fixed this
   and added a unit test.
 - added a std::map to the hotcache to speed up record retrieval

Added:
    branches/trac192/src/lib/datasrc/tests/testdata/q_example_dnskey
Modified:
    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/tests/datasrc_unittest.cc
    branches/trac192/src/lib/datasrc/tests/test_datasrc.cc

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 18:09:42 2010
@@ -67,6 +67,9 @@
     return (now < expiry_);
 }
 
+// QTuple constructor
+QTuple::QTuple(Name n, RRClass c, RRType t) : qname(n), qclass(c), qtype(t) {} 
+
 // HotCache destructor
 HotCache::~HotCache() {
     CacheNodePtr node;
@@ -84,14 +87,7 @@
 
 CacheNodePtr
 HotCache::retrieve(Name n, RRClass c, RRType t) {
-    CacheNodePtr node;
-
-    for (node = head; node != CacheNodePtr(); node = node->next) {
-        if (node->qtype == t && node->qclass == c && node->qname == n) {
-            break;
-        }
-    }
-
+    CacheNodePtr node = map_[QTuple(n, c, t)];
     if (! node) {
         return (CacheNodePtr());
     }
@@ -117,6 +113,7 @@
         tail = node;
     }
 
+    map_[QTuple(node->qname, node->qclass, node->qtype)] = node;
     ++count_;
 
     while (slots_ != 0 && count_ > slots_ && tail) {
@@ -222,6 +219,7 @@
         node->prev->next = node->next;
     }
 
+    map_.erase(QTuple(node->qname, node->qclass, node->qtype));
     --count_;
 }
 

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 18:09:42 2010
@@ -18,6 +18,7 @@
 #define __CACHE_H
 
 #include <time.h>
+#include <map>
 
 #include <boost/shared_ptr.hpp>
 
@@ -80,6 +81,21 @@
     time_t expiry_;
 };
 
+class QTuple {
+public:
+    QTuple(isc::dns::Name n, isc::dns::RRClass c, isc::dns::RRType t);
+    inline bool operator <(const QTuple& rhs) const {
+        return (qclass < rhs.qclass ||
+                (qclass == rhs.qclass &&
+                 (qtype < rhs.qtype ||
+                  (qtype == rhs.qtype && (qname < rhs.qname)))));
+    }
+
+    isc::dns::Name qname;
+    isc::dns::RRClass qclass;
+    isc::dns::RRType qtype;
+};
+
 class HotCache {
 public:
     // Constructor
@@ -118,6 +134,8 @@
     int slots_;
     int count_;
 
+    std::map<QTuple, CacheNodePtr> map_;
+
     // Move a node to the front of the LRU queue.
     void promote(CacheNodePtr node);
     void remove(CacheNodePtr node);
@@ -130,7 +148,6 @@
 }
 }
 
-
 #endif
 
 // Local Variables: 

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 18:09:42 2010
@@ -176,6 +176,7 @@
         if (count == 1) {
             task.flags = flags;
             target.append(rrsets);
+
             return (DataSrc::SUCCESS);
         }
         break;
@@ -361,17 +362,17 @@
             BOOST_FOREACH(RRsetPtr rr, target) {
                 cache.cache(rr, task.flags);
             }
-        } else if (task.flags == 0) {
+        } 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 if ((task.flags & DataSrc::DATA_NOT_FOUND) == 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 {

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 18:09:42 2010
@@ -90,12 +90,15 @@
     // NAME_NOT_FOUND: The node does not exist in the data source.
     // TYPE_NOT_FOUND: The node does not contain the requested RRType
     // NO_SUCH_ZONE:   The zone does not exist in this data source.
+    //
+    // NOT_FOUND:      A combination of the last three, for coding convenience
     enum QueryResponseFlags {
         REFERRAL = 0x01,
         CNAME_FOUND = 0x02,
         NAME_NOT_FOUND = 0x04,
         TYPE_NOT_FOUND = 0x08,
-        NO_SUCH_ZONE = 0x10
+        NO_SUCH_ZONE = 0x10,
+        DATA_NOT_FOUND = (NAME_NOT_FOUND|TYPE_NOT_FOUND|NO_SUCH_ZONE)
     };
 
     // 'High-level' methods.  These will be implemented by the

Modified: branches/trac192/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac192/src/lib/datasrc/tests/datasrc_unittest.cc Sat May 29 18:09:42 2010
@@ -213,6 +213,31 @@
     EXPECT_TRUE(it->isLast());
 }
 
+TEST_F(DataSrcTest, DNSKEYQuery) {
+    readAndProcessQuery("q_example_dnskey");
+    headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
+
+    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetPtr rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::DNSKEY(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+}
+
+// Repeat the previous query to check that cache is working correctly.
+// We query at a zone cut to ensure the REFERRAL flag doesn't cause
+// incorrect behavior.
+TEST_F(DataSrcTest, RepeatQuery) {
+    readAndProcessQuery("q_example_dnskey");
+    headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
+
+    RRsetIterator rit = msg.beginSection(Section::ANSWER());
+    RRsetPtr rrset = *rit;
+    EXPECT_EQ(Name("example.com"), rrset->getName());
+    EXPECT_EQ(RRType::DNSKEY(), rrset->getType());
+    EXPECT_EQ(RRClass::IN(), rrset->getClass());
+}
+
 TEST_F(DataSrcTest, NxRRset) {
     readAndProcessQuery("q_example_ptr");
 
@@ -227,7 +252,6 @@
 TEST_F(DataSrcTest, Nxdomain) {
     readAndProcessQuery("q_glork");
 
-    headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 6, 0);
 
     RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
     RRsetPtr rrset = *rit;

Modified: branches/trac192/src/lib/datasrc/tests/test_datasrc.cc
==============================================================================
--- branches/trac192/src/lib/datasrc/tests/test_datasrc.cc (original)
+++ branches/trac192/src/lib/datasrc/tests/test_datasrc.cc Sat May 29 18:09:42 2010
@@ -66,6 +66,7 @@
 RRsetPtr example_ns;
 RRsetPtr example_soa;
 RRsetPtr example_nsec;
+RRsetPtr example_dnskey;
 RRsetPtr www_a;
 RRsetPtr www_nsec;
 RRsetPtr foo_cname;
@@ -148,6 +149,17 @@
     rrsig->addRdata(generic::RRSIG("NSEC 5 2 7200 20100322084538 20100220084538 33495 example.com. KxuVaPPKNPJzr/q+cJPiNlkHVTQK0LVsgTbSqruXQc25lAd0wn5oKUtxL1bEAchHkfA8eLzcYCj2ZqqAv9OJubw53mfskTad7UHs4Uj2RTrIsNGMCiZGgOpvNb9JcWpQtoyXVT1uNse+Qsbeir0eyeYIufUynFU041jtNrlJMio="));
     example_nsec->addRRsig(rrsig);
 
+    example_dnskey = RRsetPtr(new RRset(example, RRClass::IN(),
+                                      RRType::DNSKEY(), RRTTL(3600)));
+    example_dnskey->addRdata(generic::DNSKEY("257 3 5 AwEAAe5WFbxdCPq2jZrZhlMj7oJdff3W7syJtbvzg62tRx0gkoCDoBI9DPjlOQG0UAbj+xUV4HQZJStJaZ+fHU5AwVNT+bBZdtV+NujSikhdTHb4FYLg2b3Cx9NyJvAVukHp/91HnWuG4T36CzAFrfPwsHIrBz9BsaIQ21VRkcmj7DswfI/iDGd8j6bqiODyNZYQ+ZrLmF0KIJ2yPN3iO6Zq23TaOrVTjB7d1a/h31ODfiHAxFHrkY3t3D5JR9Nsl/7fdRmSznwtcSDgLXBoFEYmw6p86AcvRyoYNcL1SXjaKVLG5jyU3UR+LcGZT5t/0xGfoIK/aKwENrsjcKZZj660b1M="));
+    example_dnskey->addRdata(generic::DNSKEY("256 3 5 AwEAAcOUBllYc1hf7ND9uDy+Yz1BF3sI0m4qNGV7WcTD0WEiuV7IjXgHE36fCmS9QsUxSSOVo1I/FMxI2PJVqTYHkXFBS7AzLGsQYMU7UjBZSotBJ6Imt5pXMu+lEDNy8TOUzG3xm7g0qcbWYF6qCEfvZoBtAqi5Rk7Mlrqs8agxYyMx"));
+
+    rrsig = RRsetPtr(new RRset(example, RRClass::IN(), RRType::RRSIG(),
+                               RRTTL(3600)));
+    rrsig->addRdata(generic::RRSIG("DNSKEY 5 2 3600 20100416210049 20100317210049 4456 example.com. 37FC0rcwOZVarTMjft0BMbvv8hbJU7OHNsvO7R1q6OgsLTj7QGMX3sC42JGbwUrYI/OwnZblNcv1eim0g0jX5k+sVr2OJsEubngRjVqLo54qV8rBC14tLk9PGKxxjQG0IBJU866uHxzXYBO2a1r2g93/qyTtrT7iPLu/2Ce1WRKMBPK0yf4nW2usFU/PXesXFWpZ7HLGZL73/NWv8wcezBDuU0B2PlHLjSu7k6poq6JWDC02o5SYnEBwsJ5Chi+3/NZmzKTiNP7g0H4t6QhunkEXxL3z0617mwwQt00ypXsNunnPy4Ub5Kllk1SKJl8ZkEDKkJtSvuXJhcAZsLyMQw=="));
+    rrsig->addRdata(generic::RRSIG("DNSKEY 5 2 3600 20100416210049 20100317210049 33495 example.com. h3OM5r3roBsgnEQk9fcjTg5L7p3yDptDpVzDN/lgjqpaWxtlz5LsulBH3YzwYyXzT7pG7L0/qT6dcuRECc/rniECviWvmJMJZzEAMry0Of/pk/8ekuGTxABpqwAoCwM5as30sc0cfMJTS7umpJVDA4lRB2zoKGefWnJ3+pREDiY="));
+    example_dnskey->addRRsig(rrsig);
+
     // sql1.example.com
     sql1_ns = RRsetPtr(new RRset(sql1, RRClass::IN(),
                                  RRType::NS(), RRTTL(3600)));
@@ -550,6 +562,8 @@
                 target.addRRset(example_soa);
             } else if (rdtype == RRType::NSEC()) {
                 target.addRRset(example_nsec);
+            } else if (rdtype == RRType::DNSKEY()) {
+                target.addRRset(example_dnskey);
             } else {
                 flags |= TYPE_NOT_FOUND;
             }




More information about the bind10-changes mailing list