Commit aacf7cb7 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2107] supported the creation of NSEC3Data from NSEC3 rdata.

parent c6bdb4b4
......@@ -46,7 +46,12 @@ protected:
NSEC3DataTest() : nsec3_data_(NULL), param_rdata_("1 0 12 aabbccdd"),
param_rdata_nosalt_("1 1 10 -"),
param_rdata_largesalt_(
"2 0 5 " + std::string(255 * 2, 'a'))
"2 0 5 " + std::string(255 * 2, 'a')),
nsec3_rdata_("1 0 12 aabbccdd TDK23RP6 SOA"),
nsec3_rdata_nosalt_("1 1 10 - TDK23RP6 SOA"),
nsec3_rdata_largesalt_(
"2 0 5 " + std::string(255 * 2, 'a') +
" TDK23RP6 SOA")
{}
void TearDown() {
if (nsec3_data_ != NULL) {
......@@ -58,38 +63,45 @@ protected:
MemorySegmentTest mem_sgmt_;
NSEC3Data* nsec3_data_;
const generic::NSEC3PARAM param_rdata_;
const generic::NSEC3PARAM param_rdata_nosalt_;
const generic::NSEC3PARAM param_rdata_largesalt_;
const generic::NSEC3PARAM param_rdata_, param_rdata_nosalt_,
param_rdata_largesalt_;
const generic::NSEC3 nsec3_rdata_, nsec3_rdata_nosalt_,
nsec3_rdata_largesalt_;
};
// Shared by both test cases using NSEC3 and NSEC3PARAM Rdata
template <typename RdataType>
void
check(const generic::NSEC3PARAM& expect_rdata, const NSEC3Data& nsec3_data) {
checkNSEC3Data(MemorySegmentTest& mem_sgmt, const RdataType& expect_rdata) {
NSEC3Data* nsec3_data = NSEC3Data::create(mem_sgmt, expect_rdata);
// Internal tree should be created and empty.
EXPECT_EQ(0, nsec3_data.getNSEC3Tree()->getNodeCount());
EXPECT_EQ(0, nsec3_data->getNSEC3Tree()->getNodeCount());
EXPECT_EQ(expect_rdata.getHashalg(), nsec3_data.hashalg);
EXPECT_EQ(expect_rdata.getFlags(), nsec3_data.flags);
EXPECT_EQ(expect_rdata.getIterations(), nsec3_data.iterations);
EXPECT_EQ(expect_rdata.getSalt().size(), nsec3_data.getSaltLen());
EXPECT_EQ(expect_rdata.getHashalg(), nsec3_data->hashalg);
EXPECT_EQ(expect_rdata.getFlags(), nsec3_data->flags);
EXPECT_EQ(expect_rdata.getIterations(), nsec3_data->iterations);
EXPECT_EQ(expect_rdata.getSalt().size(), nsec3_data->getSaltLen());
if (expect_rdata.getSalt().size() > 0) {
EXPECT_EQ(0, memcmp(&expect_rdata.getSalt()[0],
nsec3_data.getSaltData(),
nsec3_data->getSaltData(),
expect_rdata.getSalt().size()));
}
NSEC3Data::destroy(mem_sgmt, nsec3_data, RRClass::IN());
}
TEST_F(NSEC3DataTest, create) {
nsec3_data_ = NSEC3Data::create(mem_sgmt_, param_rdata_);
check(param_rdata_, *nsec3_data_);
NSEC3Data::destroy(mem_sgmt_, nsec3_data_, RRClass::IN());
nsec3_data_ = NSEC3Data::create(mem_sgmt_, param_rdata_nosalt_);
check(param_rdata_nosalt_, *nsec3_data_);
NSEC3Data::destroy(mem_sgmt_, nsec3_data_, RRClass::IN());
nsec3_data_ = NSEC3Data::create(mem_sgmt_, param_rdata_largesalt_);
check(param_rdata_largesalt_, *nsec3_data_);
// Create an NSEC3Data object from various types of RDATA (of NSEC3PARAM
// and of NSEC3), check if the resulting parameters match.
checkNSEC3Data(mem_sgmt_, param_rdata_); // one 'usual' form of params
checkNSEC3Data(mem_sgmt_, param_rdata_nosalt_); // empty salt
checkNSEC3Data(mem_sgmt_, param_rdata_largesalt_); // max-len salt
// Same concepts of the tests, using NSEC3 RDATA.
checkNSEC3Data(mem_sgmt_, nsec3_rdata_);
checkNSEC3Data(mem_sgmt_, nsec3_rdata_nosalt_);
checkNSEC3Data(mem_sgmt_, nsec3_rdata_largesalt_);
}
TEST_F(NSEC3DataTest, throwOnCreate) {
......
......@@ -28,6 +28,7 @@
#include <cassert>
#include <new> // for the placement new
#include <vector>
using namespace isc::dns;
using namespace isc::dns::rdata;
......@@ -57,6 +58,21 @@ nullDeleter(RdataSet* rdataset_head) {
NSEC3Data*
NSEC3Data::create(util::MemorySegment& mem_sgmt,
const generic::NSEC3PARAM& rdata)
{
return (NSEC3Data::create(mem_sgmt, rdata.getHashalg(), rdata.getFlags(),
rdata.getIterations(), rdata.getSalt()));
}
NSEC3Data*
NSEC3Data::create(util::MemorySegment& mem_sgmt, const generic::NSEC3& rdata) {
return (NSEC3Data::create(mem_sgmt, rdata.getHashalg(), rdata.getFlags(),
rdata.getIterations(), rdata.getSalt()));
}
NSEC3Data*
NSEC3Data::create(util::MemorySegment& mem_sgmt, uint8_t hashalg,
uint8_t flags, uint16_t iterations,
const std::vector<uint8_t>& salt)
{
// NSEC3Data allocation can throw. To avoid leaking the tree, we manage
// it in the holder.
......@@ -67,16 +83,15 @@ NSEC3Data::create(util::MemorySegment& mem_sgmt,
mem_sgmt, ZoneTree::create(mem_sgmt, true),
boost::bind(nullDeleter, _1));
const size_t salt_len = rdata.getSalt().size();
const size_t salt_len = salt.size();
void* p = mem_sgmt.allocate(sizeof(NSEC3Data) + salt_len + 1);
NSEC3Data* const param_data =
new(p) NSEC3Data(holder.release(), rdata.getHashalg(),
rdata.getFlags(), rdata.getIterations());
new(p) NSEC3Data(holder.release(), hashalg, flags, iterations);
uint8_t* dp = param_data->getSaltBuf();
*dp++ = salt_len;
*dp++ = salt_len;
if (salt_len > 0) {
memcpy(dp, &rdata.getSalt().at(0), salt_len); // use at for safety
memcpy(dp, &salt.at(0), salt_len); // use at for safety
}
return (param_data);
......
......@@ -26,6 +26,8 @@
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <vector>
namespace isc {
namespace dns {
namespace rdata {
......@@ -45,6 +47,8 @@ class NSEC3Data : boost::noncopyable {
public:
static NSEC3Data* create(util::MemorySegment& mem_sgmt,
const dns::rdata::generic::NSEC3PARAM& rdata);
static NSEC3Data* create(util::MemorySegment& mem_sgmt,
const dns::rdata::generic::NSEC3& rdata);
static void destroy(util::MemorySegment& mem_sgmt, NSEC3Data* data,
dns::RRClass nsec3_class);
......@@ -63,6 +67,11 @@ public:
const uint8_t* getSaltData() const { return (getSaltBuf() + 1); }
private:
// Common subroutine for the public versions of create().
static NSEC3Data* create(util::MemorySegment& mem_sgmt, uint8_t hashalg,
uint8_t flags, uint16_t iterations,
const std::vector<uint8_t>& salt);
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),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment