Commit 0e19763b authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2098] supported toWire for renderer, still skipping some advanced cases.

parent 068ecfa5
......@@ -12,12 +12,14 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <util/buffer.h>
#include <util/memory_segment_local.h>
#include <datasrc/memory/treenode_rrset.h>
#include <datasrc/memory/rdataset.h>
#include <datasrc/memory/rdata_serialization.h>
#include <util/unittests/wiredata.h>
#include <testutils/dnsmessage_test.h>
#include <gtest/gtest.h>
......@@ -26,23 +28,42 @@ using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::datasrc::memory;
using namespace isc::testutils;
using isc::util::unittests::matchWireData;
using isc::util::OutputBuffer;
namespace {
class TreeNodeRRsetTest : public ::testing::Test {
protected:
TreeNodeRRsetTest() :
name_("www.example.com"),
rrclass_(RRClass::IN()),
origin_name_("example.com"), www_name_("www.example.com"),
ns_rrset_(textToRRset("example.com. 3600 IN NS ns.example.com.")),
a_rrset_(textToRRset("www.example.com. 3600 IN A 192.0.2.1")),
dname_rrset_(textToRRset("example.com. 3600 IN DNAME d.example.org.")),
rrsig_rrset_(textToRRset("www.example.com. 3600 IN RRSIG "
"A 5 2 3600 20120814220826 20120715220826 "
"1234 example.com. FAKE"))
{
"1234 example.com. FAKE")),
tree_(NULL)
{}
void SetUp() {
// We create some common test data here in SetUp() so it will be
// as exception safe as possible.
tree_ = ZoneTree::create(mem_sgmt_, true);
tree_->insert(mem_sgmt_, name_, &zone_node_);
rdataset_ = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
rrsig_rrset_);
zone_node_->setData(mem_sgmt_, rdataset_);
tree_->insert(mem_sgmt_, origin_name_, &origin_node_);
ns_rdataset_ = RdataSet::create(mem_sgmt_, encoder_, ns_rrset_,
ConstRRsetPtr());
origin_node_->setData(mem_sgmt_, ns_rdataset_);
dname_rdataset_ = RdataSet::create(mem_sgmt_, encoder_, dname_rrset_,
ConstRRsetPtr());
ns_rdataset_->next = dname_rdataset_;
tree_->insert(mem_sgmt_, www_name_, &www_node_);
a_rdataset_ = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
rrsig_rrset_);
www_node_->setData(mem_sgmt_, a_rdataset_);
}
void TearDown() {
ZoneTree::destroy(mem_sgmt_, tree_);
......@@ -50,25 +71,97 @@ protected:
EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated());
}
const Name name_;
const RRClass rrclass_;
const Name origin_name_, www_name_;
isc::util::MemorySegmentLocal mem_sgmt_;
RdataEncoder encoder_;
ConstRRsetPtr a_rrset_, rrsig_rrset_;
MessageRenderer renderer_, renderer_expected_;
ConstRRsetPtr ns_rrset_, a_rrset_, dname_rrset_, rrsig_rrset_;
ZoneTree* tree_;
ZoneNode* zone_node_;
RdataSet* rdataset_;
ZoneNode* origin_node_;
ZoneNode* www_node_;
RdataSet* ns_rdataset_;
RdataSet* dname_rdataset_;
RdataSet* a_rdataset_;
};
TEST_F(TreeNodeRRsetTest, create) {
const TreeNodeRRset rrset1(RRClass::IN(), zone_node_, rdataset_, true);
const TreeNodeRRset rrset1(RRClass::IN(), www_node_, a_rdataset_, true);
EXPECT_EQ(RRClass::IN(), rrset1.getClass());
EXPECT_EQ(RRType::A(), rrset1.getType());
EXPECT_EQ(1, rrset1.getRdataCount());
EXPECT_EQ(1, rrset1.getRRsigDataCount());
const TreeNodeRRset rrset2(RRClass::IN(), zone_node_, rdataset_, false);
const TreeNodeRRset rrset2(RRClass::IN(), www_node_, a_rdataset_, false);
EXPECT_EQ(RRClass::IN(), rrset2.getClass());
EXPECT_EQ(1, rrset2.getRdataCount());
EXPECT_EQ(0, rrset2.getRRsigDataCount());
}
template <typename OutputType>
void
checkToWireResult(OutputType& expected_output, OutputType& actual_output,
const TreeNodeRRset& actual_rrset,
const Name& prepended_name,
ConstRRsetPtr rrset, ConstRRsetPtr rrsig_rrset,
bool dnssec_ok)
{
expected_output.clear();
actual_output.clear();
// Prepare "actual" rendered data. We prepend a name to confirm the
// owner name should be compressed in both cases.
prepended_name.toWire(actual_output);
const int expected_ret = (dnssec_ok && rrsig_rrset) ?
rrset->getRdataCount() + rrsig_rrset->getRdataCount() :
rrset->getRdataCount();
EXPECT_EQ(expected_ret, actual_rrset.toWire(actual_output));
// Prepare "expected" data.
prepended_name.toWire(expected_output);
rrset->toWire(expected_output);
if (dnssec_ok && rrsig_rrset) {
rrsig_rrset->toWire(expected_output);
}
// Compare the two.
matchWireData(expected_output.getData(), expected_output.getLength(),
actual_output.getData(), actual_output.getLength());
}
TEST_F(TreeNodeRRsetTest, toWire) {
MessageRenderer expected_renderer, actual_renderer;
//OutputBuffer expected_buffer(0), actual_buffer(0);
// 1. with RRSIG, DNSSEC OK
const TreeNodeRRset rrset1(RRClass::IN(), www_node_, a_rdataset_, true);
checkToWireResult(expected_renderer, actual_renderer, rrset1, www_name_,
a_rrset_, rrsig_rrset_, true);
#ifdef notyet
checkToWireResult(expected_buffer, actual_buffer, rrset1, www_name_,
a_rrset_, rrsig_rrset_, true);
#endif
// 2. with RRSIG, DNSSEC not OK
const TreeNodeRRset rrset2(rrclass_, www_node_, a_rdataset_, false);
checkToWireResult(expected_renderer, actual_renderer, rrset2, www_name_,
a_rrset_, rrsig_rrset_, false);
// 3. without RRSIG, DNSSEC OK
const TreeNodeRRset rrset3(rrclass_, origin_node_, ns_rdataset_, true);
checkToWireResult(expected_renderer, actual_renderer, rrset3, origin_name_,
ns_rrset_, ConstRRsetPtr(), true);
// 4. without RRSIG, DNSSEC not OK
const TreeNodeRRset rrset4(rrclass_, origin_node_, ns_rdataset_, false);
checkToWireResult(expected_renderer, actual_renderer, rrset4, origin_name_,
ns_rrset_, ConstRRsetPtr(), false);
// RDATA of DNAME RR shouldn't be compressed. Prepending "example.org"
// will check that.
const TreeNodeRRset rrset5(rrclass_, origin_node_, dname_rdataset_, false);
checkToWireResult(expected_renderer, actual_renderer, rrset5,
Name("example.org"), dname_rrset_, ConstRRsetPtr(),
false);
}
}
......@@ -25,7 +25,11 @@
#include <dns/rrset.h>
#include "treenode_rrset.h"
#include "rdata_serialization.h"
#include <boost/bind.hpp>
#include <cassert>
#include <string>
using namespace isc::dns;
......@@ -55,17 +59,80 @@ TreeNodeRRset::setTTL(const RRTTL&) {
isc_throw(Unexpected, "unexpected method called on TreeNodeRRset");
}
// needed
// needed
std::string
TreeNodeRRset::toText() const {
isc_throw(Unexpected, "unexpected method called on TreeNodeRRset");
}
namespace {
void
renderName(const LabelSequence& name_labels, RdataNameAttributes attr,
AbstractMessageRenderer* renderer)
{
renderer->writeName(name_labels, (attr & NAMEATTR_COMPRESSIBLE) != 0);
}
void
renderData(const void* data, size_t data_len,
AbstractMessageRenderer* renderer)
{
renderer->writeData(data, data_len);
}
}
// needed
unsigned int
TreeNodeRRset::toWire(AbstractMessageRenderer& /*renderer*/) const {
isc_throw(Unexpected, "unexpected method called on TreeNodeRRset");
TreeNodeRRset::toWire(AbstractMessageRenderer& renderer) const {
RdataReader reader(rrclass_, rdataset_->type, rdataset_->getDataBuf(),
rdataset_->getRdataCount(), rrsig_count_,
boost::bind(renderName, _1, _2, &renderer),
boost::bind(renderData, _1, _2, &renderer));
// Get the owner name of the RRset in the form of LabelSequence.
uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
const LabelSequence node_labels = node_->getAbsoluteLabels(labels_buf);
size_t i = 0;
for (; i < rdataset_->getRdataCount(); ++i) {
//const size_t pos0 = output.getLength();
renderer.writeName(node_labels, true);
rdataset_->type.toWire(renderer);
rrclass_.toWire(renderer);
renderer.writeData(rdataset_->getTTLData(), sizeof(uint32_t));
const size_t pos = renderer.getLength();
renderer.skip(sizeof(uint16_t)); // leave the space for RDLENGTH
const bool rendered = reader.iterateRdata();
assert(rendered == true);
renderer.writeUint16At(renderer.getLength() - pos - sizeof(uint16_t),
pos);
// for truncation processing
}
const bool rendered = reader.iterateRdata();
assert(rendered == false); // we should've reached the end
size_t j = 0;
if (dnssec_ok_) {
for (; j < rrsig_count_; ++j) {
// TBD: truncation consideration
renderer.writeName(node_labels, true);
RRType::RRSIG().toWire(renderer);
rrclass_.toWire(renderer);
renderer.writeData(rdataset_->getTTLData(), sizeof(uint32_t));
const size_t pos = renderer.getLength();
renderer.skip(sizeof(uint16_t)); // leave the space for RDLENGTH
assert(reader.iterateSingleSig() == true);
renderer.writeUint16At(renderer.getLength() - pos -
sizeof(uint16_t), pos);
}
assert(reader.iterateSingleSig() == false);
}
return (i + j);
}
unsigned int
......
......@@ -16,7 +16,7 @@
#define DATASRC_MEMORY_TREENODE_RRSET_H 1
#include <util/buffer.h>
#include <util/memory_segment.h>
#include <util/memory_segment.h> // CLEAN UP: only for temporary setup
#include <dns/messagerenderer.h>
#include <dns/name.h>
......@@ -26,7 +26,7 @@
#include <dns/rdata.h>
#include <dns/rrset.h>
#include <datasrc/memory/domaintree.h>
#include <datasrc/memory/domaintree.h> // CLEAN UP: only for temporary setup
#include <datasrc/memory/zone_data.h>
#include <datasrc/memory/rdataset.h>
......@@ -36,6 +36,7 @@ namespace isc {
namespace datasrc {
namespace memory {
// Temporary definition: Until we merge #2107 we need the following
class RdataSetDeleter {
public:
RdataSetDeleter() {}
......@@ -52,12 +53,14 @@ public:
typedef DomainTree<RdataSet, RdataSetDeleter> ZoneTree;
typedef DomainTreeNode<RdataSet, RdataSetDeleter> ZoneNode;
// end of temporary definition
class TreeNodeRRset : public dns::AbstractRRset {
public:
TreeNodeRRset(dns::RRClass rrclass, const ZoneNode* node,
const RdataSet* rdataset, bool dnssec_ok) :
node_(node), rdataset_(rdataset), rrclass_(rrclass),
node_(node), rdataset_(rdataset),
rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
dnssec_ok_(dnssec_ok)
{}
......@@ -94,7 +97,7 @@ public:
virtual dns::RRsetPtr getRRsig() const;
virtual unsigned int getRRsigDataCount() const {
return (dnssec_ok_ ? rdataset_->getSigRdataCount() : 0);
return (dnssec_ok_ ? rrsig_count_ : 0);
}
virtual void addRRsig(const dns::rdata::ConstRdataPtr& rdata);
......@@ -110,6 +113,7 @@ public:
private:
const ZoneNode* node_;
const RdataSet* rdataset_;
const size_t rrsig_count_;
const dns::RRClass rrclass_;
const bool dnssec_ok_;
};
......
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