Commit 010bda2e authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2976] Basic implementation of fromWire test.

parent 87fc0368
......@@ -26,7 +26,9 @@ using namespace isc::dns;
D2UpdateMessage::D2UpdateMessage(const bool parse)
: message_(parse ? dns::Message::PARSE : dns::Message::RENDER) {
message_.setOpcode(Opcode(Opcode::UPDATE_CODE));
if (!parse) {
message_.setOpcode(Opcode(Opcode::UPDATE_CODE));
}
}
D2UpdateMessage::QRFlag
......@@ -67,6 +69,16 @@ D2UpdateMessage::getRRCount(const UpdateMsgSection section) const {
return (message_.getRRCount(ddnsToDnsSection(section)));
}
const dns::RRsetIterator
D2UpdateMessage::beginSection(const UpdateMsgSection section) const {
return (message_.beginSection(ddnsToDnsSection(section)));
}
const dns::RRsetIterator
D2UpdateMessage::endSection(const UpdateMsgSection section) const {
return (message_.endSection(ddnsToDnsSection(section)));
}
void
D2UpdateMessage::setZone(const Name& zone, const RRClass& rrclass) {
if (message_.getRRCount(dns::Message::SECTION_QUESTION) > 0) {
......
......@@ -16,6 +16,7 @@
#include <d2/d2_update_message.h>
#include <dns/messagerenderer.h>
#include <dns/rdataclass.h>
#include <dns/rdata.h>
#include <dns/rrttl.h>
......@@ -74,6 +75,128 @@ public:
}
};
// This test verifies that the DNS message is properly decoded from the
// wire format.
TEST_F(D2UpdateMessageTest, fromWire) {
// The following table holds the DNS response in on-wire format.
// This message comprises the following sections:
// - HEADER
// - PREREQUISITE section with one RR
// - UPDATE section with 1 RR.
// Such a response may be generated by the DNS server as a result
// of copying the contents of the REQUEST message sent by DDNS client.
const uint8_t bin_msg[] = {
// HEADER section starts here (see RFC 2136, section 2).
0x05, 0xAF, // ID=0x05AF
0xA8, 0x6, // QR=1, Opcode=6, RCODE=YXDOMAIN
0x0, 0x1, // ZOCOUNT=1
0x0, 0x2, // PRCOUNT=2
0x0, 0x1, // UPCOUNT=1
0x0, 0x0, // ADCOUNT=0
// Zone section starts here. The The first field comprises
// the Zone name encoded as a set of labels, each preceded
// by a length of the following label. The whole Zone name is
// terminated with a NULL char.
// For Zone section format see (RFC 2136, section 2.3).
0x7, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example (0x7 is a length)
0x3, 0x63, 0x6F, 0x6D, //.com. (0x3 is a length)
0x0, // NULL character terminates the Zone name.
0x0, 0x6, // ZTYPE='SOA'
0x0, 0x1, // ZCLASS='IN'
// Prerequisite section starts here. This section comprises two
// prerequisites:
// - 'Name is not in use'
// - 'Name is in use'
// See RFC 2136, section 2.4 for the format of Prerequisite section.
// Each prerequisite RR starts with its name. It is expressed in the
// compressed format as described in RFC 1035, section 4.1.4. The first
// label is expressed as in case of non-compressed name. It is preceded
// by the length value. The following two bytes are the pointer to the
// offset in the message where 'example.com' was used. That is, in the
// Zone name at offset 12. Pointer starts with two bits set - they
// mark start of the pointer.
// First prerequisite. NONE class indicates that the update requires
// that the name 'foo.example.com' is not use/
0x03, 0x66, 0x6F, 0x6F, // foo.
0xC0, 0x0C, // pointer to example.com.
0x0, 0x1C, // TYPE=AAAA
0x0, 0xFE, // CLASS=NONE
0x0, 0x0, 0x0, 0x0, // TTL=0
0x0, 0x0, // RDLENGTH=0
// Second prerequisite. ANY class indicates tha the update requires
// that the name 'bar.example.com' exists.
0x03, 0x62, 0x61, 0x72, // bar.
0xC0, 0x0C, // pointer to example.com.
0x0, 0x1C, // TYPE=AAAA
0x0, 0xFF, // CLASS=ANY
0x0, 0x0, 0x0, 0x0, // TTL=0
0x0, 0x0, // RDLENGTH=0
// Update section starts here. The format of this section conforms to
// RFC 2136, section 2.5. The name of the RR is again expressed in
// compressed format. The two pointer bytes point to the offset in the
// message where 'foo.example.com' was used already - 29.
0xC0, 0x1D, // pointer to foo.example.com.
0x0, 0x1C, // TYPE=AAAA
0x0, 0x1, // CLASS=IN
0xAA, 0xBB, 0xCC, 0xDD, // TTL=0xAABBCCDD
0x0, 0x10, // RDLENGTH=16
// The following 16 bytes of RDATA hold IPv6 address: 2001:db8:1::1.
0x20, 0x01, 0x0D, 0xB8, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
InputBuffer buf(bin_msg, sizeof(bin_msg));
D2UpdateMessage msg(true);
ASSERT_NO_THROW(msg.fromWire(buf));
EXPECT_EQ(0x05AF, msg.getQid());
EXPECT_EQ(D2UpdateMessage::RESPONSE, msg.getQRFlag());
EXPECT_EQ(Rcode::YXDOMAIN_CODE, msg.getRcode().getCode());
ASSERT_EQ(1, msg.getRRCount(D2UpdateMessage::SECTION_ZONE));
// Zone section is TBD
ASSERT_EQ(2, msg.getRRCount(D2UpdateMessage::SECTION_PREREQUISITE));
RRsetIterator rrset_it = msg.beginSection(D2UpdateMessage::SECTION_PREREQUISITE);
RRsetPtr prereq1 = *rrset_it;
ASSERT_TRUE(prereq1);
EXPECT_EQ("foo.example.com.", prereq1->getName().toText());
EXPECT_EQ(RRType::AAAA().getCode(), prereq1->getType().getCode());
EXPECT_EQ(RRClass::NONE().getCode(), prereq1->getClass().getCode());
EXPECT_EQ(0, prereq1->getTTL().getValue());
EXPECT_EQ(0, prereq1->getRdataCount());
// Move to next prerequisite section.
++rrset_it;
RRsetPtr prereq2 = *rrset_it;
ASSERT_TRUE(prereq2);
EXPECT_EQ("bar.example.com.", prereq2->getName().toText());
EXPECT_EQ(RRType::AAAA().getCode(), prereq2->getType().getCode());
EXPECT_EQ(RRClass::ANY().getCode(), prereq2->getClass().getCode());
EXPECT_EQ(0, prereq2->getTTL().getValue());
EXPECT_EQ(0, prereq2->getRdataCount());
ASSERT_EQ(1, msg.getRRCount(D2UpdateMessage::SECTION_UPDATE));
rrset_it = msg.beginSection(D2UpdateMessage::SECTION_UPDATE);
RRsetPtr update = *rrset_it;
ASSERT_TRUE(update);
EXPECT_EQ("foo.example.com.", update->getName().toText());
EXPECT_EQ(RRType::AAAA().getCode(), update->getType().getCode());
EXPECT_EQ(RRClass::IN().getCode(), update->getClass().getCode());
EXPECT_EQ(0xAABBCCDD, update->getTTL().getValue());
ASSERT_EQ(1, update->getRdataCount());
RdataIteratorPtr rdata_it = update->getRdataIterator();
ASSERT_TRUE(rdata_it);
in::AAAA rdata_ref("2001:db8:1::1");
EXPECT_EQ(0, rdata_ref.compare(rdata_it->getCurrent()));
}
// This test verifies that the wire format of the message is produced
// in the render mode.
TEST_F(D2UpdateMessageTest, toWire) {
......
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