BIND 10 trac2218_2, updated. 38081a3eb213dad9b2233f37e8c8f499a9e50f1a [2218] Implement TreeNodeRRset::getRRsig()
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Sep 18 18:10:57 UTC 2012
The branch, trac2218_2 has been updated
via 38081a3eb213dad9b2233f37e8c8f499a9e50f1a (commit)
via 350fa8a59935fac90f02e86a28d81b4941cc7ee3 (commit)
via 06bf41c4a9c79e450e78f3eecac362dd0b18d06c (commit)
via 467078e47174e5a3d20caa8b1a1c8c0b35b0876f (commit)
via faa94e73318b57601aa9bf857387863c9be72a6b (commit)
via f8b99e43fcc928eccd9b30fd187d91e92782ee02 (commit)
via 4c9e89ec998fb375031f14929775074aa1d9c903 (commit)
from e7ecb231083afee21757b37c4128fd222a6e93a5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 38081a3eb213dad9b2233f37e8c8f499a9e50f1a
Author: Mukund Sivaraman <muks at isc.org>
Date: Tue Sep 18 23:37:48 2012 +0530
[2218] Implement TreeNodeRRset::getRRsig()
commit 350fa8a59935fac90f02e86a28d81b4941cc7ee3
Author: Mukund Sivaraman <muks at isc.org>
Date: Mon Sep 17 00:02:52 2012 +0530
[2218] Add facility to setup a fake NSEC3Calculate function for use in tests
commit 06bf41c4a9c79e450e78f3eecac362dd0b18d06c
Author: Mukund Sivaraman <muks at isc.org>
Date: Tue Sep 18 23:18:24 2012 +0530
[2218] Fix ZoneChain type name (after rebasing)
commit 467078e47174e5a3d20caa8b1a1c8c0b35b0876f
Author: Mukund Sivaraman <muks at isc.org>
Date: Fri Sep 14 09:59:40 2012 +0530
[2218] Fix addZoneDataNSEC3() to populate NSEC3Data inside ZoneData
commit faa94e73318b57601aa9bf857387863c9be72a6b
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Sep 12 23:17:54 2012 +0530
[2218] Fix condition in DomainTree::getLargestNode()
commit f8b99e43fcc928eccd9b30fd187d91e92782ee02
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Sep 12 23:14:04 2012 +0530
[2218] Add an initial InMemoryZoneFinder::findNSEC3() implementation
commit 4c9e89ec998fb375031f14929775074aa1d9c903
Author: Mukund Sivaraman <muks at isc.org>
Date: Wed Sep 12 23:13:12 2012 +0530
[2218] Add DomainTree::getLargestNode()
-----------------------------------------------------------------------
Summary of changes:
src/lib/datasrc/memory/domaintree.h | 23 +++
.../memory/tests/treenode_rrset_unittest.cc | 1 -
.../datasrc/memory/tests/zone_finder_unittest.cc | 157 +++++++++++---------
src/lib/datasrc/memory/treenode_rrset.cc | 26 ++--
src/lib/datasrc/memory/zone_finder.cc | 148 +++++++++++++++++-
src/lib/datasrc/memory/zone_finder.h | 17 ++-
6 files changed, 286 insertions(+), 86 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/memory/domaintree.h b/src/lib/datasrc/memory/domaintree.h
index b29f10f..4c4de93 100644
--- a/src/lib/datasrc/memory/domaintree.h
+++ b/src/lib/datasrc/memory/domaintree.h
@@ -1214,6 +1214,14 @@ public:
}
//@}
+ /// \brief return the largest node (right-most last node) in the
+ /// tree.
+ ///
+ /// \return A \c DomainTreeNode that is largest in the tree. If the
+ /// tree has no nodes, NULL will be returned.
+ const DomainTreeNode<T>*
+ getLargestNode() const;
+
/// \brief return the next bigger node in DNSSEC order from a given node
/// chain.
///
@@ -1710,6 +1718,21 @@ DomainTree<T>::previousNode(DomainTreeNodeChain<T>& node_path) const {
}
template <typename T>
+const DomainTreeNode<T>*
+DomainTree<T>::getLargestNode() const {
+ const DomainTreeNode<T>* node = root_.get();
+ if (node == NULL) {
+ return (NULL);
+ }
+
+ while (node->getRight() != NULL) {
+ node = node->getRight();
+ }
+
+ return (node);
+}
+
+template <typename T>
typename DomainTree<T>::Result
DomainTree<T>::insert(util::MemorySegment& mem_sgmt,
const isc::dns::Name& target_name,
diff --git a/src/lib/datasrc/memory/tests/treenode_rrset_unittest.cc b/src/lib/datasrc/memory/tests/treenode_rrset_unittest.cc
index 182cca6..eea62e6 100644
--- a/src/lib/datasrc/memory/tests/treenode_rrset_unittest.cc
+++ b/src/lib/datasrc/memory/tests/treenode_rrset_unittest.cc
@@ -578,7 +578,6 @@ TEST_F(TreeNodeRRsetTest, unexpectedMethods) {
EXPECT_THROW(rrset.setName(Name("example")), isc::Unexpected);
EXPECT_THROW(rrset.addRdata(createRdata(RRType::A(), rrclass_, "0.0.0.0")),
isc::Unexpected);
- EXPECT_THROW(rrset.getRRsig(), isc::Unexpected);
RdataPtr sig_rdata = createRdata(
RRType::RRSIG(), rrclass_,
"A 5 2 3600 20120814220826 20120715220826 5300 example.com. FAKE");
diff --git a/src/lib/datasrc/memory/tests/zone_finder_unittest.cc b/src/lib/datasrc/memory/tests/zone_finder_unittest.cc
index 94ebe5e..895608c 100644
--- a/src/lib/datasrc/memory/tests/zone_finder_unittest.cc
+++ b/src/lib/datasrc/memory/tests/zone_finder_unittest.cc
@@ -61,59 +61,57 @@ const char* const xyw_hash = "2vptu5timamqttgl4luu9kg21e0aor3s";
// For zzz.example.org.
const char* const zzz_hash = "R53BQ7CC2UVMUBFU5OCMM6PERS9TK9EN";
-// A simple faked NSEC3 hash calculator with a dedicated creator for it.
-//
-// This is used in some NSEC3-related tests below.
-// Also see NOTE at inclusion of "../../tests/faked_nsec3.h"
-class TestNSEC3HashCreator : public NSEC3HashCreator {
- class TestNSEC3Hash : public NSEC3Hash {
- private:
- typedef map<Name, string> NSEC3HashMap;
- typedef NSEC3HashMap::value_type NSEC3HashPair;
- NSEC3HashMap map_;
- public:
- TestNSEC3Hash() {
- // Build pre-defined hash
- map_[Name("example.org")] = apex_hash;
- map_[Name("www.example.org")] = "2S9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
- map_[Name("xxx.example.org")] = "Q09MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
- map_[Name("yyy.example.org")] = "0A9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
- map_[Name("x.y.w.example.org")] =
- "2VPTU5TIMAMQTTGL4LUU9KG21E0AOR3S";
- map_[Name("y.w.example.org")] = "K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
- map_[Name("w.example.org")] = w_hash;
- map_[Name("zzz.example.org")] = zzz_hash;
- map_[Name("smallest.example.org")] =
- "00000000000000000000000000000000";
- map_[Name("largest.example.org")] =
- "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU";
- }
- virtual string calculate(const Name& name) const {
- const NSEC3HashMap::const_iterator found = map_.find(name);
- if (found != map_.end()) {
- return (found->second);
- }
- isc_throw(isc::Unexpected, "unexpected name for NSEC3 test: "
- << name);
- }
- virtual bool match(const generic::NSEC3PARAM&) const {
- return (true);
- }
- virtual bool match(const generic::NSEC3&) const {
- return (true);
- }
- };
+typedef map<Name, string> NSEC3HashMap;
+typedef NSEC3HashMap::value_type NSEC3HashPair;
+NSEC3HashMap nsec3_hash_map;
+
+// A faked NSEC3 hash calculator for convenience. Tests that need to use
+// the faked hashed values should call setFakeNSEC3Calculate() on the
+// MyZoneFinder object at the beginning of the test (at least before
+// adding any NSEC3/NSEC3PARAM RR).
+std::string
+fakeNSEC3Calculate(const Name& name,
+ const uint16_t,
+ const uint8_t*,
+ size_t) {
+ const NSEC3HashMap::const_iterator found = nsec3_hash_map.find(name);
+ if (found != nsec3_hash_map.end()) {
+ return (found->second);
+ }
+ isc_throw(isc::Unexpected,
+ "unexpected name for NSEC3 test: " << name);
+}
+
+class MyZoneFinder : public memory::InMemoryZoneFinder {
+private:
public:
- virtual NSEC3Hash* create(const generic::NSEC3PARAM&) const {
- return (new TestNSEC3Hash);
+ MyZoneFinder(const ZoneData& zone_data,
+ const isc::dns::RRClass& rrclass) :
+ memory::InMemoryZoneFinder(zone_data, rrclass)
+ {
+ // Build pre-defined hash
+ nsec3_hash_map.clear();
+ nsec3_hash_map[Name("example.org")] = apex_hash;
+ nsec3_hash_map[Name("www.example.org")] = "2S9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
+ nsec3_hash_map[Name("xxx.example.org")] = "Q09MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
+ nsec3_hash_map[Name("yyy.example.org")] = "0A9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM";
+ nsec3_hash_map[Name("x.y.w.example.org")] =
+ "2VPTU5TIMAMQTTGL4LUU9KG21E0AOR3S";
+ nsec3_hash_map[Name("y.w.example.org")] = "K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H";
+ nsec3_hash_map[Name("w.example.org")] = w_hash;
+ nsec3_hash_map[Name("zzz.example.org")] = zzz_hash;
+ nsec3_hash_map[Name("smallest.example.org")] =
+ "00000000000000000000000000000000";
+ nsec3_hash_map[Name("largest.example.org")] =
+ "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU";
}
- virtual NSEC3Hash* create(const generic::NSEC3&) const {
- return (new TestNSEC3Hash);
+
+ void setFakeNSEC3Calculate() {
+ nsec3_calculate_ = fakeNSEC3Calculate;
}
};
-
/// \brief expensive rrset converter
///
/// converts any specialized rrset (which may not have implemented some
@@ -259,14 +257,45 @@ public:
void addZoneDataNSEC3(const ConstRRsetPtr rrset) {
assert(rrset->getType() == RRType::NSEC3());
- const Rdata* rdata = &rrset->getRdataIterator()->getCurrent();
- const generic::NSEC3* nsec3_rdata =
- dynamic_cast<const generic::NSEC3*>(rdata);
- NSEC3Data* nsec3_data = NSEC3Data::create(mem_sgmt_, *nsec3_rdata);
- // in case we happen to be replacing, destroy old
- NSEC3Data* old_data = zone_data_->setNSEC3Data(nsec3_data);
- if (old_data != NULL) {
- NSEC3Data::destroy(mem_sgmt_, old_data, rrset->getClass());
+ const generic::NSEC3& nsec3_rdata =
+ dynamic_cast<const generic::NSEC3&>(
+ rrset->getRdataIterator()->getCurrent());
+
+ NSEC3Data* nsec3_data = zone_data_->getNSEC3Data();
+ if (nsec3_data == NULL) {
+ nsec3_data = NSEC3Data::create(mem_sgmt_, nsec3_rdata);
+ zone_data_->setNSEC3Data(nsec3_data);
+ } else {
+ size_t salt_len = nsec3_data->getSaltLen();
+ const uint8_t* salt_data = nsec3_data->getSaltData();
+ const vector<uint8_t>& salt_data_2 = nsec3_rdata.getSalt();
+
+ if ((nsec3_rdata.getHashalg() != nsec3_data->hashalg) ||
+ (nsec3_rdata.getIterations() != nsec3_data->iterations) ||
+ (salt_data_2.size() != salt_len) ||
+ (std::memcmp(&salt_data_2[0], salt_data, salt_len) != 0)) {
+ isc_throw(isc::Unexpected,
+ "NSEC3 with inconsistent parameters: " <<
+ rrset->toText());
+ }
+ }
+
+ string fst_label = rrset->getName().split(0, 1).toText(true);
+ transform(fst_label.begin(), fst_label.end(), fst_label.begin(),
+ ::toupper);
+
+ ZoneNode *node;
+ nsec3_data->insertName(mem_sgmt_, Name(fst_label), &node);
+
+ RdataEncoder encoder;
+
+ // We assume that rrsig has already been checked to match rrset
+ // by the caller.
+ RdataSet *set = RdataSet::create(mem_sgmt_, encoder,
+ rrset, ConstRRsetPtr());
+ RdataSet *old_set = node->setData(set);
+ if (old_set != NULL) {
+ RdataSet::destroy(mem_sgmt_, class_, old_set);
}
zone_data_->setSigned(true);
}
@@ -320,7 +349,7 @@ public:
// The zone finder to torture by tests
MemorySegmentTest mem_sgmt_;
memory::ZoneData* zone_data_;
- memory::InMemoryZoneFinder zone_finder_;
+ MyZoneFinder zone_finder_;
isc::datasrc::memory::RdataEncoder encoder_;
// Placeholder for storing RRsets to be checked with rrsetsCheck()
@@ -369,12 +398,6 @@ public:
RRsetPtr rr_ns_nsec_;
RRsetPtr rr_wild_nsec_;
- // A faked NSEC3 hash calculator for convenience.
- // Tests that need to use the faked hashed values should call
- // setNSEC3HashCreator() with a pointer to this variable at the beginning
- // of the test (at least before adding any NSEC3/NSEC3PARAM RR).
- TestNSEC3HashCreator nsec3_hash_creator_;
-
/**
* \brief Test one find query to the zone finder.
*
@@ -1427,10 +1450,9 @@ TEST_F(InMemoryZoneFinderTest, cancelWildcardNSEC) {
}
-// DISABLED: nsec3 will be re-added in #2118
-TEST_F(InMemoryZoneFinderTest, DISABLED_findNSEC3) {
+TEST_F(InMemoryZoneFinderTest, findNSEC3) {
// Set up the faked hash calculator.
- setNSEC3HashCreator(&nsec3_hash_creator_);
+ zone_finder_.setFakeNSEC3Calculate();
// Add a few NSEC3 records:
// apex (example.org.): hash=0P..
@@ -1453,10 +1475,9 @@ TEST_F(InMemoryZoneFinderTest, DISABLED_findNSEC3) {
performNSEC3Test(zone_finder_);
}
-// DISABLED: NSEC3 will be re-added in #2218
-TEST_F(InMemoryZoneFinderTest, DISABLED_findNSEC3ForBadZone) {
+TEST_F(InMemoryZoneFinderTest, findNSEC3ForBadZone) {
// Set up the faked hash calculator.
- setNSEC3HashCreator(&nsec3_hash_creator_);
+ zone_finder_.setFakeNSEC3Calculate();
// If the zone has nothing about NSEC3 (neither NSEC3 or NSEC3PARAM),
// findNSEC3() should be rejected.
diff --git a/src/lib/datasrc/memory/treenode_rrset.cc b/src/lib/datasrc/memory/treenode_rrset.cc
index e1b2273..b3f842d 100644
--- a/src/lib/datasrc/memory/treenode_rrset.cc
+++ b/src/lib/datasrc/memory/treenode_rrset.cc
@@ -97,17 +97,7 @@ TreeNodeRRset::toText() const {
}
// Dump any RRSIGs
- tmp_rrset.reset();
- for (RdataIteratorPtr rit = getSigRdataIterator();
- !rit->isLast();
- rit->next())
- {
- if (!tmp_rrset) {
- tmp_rrset = RRsetPtr(new RRset(getName(), rrclass_,
- RRType::RRSIG(), getTTL()));
- }
- tmp_rrset->addRdata(rit->getCurrent());
- }
+ tmp_rrset = getRRsig();
if (tmp_rrset) {
ret += tmp_rrset->toText();
}
@@ -288,7 +278,19 @@ TreeNodeRRset::getSigRdataIterator() const {
RRsetPtr
TreeNodeRRset::getRRsig() const {
- isc_throw(Unexpected, "unexpected method called on TreeNodeRRset");
+ RRsetPtr tmp_rrset;
+ for (RdataIteratorPtr rit = getSigRdataIterator();
+ !rit->isLast();
+ rit->next())
+ {
+ if (!tmp_rrset) {
+ tmp_rrset = RRsetPtr(new RRset(getName(), rrclass_,
+ RRType::RRSIG(), getTTL()));
+ }
+ tmp_rrset->addRdata(rit->getCurrent());
+ }
+
+ return (tmp_rrset);
}
void
diff --git a/src/lib/datasrc/memory/zone_finder.cc b/src/lib/datasrc/memory/zone_finder.cc
index 75d3187..59987cf 100644
--- a/src/lib/datasrc/memory/zone_finder.cc
+++ b/src/lib/datasrc/memory/zone_finder.cc
@@ -23,11 +23,18 @@
#include <dns/rrset.h>
#include <dns/rrtype.h>
+#include <util/buffer.h>
+#include <util/encode/base32hex.h>
+#include <util/hash/sha1.h>
+
#include <datasrc/logger.h>
using namespace isc::dns;
using namespace isc::datasrc::memory;
using namespace isc::datasrc;
+using namespace isc::util;
+using namespace isc::util::encode;
+using namespace isc::util::hash;
namespace isc {
namespace datasrc {
@@ -446,6 +453,45 @@ FindNodeResult findNode(const ZoneData& zone_data,
} // end anonymous namespace
+inline void
+iterateSHA1(SHA1Context* ctx, const uint8_t* input, size_t inlength,
+ const uint8_t* salt, size_t saltlen,
+ uint8_t output[SHA1_HASHSIZE])
+{
+ SHA1Reset(ctx);
+ SHA1Input(ctx, input, inlength);
+ SHA1Input(ctx, salt, saltlen); // this works whether saltlen == or > 0
+ SHA1Result(ctx, output);
+}
+
+std::string
+InMemoryZoneFinderNSEC3Calculate(const Name& name,
+ const uint16_t iterations,
+ const uint8_t* salt,
+ size_t salt_len) {
+ // We first need to normalize the name by converting all upper case
+ // characters in the labels to lower ones.
+ OutputBuffer obuf(Name::MAX_WIRE);
+ Name name_copy(name);
+ name_copy.downcase();
+ name_copy.toWire(obuf);
+
+ const uint8_t* const salt_buf = (salt_len > 0) ? salt : NULL;
+ std::vector<uint8_t> digest(SHA1_HASHSIZE);
+ uint8_t* const digest_buf = &digest[0];
+
+ SHA1Context sha1_ctx;
+ iterateSHA1(&sha1_ctx, static_cast<const uint8_t*>(obuf.getData()),
+ obuf.getLength(), salt_buf, salt_len, digest_buf);
+ for (unsigned int n = 0; n < iterations; ++n) {
+ iterateSHA1(&sha1_ctx, digest_buf, SHA1_HASHSIZE,
+ salt_buf, salt_len,
+ digest_buf);
+ }
+
+ return (encodeBase32Hex(digest));
+}
+
// Specialization of the ZoneFinder::Context for the in-memory finder.
class InMemoryZoneFinder::Context : public ZoneFinder::Context {
public:
@@ -590,9 +636,105 @@ InMemoryZoneFinder::find_internal(const isc::dns::Name& name,
isc::datasrc::ZoneFinder::FindNSEC3Result
InMemoryZoneFinder::findNSEC3(const isc::dns::Name& name, bool recursive) {
- (void)name;
- (void)recursive;
- isc_throw(isc::NotImplemented, "not completed yet! please implement me");
+ LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FINDNSEC3).arg(name).
+ arg(recursive ? "recursive" : "non-recursive");
+
+ if (!zone_data_.isNSEC3Signed()) {
+ isc_throw(DataSourceError,
+ "findNSEC3 attempt for non NSEC3 signed zone: " <<
+ getOrigin() << "/" << getClass());
+ }
+
+ const NameComparisonResult cmp_result = name.compare(getOrigin());
+ if (cmp_result.getRelation() != NameComparisonResult::EQUAL &&
+ cmp_result.getRelation() != NameComparisonResult::SUBDOMAIN) {
+ isc_throw(OutOfZone, "findNSEC3 attempt for out-of-zone name: "
+ << name << ", zone: " << getOrigin() << "/"
+ << getClass());
+ }
+
+ // Convenient shortcuts
+ const unsigned int olabels = getOrigin().getLabelCount();
+ const unsigned int qlabels = name.getLabelCount();
+ const NSEC3Data* nsec3_data = zone_data_.getNSEC3Data();
+
+ const ZoneNode* covering_node(NULL); // placeholder of the next closer proof
+ // Examine all names from the query name to the origin name, stripping
+ // the deepest label one by one, until we find a name that has a matching
+ // NSEC3 hash.
+ for (unsigned int labels = qlabels; labels >= olabels; --labels) {
+ const std::string hlabel =
+ (nsec3_calculate_)((labels == qlabels ?
+ name : name.split(qlabels - labels, labels)),
+ nsec3_data->iterations,
+ nsec3_data->getSaltData(),
+ nsec3_data->getSaltLen());
+
+ LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FINDNSEC3_TRYHASH).
+ arg(name).arg(labels).arg(hlabel);
+
+ const ZoneTree& tree = nsec3_data->getNSEC3Tree();
+
+ ZoneNode* node(NULL);
+ ZoneChain chain;
+
+ ZoneTree::Result result = tree.find(Name(hlabel), &node, chain);
+
+ if (result == ZoneTree::EXACTMATCH) {
+ // We found an exact match.
+ RdataSet* set = node->getData();
+ ConstRRsetPtr closest = createTreeNodeRRset(node,
+ set,
+ getClass());
+ ConstRRsetPtr next = createTreeNodeRRset(covering_node,
+ covering_node->getData(),
+ getClass());
+
+ LOG_DEBUG(logger, DBG_TRACE_BASIC,
+ DATASRC_MEM_FINDNSEC3_MATCH).arg(name).arg(labels).
+ arg(*closest);
+
+ return (FindNSEC3Result(true, labels, closest, next));
+ } else {
+ const NameComparisonResult& cmp = chain.getLastComparisonResult();
+ assert(cmp.getOrder() != 0);
+
+ // find() finished in between these two:
+ const ZoneNode* previous_node = tree.previousNode(chain);
+ const ZoneNode* next_node = tree.nextNode(chain);
+
+ // If the given hash is larger than the largest stored hash or
+ // the first label doesn't match the target, identify the "previous"
+ // hash value and remember it as the candidate next closer proof.
+ if (((cmp.getOrder() < 0) && (previous_node == NULL)) ||
+ ((cmp.getOrder() > 0) && (next_node == NULL))) {
+ covering_node = tree.getLargestNode();
+ } else {
+ // Otherwise, H(found_entry-1) < given_hash < H(found_entry).
+ // The covering proof is the first one (and it's valid
+ // because found is neither begin nor end)
+ covering_node = previous_node;
+ }
+
+ if (!recursive) { // in non recursive mode, we are done.
+ ConstRRsetPtr closest =
+ createTreeNodeRRset(covering_node,
+ covering_node->getData(),
+ getClass());
+
+ LOG_DEBUG(logger, DBG_TRACE_BASIC,
+ DATASRC_MEM_FINDNSEC3_COVER).
+ arg(name).arg(*closest);
+
+ return (FindNSEC3Result(false, labels,
+ closest, ConstRRsetPtr()));
+ }
+ }
+ }
+
+ isc_throw(DataSourceError, "recursive findNSEC3 mode didn't stop, likely "
+ "a broken NSEC3 zone: " << getOrigin() << "/"
+ << getClass());
}
} // namespace memory
diff --git a/src/lib/datasrc/memory/zone_finder.h b/src/lib/datasrc/memory/zone_finder.h
index 8f2c687..a42f6f8 100644
--- a/src/lib/datasrc/memory/zone_finder.h
+++ b/src/lib/datasrc/memory/zone_finder.h
@@ -48,6 +48,12 @@ public:
const ZoneNode* const found_node;
};
+std::string
+InMemoryZoneFinderNSEC3Calculate(const isc::dns::Name& name,
+ const uint16_t iterations,
+ const uint8_t* salt,
+ size_t salt_len);
+
/// A derived zone finder class intended to be used with the memory data
/// source, using ZoneData for its contents.
class InMemoryZoneFinder : boost::noncopyable, public ZoneFinder {
@@ -66,7 +72,8 @@ public:
InMemoryZoneFinder(const ZoneData& zone_data,
const isc::dns::RRClass& rrclass) :
zone_data_(zone_data),
- rrclass_(rrclass)
+ rrclass_(rrclass),
+ nsec3_calculate_(InMemoryZoneFinderNSEC3Calculate)
{}
/// \brief Find an RRset in the datasource
@@ -101,7 +108,6 @@ public:
return rrclass_;
}
-
private:
/// \brief In-memory version of finder context.
///
@@ -119,6 +125,13 @@ private:
const ZoneData& zone_data_;
const isc::dns::RRClass& rrclass_;
+
+protected:
+ typedef std::string (NSEC3CalculateFn) (const isc::dns::Name& name,
+ const uint16_t iterations,
+ const uint8_t* salt,
+ size_t salt_len);
+ NSEC3CalculateFn* nsec3_calculate_;
};
} // namespace memory
More information about the bind10-changes
mailing list