From: JINMEI Tatuya Date: Wed, 22 Aug 2012 01:40:58 +0000 (-0700) Subject: [2107] added NSEC3Data X-Git-Tag: trac2351_base~109^2~1^2~30 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=042e6179638fccfcc7ceaebbaf89ad830bfa3c56;p=thirdparty%2Fkea.git [2107] added NSEC3Data --- diff --git a/src/lib/datasrc/memory/tests/zone_data_unittest.cc b/src/lib/datasrc/memory/tests/zone_data_unittest.cc index 9a5d19eed1..a6bbff8d7f 100644 --- a/src/lib/datasrc/memory/tests/zone_data_unittest.cc +++ b/src/lib/datasrc/memory/tests/zone_data_unittest.cc @@ -14,6 +14,8 @@ #include "memory_segment_test.h" +#include + #include #include @@ -31,6 +33,7 @@ #include // for bad_alloc using namespace isc::dns; +using namespace isc::dns::rdata; using namespace isc::datasrc::memory; using namespace isc::datasrc::memory::test; using namespace isc::testutils; @@ -83,9 +86,9 @@ TEST_F(ZoneDataTest, addRdataSets) { ConstRRsetPtr a_rrset_ = textToRRset("www.example.com. 3600 IN A 192.0.2.1"); - ZoneData::ZoneNode* node = NULL; + ZoneNode* node = NULL; zone_data_->insertName(mem_sgmt_, a_rrset_->getName(), &node); - ASSERT_NE(static_cast(NULL), node); + ASSERT_NE(static_cast(NULL), node); EXPECT_TRUE(node->isEmpty()); // initially it should be empty RdataSet* rdataset_a = @@ -102,4 +105,30 @@ TEST_F(ZoneDataTest, addRdataSets) { // TearDown() will confirm there's no leak on destroy } + +class NSEC3DataTest : public ::testing::Test { +protected: + NSEC3DataTest() : param_rdata_("1 0 12 aabbccdd") + {} + void TearDown() { + // detect any memory leak in the test memory segment + EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated()); + } + + MemorySegmentTest mem_sgmt_; + NSEC3Data* nsec3_data_; + const generic::NSEC3PARAM param_rdata_; +}; + +TEST_F(NSEC3DataTest, create) { + nsec3_data_ = NSEC3Data::create(mem_sgmt_, param_rdata_); + EXPECT_EQ(0, nsec3_data_->getNSEC3Tree()->getNodeCount()); + EXPECT_EQ(1, nsec3_data_->hashalg); + EXPECT_EQ(0, nsec3_data_->flags); + EXPECT_EQ(12, nsec3_data_->iterations); + EXPECT_EQ(param_rdata_.getSalt().size(), nsec3_data_->getSaltLen()); + EXPECT_EQ(0, memcmp(¶m_rdata_.getSalt()[0], nsec3_data_->getSaltData(), + param_rdata_.getSalt().size())); + NSEC3Data::destroy(mem_sgmt_, nsec3_data_, RRClass::IN()); +} } diff --git a/src/lib/datasrc/memory/zone_data.cc b/src/lib/datasrc/memory/zone_data.cc index 9bf7406e3f..3e38959ab2 100644 --- a/src/lib/datasrc/memory/zone_data.cc +++ b/src/lib/datasrc/memory/zone_data.cc @@ -16,6 +16,7 @@ #include #include +#include #include "rdataset.h" #include "rdata_encoder.h" @@ -29,6 +30,7 @@ #include // for the placement new using namespace isc::dns; +using namespace isc::dns::rdata; namespace isc { namespace datasrc { @@ -52,6 +54,36 @@ nullDeleter(RdataSet* rdataset_head) { } } +NSEC3Data* +NSEC3Data::create(util::MemorySegment& mem_sgmt, + const generic::NSEC3PARAM& rdata) +{ + ZoneTree* tree = ZoneTree::create(mem_sgmt, true); + + const size_t salt_len = rdata.getSalt().size(); + + void* p = mem_sgmt.allocate(sizeof(NSEC3Data) + salt_len + 1); + NSEC3Data* const param_data = + new(p) NSEC3Data(tree, rdata.getHashalg(), rdata.getFlags(), + rdata.getIterations()); + uint8_t* dp = param_data->getSaltBuf(); + *dp++ = salt_len; + memcpy(dp, &rdata.getSalt().at(0), salt_len); // use at for safety + + return (param_data); +} + +void +NSEC3Data::destroy(util::MemorySegment& mem_sgmt, NSEC3Data* data, + RRClass nsec3_class) +{ + ZoneTree::destroy(mem_sgmt, data->nsec3_tree_.get(), + boost::bind(rdataSetDeleter, nsec3_class, &mem_sgmt, + _1)); + + mem_sgmt.deallocate(data, sizeof(NSEC3Data) + 1 + data->getSaltLen()); +} + ZoneData* ZoneData::create(util::MemorySegment& mem_sgmt, const Name& zone_origin) { // ZoneTree::insert() and ZoneData allocation can throw. To avoid diff --git a/src/lib/datasrc/memory/zone_data.h b/src/lib/datasrc/memory/zone_data.h index 3b19ad4299..1802baed19 100644 --- a/src/lib/datasrc/memory/zone_data.h +++ b/src/lib/datasrc/memory/zone_data.h @@ -27,13 +27,58 @@ #include namespace isc { +namespace dns { +namespace rdata { +namespace generic { +class NSEC3PARAM; +} +} +} + namespace datasrc { namespace memory { +typedef DomainTree ZoneTree; +typedef DomainTreeNode ZoneNode; + +class NSEC3Data : boost::noncopyable { +public: + static NSEC3Data* create(util::MemorySegment& mem_sgmt, + const dns::rdata::generic::NSEC3PARAM& rdata); + static void destroy(util::MemorySegment& mem_sgmt, NSEC3Data* data, + dns::RRClass nsec3_class); + + const boost::interprocess::offset_ptr nsec3_tree_; +public: + const uint8_t hashalg; + const uint8_t flags; + const uint16_t iterations; + // For 64-bit machines there'll be a padding space here, but since + // only at most one (or a few in very rare cases) instance will be + // created per zone, the overhead should be acceptable. + + const ZoneTree* getNSEC3Tree() const { return (nsec3_tree_.get()); } + ZoneTree* getNSEC3Tree() { return (nsec3_tree_.get()); } + size_t getSaltLen() const { return (*getSaltBuf()); } + const uint8_t* getSaltData() const { return (getSaltBuf() + 1); } + +private: + NSEC3Data(ZoneTree* nsec3_tree_param, uint8_t hashalg_param, + uint8_t flags_param, uint16_t iterations_param) : + nsec3_tree_(nsec3_tree_param), hashalg(hashalg_param), + flags(flags_param), iterations(iterations_param) + {} + + const uint8_t* getSaltBuf() const { + return (reinterpret_cast(this + 1)); + } + uint8_t* getSaltBuf() { + return (reinterpret_cast(this + 1)); + } +}; + class ZoneData : boost::noncopyable { public: - typedef DomainTree ZoneTree; - typedef DomainTreeNode ZoneNode; private: ZoneData(ZoneTree* zone_tree, ZoneNode* origin_node) :