[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