BIND 10 trac2976, updated. 5eea9d893ec4ac21e89f8b3b0f3e68af625eed48 [2976] Updated doxygen documentation for D2UpdateMessage class.
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jun 26 09:58:47 UTC 2013
The branch, trac2976 has been updated
via 5eea9d893ec4ac21e89f8b3b0f3e68af625eed48 (commit)
via 5d9916e93986dbeb890cbce2782d67b9f535adb4 (commit)
from a63b3077dd102512b9002e204a955f5b8d783ff4 (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 5eea9d893ec4ac21e89f8b3b0f3e68af625eed48
Author: Marcin Siodelski <marcin at isc.org>
Date: Wed Jun 26 11:58:21 2013 +0200
[2976] Updated doxygen documentation for D2UpdateMessage class.
commit 5d9916e93986dbeb890cbce2782d67b9f535adb4
Author: Marcin Siodelski <marcin at isc.org>
Date: Wed Jun 26 11:56:44 2013 +0200
[2976] Added negative test cases for fromWire function.
Also, some of the comments have been improved in unit tests.
-----------------------------------------------------------------------
Summary of changes:
src/bin/d2/d2_update_message.cc | 12 ++-
src/bin/d2/d2_update_message.h | 20 +++-
src/bin/d2/tests/d2_update_message_unittests.cc | 130 ++++++++++++++++++++++-
3 files changed, 155 insertions(+), 7 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/d2/d2_update_message.cc b/src/bin/d2/d2_update_message.cc
index f1b2de2..16656e3 100644
--- a/src/bin/d2/d2_update_message.cc
+++ b/src/bin/d2/d2_update_message.cc
@@ -160,20 +160,26 @@ D2UpdateMessage::fromWire(isc::util::InputBuffer& buffer) {
dns::Message::Section
D2UpdateMessage::ddnsToDnsSection(const UpdateMsgSection section) {
+ /// The following switch maps the enumerator values from the
+ /// DNS Update message to the corresponding enumerator values
+ /// representing fields of the DNS message.
switch(section) {
case SECTION_ZONE :
return (dns::Message::SECTION_QUESTION);
+
case SECTION_PREREQUISITE:
return (dns::Message::SECTION_ANSWER);
+
case SECTION_UPDATE:
return (dns::Message::SECTION_AUTHORITY);
+
case SECTION_ADDITIONAL:
return (dns::Message::SECTION_ADDITIONAL);
+
default:
;
}
- isc_throw(dns::InvalidMessageSection,
- "unknown message section " << section);
+ isc_throw(dns::InvalidMessageSection, "unknown message section " << section);
}
void
@@ -190,7 +196,7 @@ D2UpdateMessage::validate() const {
// Received message should have QR flag set, which indicates that it is
// a RESPONSE.
if (getQRFlag() == REQUEST) {
- isc_throw(NotUpdateMessage, "received message should should have QR flag set,"
+ isc_throw(InvalidQRFlag, "received message should should have QR flag set,"
" to indicate that it is a RESPONSE message, the QR flag is unset");
}
// DNS server may copy a Zone record from the query message. Since query must
diff --git a/src/bin/d2/d2_update_message.h b/src/bin/d2/d2_update_message.h
index 784a7fe..3ad393d 100644
--- a/src/bin/d2/d2_update_message.h
+++ b/src/bin/d2/d2_update_message.h
@@ -223,8 +223,7 @@ public:
/// @param rrset A reference to a RRset which should be added.
void addRRset(const UpdateMsgSection section, const dns::RRsetPtr& rrset);
-
- /// @name Functions to handle messages encoding and decoding.
+ /// @name Functions to handle message encoding and decoding.
///
//@{
/// @brief Encode outgoing message into wire format.
@@ -272,7 +271,6 @@ public:
//@}
private:
-
/// Maps the values of the @c UpdateMessageSection field to the
/// corresponding values in the @c isc::dns::Message class. This
/// mapping is required here because this class uses @c isc::dns::Message
@@ -284,6 +282,22 @@ private:
/// @return The enum value indicating the section in the DNS message
/// represented by the @c isc::dns::Message class.
static dns::Message::Section ddnsToDnsSection(const UpdateMsgSection section);
+
+ /// @brief Checks received response message for correctness.
+ ///
+ /// This function verifies that the received response from a server is
+ /// correct. Currently this function checks the following:
+ /// - Opcode is 'DNS Update',
+ /// - QR flag is RESPONSE (flag bit is set),
+ /// - Zone section comprises at most one record.
+ ///
+ /// The function will throw exception if any of the conditions above are
+ /// not met.
+ ///
+ /// @throw isc::d2::NotUpdateMessage if invalid Opcode.
+ /// @throw isc::d2::InvalidQRFlag if QR flag is not set to RESPONSE
+ /// @throw isc::d2::InvalidZone section, if Zone section comprises more
+ /// than one record.
void validate() const;
dns::Message message_;
diff --git a/src/bin/d2/tests/d2_update_message_unittests.cc b/src/bin/d2/tests/d2_update_message_unittests.cc
index 3883fc7..de6f93c 100644
--- a/src/bin/d2/tests/d2_update_message_unittests.cc
+++ b/src/bin/d2/tests/d2_update_message_unittests.cc
@@ -79,8 +79,10 @@ public:
// This test verifies that DNS Update message ID can be set using
// setId function.
TEST_F(D2UpdateMessageTest, setId) {
+ // Message ID is initialized to 0.
D2UpdateMessage msg;
EXPECT_EQ(0, msg.getId());
+ // Override the default value and verify that it has been set.
msg.setId(0x1234);
EXPECT_EQ(0x1234, msg.getId());
}
@@ -89,9 +91,11 @@ TEST_F(D2UpdateMessageTest, setId) {
// using setRcode function.
TEST_F(D2UpdateMessageTest, setRcode) {
D2UpdateMessage msg;
+ // Rcode must be explicitly set before it is accessed.
msg.setRcode(Rcode::NOERROR());
EXPECT_EQ(Rcode::NOERROR().getCode(), msg.getRcode().getCode());
-
+ // Let's override current value to make sure that getter does
+ // not return fixed value.
msg.setRcode(Rcode::NOTIMP());
EXPECT_EQ(Rcode::NOTIMP().getCode(), msg.getRcode().getCode());
}
@@ -100,14 +104,19 @@ TEST_F(D2UpdateMessageTest, setRcode) {
// can be set.
TEST_F(D2UpdateMessageTest, setZone) {
D2UpdateMessage msg;
+ // The zone pointer is initialized to NULL.
D2ZonePtr zone = msg.getZone();
EXPECT_FALSE(zone);
+ // Let's create a new Zone and check that it is returned
+ // via getter.
msg.setZone(Name("example.com"), RRClass::ANY());
zone = msg.getZone();
EXPECT_TRUE(zone);
EXPECT_EQ("example.com.", zone->getName().toText());
EXPECT_EQ(RRClass::ANY().getCode(), zone->getClass().getCode());
+ // Now, let's check that the existing Zone object can be
+ // overriden with a new one.
msg.setZone(Name("foo.example.com"), RRClass::NONE());
zone = msg.getZone();
EXPECT_TRUE(zone);
@@ -259,6 +268,93 @@ TEST_F(D2UpdateMessageTest, fromWire) {
// consider implementing tests for it in the future.
}
+// This test verifies that the fromWire function throws appropriate exception
+// if the message being parsed comprises invalid Opcode (is not a DNS Update).
+TEST_F(D2UpdateMessageTest, fromWireInvalidOpcode) {
+ // This is a binary representation of the DNS message.
+ // It comprises invalid Opcode=3, expected value is 6
+ // (Update).
+ const uint8_t bin_msg[] = {
+ 0x05, 0xAF, // ID=0x05AF
+ 0x98, 0x6, // QR=1, Opcode=3, RCODE=YXDOMAIN
+ 0x0, 0x0, // ZOCOUNT=0
+ 0x0, 0x0, // PRCOUNT=0
+ 0x0, 0x0, // UPCOUNT=0
+ 0x0, 0x0 // ADCOUNT=0
+ };
+ InputBuffer buf(bin_msg, sizeof(bin_msg));
+ // The 'true' argument passed to the constructor turns the
+ // message into the parse mode in which the fromWire function
+ // can be used to decode the binary mesasage data.
+ D2UpdateMessage msg(true);
+ // When using invalid Opcode, the fromWire function should
+ // throw NotUpdateMessage exception.
+ EXPECT_THROW(msg.fromWire(buf), isc::d2::NotUpdateMessage);
+}
+
+// This test verifies that the fromWire function throws appropriate exception
+// if the message being parsed comprises invalid QR flag. The QR bit is
+// expected to be set to indicate that the message is a RESPONSE.
+TEST_F(D2UpdateMessageTest, fromWireInvalidQRFlag) {
+ // This is a binary representation of the DNS message.
+ // It comprises invalid QR flag = 0.
+ const uint8_t bin_msg[] = {
+ 0x05, 0xAF, // ID=0x05AF
+ 0x28, 0x6, // QR=0, Opcode=6, RCODE=YXDOMAIN
+ 0x0, 0x0, // ZOCOUNT=0
+ 0x0, 0x0, // PRCOUNT=0
+ 0x0, 0x0, // UPCOUNT=0
+ 0x0, 0x0 // ADCOUNT=0
+ };
+ InputBuffer buf(bin_msg, sizeof(bin_msg));
+ // The 'true' argument passed to the constructor turns the
+ // message into the parse mode in which the fromWire function
+ // can be used to decode the binary mesasage data.
+ D2UpdateMessage msg(true);
+ // When using invalid QR flag, the fromWire function should
+ // throw InvalidQRFlag exception.
+ EXPECT_THROW(msg.fromWire(buf), isc::d2::InvalidQRFlag);
+}
+
+// This test verifies that the fromWire function throws appropriate exception
+// if the message being parsed comprises more than one (two in this case)
+// Zone records.
+TEST_F(D2UpdateMessageTest, fromWireTooManyZones) {
+ // This is a binary representation of the DNS message. This message
+ // comprises two Zone records.
+ const uint8_t bin_msg[] = {
+ 0x05, 0xAF, // ID=0x05AF
+ 0xA8, 0x6, // QR=1, Opcode=6, RCODE=YXDOMAIN
+ 0x0, 0x2, // ZOCOUNT=2
+ 0x0, 0x0, // PRCOUNT=0
+ 0x0, 0x0, // UPCOUNT=0
+ 0x0, 0x0, // ADCOUNT=0
+
+ // Start first Zone record.
+ 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'
+
+ // Start second Zone record. Presence of this record should result
+ // in error when parsing this message.
+ 0x3, 0x63, 0x6F, 0x6D, // com. (0x3 is a length)
+ 0x0, // NULL character terminates the Zone name.
+ 0x0, 0x6, // ZTYPE='SOA'
+ 0x0, 0x1 // ZCLASS='IN'
+ };
+ InputBuffer buf(bin_msg, sizeof(bin_msg));
+
+ // The 'true' argument passed to the constructor turns the
+ // message into the parse mode in which the fromWire function
+ // can be used to decode the binary mesasage data.
+ D2UpdateMessage msg(true);
+ // When parsing a message with more than one Zone record,
+ // exception should be thrown.
+ EXPECT_THROW(msg.fromWire(buf), isc::d2::InvalidZoneSection);
+}
+
// This test verifies that the wire format of the message is produced
// in the render mode.
TEST_F(D2UpdateMessageTest, toWire) {
@@ -455,4 +551,36 @@ TEST_F(D2UpdateMessageTest, toWire) {
// section.
}
+// This test verifies that an attempt to call toWire function on the
+// received message will result in an exception.
+TEST_F(D2UpdateMessageTest, toWireInvalidQRFlag) {
+ // This is a binary representation of the DNS message.
+ // This message is valid and should be parsed with no
+ // error.
+ const uint8_t bin_msg[] = {
+ 0x05, 0xAF, // ID=0x05AF
+ 0xA8, 0x6, // QR=1, Opcode=6, RCODE=YXDOMAIN
+ 0x0, 0x0, // ZOCOUNT=0
+ 0x0, 0x0, // PRCOUNT=0
+ 0x0, 0x0, // UPCOUNT=0
+ 0x0, 0x0 // ADCOUNT=0
+ };
+
+ InputBuffer buf(bin_msg, sizeof(bin_msg));
+ // The 'true' argument passed to the constructor turns the
+ // message into the parse mode in which the fromWire function
+ // can be used to decode the binary mesasage data.
+ D2UpdateMessage msg(true);
+ ASSERT_NO_THROW(msg.fromWire(buf));
+
+ // The message is parsed. The QR Flag should now indicate that
+ // it is a Response message.
+ ASSERT_EQ(D2UpdateMessage::RESPONSE, msg.getQRFlag());
+
+ // An attempt to call toWire on the Response message should
+ // result in the InvalidQRFlag exception.
+ MessageRenderer renderer;
+ EXPECT_THROW(msg.toWire(renderer), isc::d2::InvalidQRFlag);
+}
+
} // End of anonymous namespace
More information about the bind10-changes
mailing list