#include "memory_segment_test.h"
+#include <dns/rdataclass.h>
+
#include <exceptions/exceptions.h>
#include <dns/name.h>
#include <new> // 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;
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<ZoneData::ZoneNode*>(NULL), node);
+ ASSERT_NE(static_cast<ZoneNode*>(NULL), node);
EXPECT_TRUE(node->isEmpty()); // initially it should be empty
RdataSet* rdataset_a =
// 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());
+}
}
#include <dns/name.h>
#include <dns/rrclass.h>
+#include <dns/rdataclass.h>
#include "rdataset.h"
#include "rdata_encoder.h"
#include <new> // for the placement new
using namespace isc::dns;
+using namespace isc::dns::rdata;
namespace isc {
namespace datasrc {
}
}
+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
#include <boost/noncopyable.hpp>
namespace isc {
+namespace dns {
+namespace rdata {
+namespace generic {
+class NSEC3PARAM;
+}
+}
+}
+
namespace datasrc {
namespace memory {
+typedef DomainTree<RdataSet> ZoneTree;
+typedef DomainTreeNode<RdataSet> 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<ZoneTree> 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<const uint8_t*>(this + 1));
+ }
+ uint8_t* getSaltBuf() {
+ return (reinterpret_cast<uint8_t*>(this + 1));
+ }
+};
+
class ZoneData : boost::noncopyable {
public:
- typedef DomainTree<RdataSet> ZoneTree;
- typedef DomainTreeNode<RdataSet> ZoneNode;
private:
ZoneData(ZoneTree* zone_tree, ZoneNode* origin_node) :