BIND 10 trac1396, updated. 1e762fa3653c39e649f1b8cf66f17c0bdd8bdfa7 [1396] Use RRset::getLength() in xfrout
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Jan 28 05:55:40 UTC 2014
The branch, trac1396 has been updated
via 1e762fa3653c39e649f1b8cf66f17c0bdd8bdfa7 (commit)
via 63eca991aef43dac723b6aec44345c7747b5939a (commit)
via 6f177a3d2719a0b08501d22cdd725ff5824bb688 (commit)
from 5410f9ce9d90585e00828253cedce1e024ad4524 (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 1e762fa3653c39e649f1b8cf66f17c0bdd8bdfa7
Author: Mukund Sivaraman <muks at isc.org>
Date: Tue Jan 28 11:25:13 2014 +0530
[1396] Use RRset::getLength() in xfrout
commit 63eca991aef43dac723b6aec44345c7747b5939a
Author: Mukund Sivaraman <muks at isc.org>
Date: Tue Jan 28 11:24:31 2014 +0530
[1396] Fix width of TTL field
commit 6f177a3d2719a0b08501d22cdd725ff5824bb688
Author: Mukund Sivaraman <muks at isc.org>
Date: Tue Jan 28 11:10:35 2014 +0530
[1396] Add TreenodeRRset::getLength() implementation
-----------------------------------------------------------------------
Summary of changes:
src/bin/xfrout/xfrout.py.in | 6 +-
src/lib/datasrc/memory/treenode_rrset.cc | 75 ++++++++++++++++++++
src/lib/datasrc/memory/treenode_rrset.h | 4 +-
.../tests/memory/treenode_rrset_unittest.cc | 31 ++++++++
src/lib/dns/python/tests/rrset_python_test.py | 10 +--
src/lib/dns/rrset.cc | 4 +-
src/lib/dns/tests/rrset_unittest.cc | 28 ++++----
7 files changed, 133 insertions(+), 25 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/xfrout/xfrout.py.in b/src/bin/xfrout/xfrout.py.in
index aa84587..a776690 100755
--- a/src/bin/xfrout/xfrout.py.in
+++ b/src/bin/xfrout/xfrout.py.in
@@ -143,11 +143,11 @@ def format_addrinfo(addrinfo):
raise TypeError("addrinfo argument to format_addrinfo() does not "
"appear to be consisting of (family, socktype, (addr, port))")
+# This function is not inlined as it is replaced with a mock function
+# during testing.
def get_rrset_len(rrset):
"""Returns the wire length of the given RRset"""
- bytes = bytearray()
- rrset.to_wire(bytes)
- return len(bytes)
+ return rrset.get_length()
def get_soa_serial(soa_rdata):
'''Extract the serial field of an SOA RDATA and returns it as an Serial object.
diff --git a/src/lib/datasrc/memory/treenode_rrset.cc b/src/lib/datasrc/memory/treenode_rrset.cc
index 4734e04..1d468ef 100644
--- a/src/lib/datasrc/memory/treenode_rrset.cc
+++ b/src/lib/datasrc/memory/treenode_rrset.cc
@@ -101,6 +101,19 @@ TreeNodeRRset::toText() const {
namespace {
void
+sizeupName(const LabelSequence& name_labels, RdataNameAttributes,
+ size_t* length)
+{
+ *length += name_labels.getDataLength();
+}
+
+void
+sizeupData(const void*, size_t data_len, size_t* length)
+{
+ *length += data_len;
+}
+
+void
renderName(const LabelSequence& name_labels, RdataNameAttributes attr,
AbstractMessageRenderer* renderer)
{
@@ -114,6 +127,35 @@ renderData(const void* data, size_t data_len,
renderer->writeData(data, data_len);
}
+// Helper for calculating wire data length of a single (etiher main or
+// RRSIG) RRset.
+uint16_t
+getLengthHelper(size_t* rlength, size_t rr_count, uint16_t name_labels_size,
+ RdataReader& reader, bool (RdataReader::* rdata_iterate_fn)())
+{
+ uint16_t length = 0;
+
+ for (size_t i = 0; i < rr_count; ++i) {
+ size_t rrlen = 0;
+
+ rrlen += name_labels_size;
+ rrlen += 2; // TYPE field
+ rrlen += 2; // CLASS field
+ rrlen += 4; // TTL field
+ rrlen += 2; // RDLENGTH field
+
+ *rlength = 0;
+ const bool rendered = (reader.*rdata_iterate_fn)();
+ assert(rendered == true);
+
+ rrlen += *rlength;
+ assert(length + rrlen < 65536);
+ length += rrlen;
+ }
+
+ return (length);
+}
+
// Common code logic for rendering a single (either main or RRSIG) RRset.
size_t
writeRRs(AbstractMessageRenderer& renderer, size_t rr_count,
@@ -149,6 +191,39 @@ writeRRs(AbstractMessageRenderer& renderer, size_t rr_count,
}
}
+uint16_t
+TreeNodeRRset::getLength() const {
+ size_t rlength = 0;
+ RdataReader reader(rrclass_, rdataset_->type, rdataset_->getDataBuf(),
+ rdataset_->getRdataCount(), rrsig_count_,
+ boost::bind(sizeupName, _1, _2, &rlength),
+ boost::bind(sizeupData, _1, _2, &rlength));
+
+ // Get the owner name of the RRset in the form of LabelSequence.
+ uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
+ const LabelSequence name_labels = getOwnerLabels(labels_buf);
+ const uint16_t name_labels_size = name_labels.getDataLength();
+
+ // Find the length of the main (non RRSIG) RRs
+ const uint16_t rrset_length =
+ getLengthHelper(&rlength, rdataset_->getRdataCount(), name_labels_size,
+ reader, &RdataReader::iterateRdata);
+
+ rlength = 0;
+ const bool rendered = reader.iterateRdata();
+ assert(rendered == false); // we should've reached the end
+
+ // Find the length of any RRSIGs, if we supposed to do so
+ const uint16_t rrsig_length = dnssec_ok_ ?
+ getLengthHelper(&rlength, rrsig_count_, name_labels_size,
+ reader, &RdataReader::iterateSingleSig) : 0;
+
+ // the uint16_ts are promoted to ints during addition below, so it
+ // won't overflow a 16-bit register.
+ assert(rrset_length + rrsig_length < 65536);
+ return (rrset_length + rrsig_length);
+}
+
unsigned int
TreeNodeRRset::toWire(AbstractMessageRenderer& renderer) const {
RdataReader reader(rrclass_, rdataset_->type, rdataset_->getDataBuf(),
diff --git a/src/lib/datasrc/memory/treenode_rrset.h b/src/lib/datasrc/memory/treenode_rrset.h
index 640c972..51e1eed 100644
--- a/src/lib/datasrc/memory/treenode_rrset.h
+++ b/src/lib/datasrc/memory/treenode_rrset.h
@@ -155,7 +155,7 @@ public:
node_(node), rdataset_(rdataset),
rrsig_count_(rdataset_->getSigRdataCount()), rrclass_(rrclass),
dnssec_ok_(dnssec_ok), name_(NULL), realname_(new dns::Name(realname)),
- ttl_data_(rdataset->getTTLData()), ttl_(NULL)
+ ttl_data_(rdataset->getTTLData()), ttl_(NULL)
{}
virtual ~TreeNodeRRset() {
@@ -168,6 +168,8 @@ public:
return (rdataset_->getRdataCount());
}
+ virtual uint16_t getLength() const;
+
virtual const dns::Name& getName() const;
virtual const dns::RRClass& getClass() const {
return (rrclass_);
diff --git a/src/lib/datasrc/tests/memory/treenode_rrset_unittest.cc b/src/lib/datasrc/tests/memory/treenode_rrset_unittest.cc
index 4d1f6e1..451a91a 100644
--- a/src/lib/datasrc/tests/memory/treenode_rrset_unittest.cc
+++ b/src/lib/datasrc/tests/memory/treenode_rrset_unittest.cc
@@ -333,6 +333,37 @@ checkToWireResult(OutputType& expected_output, OutputType& actual_output,
actual_output.getData(), actual_output.getLength());
}
+TEST_F(TreeNodeRRsetTest, getLength) {
+ // A RR
+ // www.example.com = 1 + 3 + 1 + 7 + 1 + 3 + 1 = 17 octets
+ // TYPE field = 2 octets
+ // CLASS field = 2 octets
+ // TTL field = 4 octets
+ // RDLENGTH field = 2 octets
+ // A RDATA = 4 octets
+ // Total = 17 + 2 + 2 + 4 + 2 + 4 = 31 octets
+
+ // RRSIG RR
+ // www.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 17 octets
+ // TYPE field = 2 octets
+ // CLASS field = 2 octets
+ // TTL field = 4 octets
+ // RDLENGTH field = 2 octets
+ // RRSIG RDATA = 18 + [1 + 7 + 1 + 3 + 1 (example.com)] + 3 (base64
+ // decode of FAKE) octets
+ // Total = 17 + 2 + 2 + 4 + 2 + 34 = 61 octets
+
+ // 1. with RRSIG, DNSSEC not OK
+ // ` 2 A RRs + 0 RRSIG RRs
+ const TreeNodeRRset rrset1(rrclass_, www_node_, a_rdataset_, false);
+ EXPECT_EQ(31 + 31, rrset1.getLength());
+
+ // 2. with RRSIG, DNSSEC OK
+ // ` 2 A RRs + 1 RRSIG RR
+ const TreeNodeRRset rrset2(rrclass_, www_node_, a_rdataset_, true);
+ EXPECT_EQ(31 + 31 + 61, rrset2.getLength());
+}
+
TEST_F(TreeNodeRRsetTest, toWire) {
MessageRenderer expected_renderer, actual_renderer;
OutputBuffer expected_buffer(0), actual_buffer(0);
diff --git a/src/lib/dns/python/tests/rrset_python_test.py b/src/lib/dns/python/tests/rrset_python_test.py
index 4298181..d848d27 100644
--- a/src/lib/dns/python/tests/rrset_python_test.py
+++ b/src/lib/dns/python/tests/rrset_python_test.py
@@ -53,15 +53,15 @@ class TestModuleSpec(unittest.TestCase):
# test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets
# TYPE field = 2 octets
# CLASS field = 2 octets
- # TTL field = 2 octets
+ # TTL field = 4 octets
# RDLENGTH field = 2 octets
- # Total = 18 + 2 + 2 + 2 + 2 = 26 octets
- self.assertEqual(26, self.rrset_any_a_empty.get_length())
+ # Total = 18 + 2 + 2 + 4 + 2 = 28 octets
+ self.assertEqual(28, self.rrset_any_a_empty.get_length())
# Single A RR:
- # 26 octets (above) + 4 octets (A RDATA) = 30 octets
+ # 28 octets (above) + 4 octets (A RDATA) = 32 octets
# With 2 A RRs:
- self.assertEqual(30 + 30, self.rrset_a.get_length())
+ self.assertEqual(32 + 32, self.rrset_a.get_length())
def test_get_name(self):
self.assertEqual(self.test_name, self.rrset_a.get_name())
diff --git a/src/lib/dns/rrset.cc b/src/lib/dns/rrset.cc
index 7fbd0d1..8b9f4c4 100644
--- a/src/lib/dns/rrset.cc
+++ b/src/lib/dns/rrset.cc
@@ -306,7 +306,7 @@ BasicRRset::getLength() const {
length += getName().getLength();
length += 2; // TYPE field
length += 2; // CLASS field
- length += 2; // TTL field
+ length += 4; // TTL field
length += 2; // RDLENGTH field (=0 in wire format)
return (length);
@@ -320,7 +320,7 @@ BasicRRset::getLength() const {
rrlen += getName().getLength();
rrlen += 2; // TYPE field
rrlen += 2; // CLASS field
- rrlen += 2; // TTL field
+ rrlen += 4; // TTL field
rrlen += 2; // RDLENGTH field
rrlen += it->getCurrent().getLength();
diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc
index 72049b2..558b663 100644
--- a/src/lib/dns/tests/rrset_unittest.cc
+++ b/src/lib/dns/tests/rrset_unittest.cc
@@ -212,20 +212,20 @@ TEST_F(RRsetTest, getLength) {
// test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets
// TYPE field = 2 octets
// CLASS field = 2 octets
- // TTL field = 2 octets
+ // TTL field = 4 octets
// RDLENGTH field = 2 octets
- // Total = 18 + 2 + 2 + 2 + 2 = 26 octets
- EXPECT_EQ(26, rrset_any_a_empty.getLength());
- EXPECT_EQ(26, rrset_none_a_empty.getLength());
+ // Total = 18 + 2 + 2 + 4 + 2 = 28 octets
+ EXPECT_EQ(28, rrset_any_a_empty.getLength());
+ EXPECT_EQ(28, rrset_none_a_empty.getLength());
// RRset with single RDATA
- // 26 (above) + 4 octets (A RDATA) = 30 octets
+ // 28 (above) + 4 octets (A RDATA) = 32 octets
rrset_a_empty.addRdata(in::A("192.0.2.1"));
- EXPECT_EQ(30, rrset_a_empty.getLength());
+ EXPECT_EQ(32, rrset_a_empty.getLength());
// 2 A RRs
rrset_a_empty.addRdata(in::A("192.0.2.2"));
- EXPECT_EQ(60, rrset_a_empty.getLength());
+ EXPECT_EQ(32 + 32, rrset_a_empty.getLength());
}
TEST_F(RRsetTest, toWireBuffer) {
@@ -395,32 +395,32 @@ TEST_F(RRsetRRSIGTest, getLength) {
// test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets
// TYPE field = 2 octets
// CLASS field = 2 octets
- // TTL field = 2 octets
+ // TTL field = 4 octets
// RDLENGTH field = 2 octets
// A RDATA = 4 octets
- // Total = 18 + 2 + 2 + 2 + 2 + 4 = 30 octets
+ // Total = 18 + 2 + 2 + 4 + 2 + 4 = 32 octets
// 2 A RRs
- EXPECT_EQ(60, rrset_a->getLength());
+ EXPECT_EQ(32 + 32, rrset_a->getLength());
// RRSIG
// test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets
// TYPE field = 2 octets
// CLASS field = 2 octets
- // TTL field = 2 octets
+ // TTL field = 4 octets
// RDLENGTH field = 2 octets
// RRSIG RDATA = 40 octets
- // Total = 18 + 2 + 2 + 2 + 2 + 40 = 66 octets
+ // Total = 18 + 2 + 2 + 4 + 2 + 40 = 68 octets
RRsetPtr my_rrsig(new RRset(test_name, RRClass::IN(),
RRType::RRSIG(), RRTTL(3600)));
my_rrsig->addRdata(generic::RRSIG("A 4 3 3600 "
"20000101000000 20000201000000 "
"12345 example.com. FAKEFAKEFAKE"));
- EXPECT_EQ(66, my_rrsig->getLength());
+ EXPECT_EQ(68, my_rrsig->getLength());
// RRset with attached RRSIG
rrset_a->addRRsig(my_rrsig);
- EXPECT_EQ(60 + 66, rrset_a->getLength());
+ EXPECT_EQ(32 + 32 + 68, rrset_a->getLength());
}
}
More information about the bind10-changes
mailing list