BIND 10 trac2491, updated. 372f3a19f5bad9ed51e50d083063fccbe1ff6900 [2491] Create Status Code option using an option definition.
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Dec 3 15:55:25 UTC 2012
The branch, trac2491 has been updated
via 372f3a19f5bad9ed51e50d083063fccbe1ff6900 (commit)
via a0662ae5601ee75f3e99b2b53d4f3376b5e6a037 (commit)
from 10e87104e0b7977804c8c55275a403602dcbb2e5 (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 372f3a19f5bad9ed51e50d083063fccbe1ff6900
Author: Marcin Siodelski <marcin at isc.org>
Date: Mon Dec 3 16:55:16 2012 +0100
[2491] Create Status Code option using an option definition.
commit a0662ae5601ee75f3e99b2b53d4f3376b5e6a037
Author: Marcin Siodelski <marcin at isc.org>
Date: Mon Dec 3 16:10:01 2012 +0100
[2491] Added unit test to check overriding record field values.
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp6/dhcp6_srv.cc | 20 +++++---
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 21 +++++++--
src/lib/dhcp/option_custom.cc | 12 ++++-
src/lib/dhcp/option_definition.cc | 2 +-
src/lib/dhcp/option_definition.h | 2 +-
src/lib/dhcp/tests/option_custom_unittest.cc | 64 ++++++++++++++++++++++++++
6 files changed, 106 insertions(+), 15 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 02c0dd0..bd3675b 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -24,6 +24,7 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_int_array.h>
+#include <dhcp/option_custom.h>
#include <dhcp/pkt6.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/dhcp6_srv.h>
@@ -348,13 +349,18 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer)
}
OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
-
- // @todo: Implement Option6_StatusCode and rewrite this code here
- vector<uint8_t> data(text.c_str(), text.c_str() + text.length());
- data.insert(data.begin(), static_cast<uint8_t>(code % 256));
- data.insert(data.begin(), static_cast<uint8_t>(code >> 8));
- OptionPtr status(new Option(Option::V6, D6O_STATUS_CODE, data));
- return (status);
+ OptionDefinitionPtr status_code_def =
+ LibDHCP::getOptionDef(Option::V6, D6O_STATUS_CODE);
+ assert(status_code_def);
+
+ boost::shared_ptr<OptionCustom> option_status =
+ boost::dynamic_pointer_cast<
+ OptionCustom>(status_code_def->optionFactory(Option::V6, D6O_STATUS_CODE));
+ assert(option_status);
+
+ option_status->writeInteger<uint16_t>(code, 0);
+ option_status->writeString(text, 1);
+ return (option_status);
}
Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 335fb7b..6a598eb 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -801,12 +801,23 @@ TEST_F(Dhcpv6SrvTest, StatusCode) {
ASSERT_NO_THROW( srv.reset(new NakedDhcpv6Srv(0)) );
// a dummy content for client-id
- uint8_t expected[] = {0x0, 0x3, 0x41, 0x42, 0x43, 0x44, 0x45};
- OptionBuffer exp(expected, expected + sizeof(expected));
-
+ uint8_t expected[] = {
+ 0x0, 0xD, // option code = 14
+ 0x0, 0x7, // option length = 7
+ 0x0, 0x3, // status code = 3
+ 0x41, 0x42, 0x43, 0x44, 0x45 // string value ABCDE
+ };
+ // Create the option.
OptionPtr status = srv->createStatusCode(3, "ABCDE");
-
- EXPECT_TRUE(status->getData() == exp);
+ // Allocate an output buffer. We will store the option
+ // in wire format here.
+ OutputBuffer buf(sizeof(expected));
+ // Prepare the wire format.
+ ASSERT_NO_THROW(status->pack(buf));
+ // Check that the option buffer has valid length (option header + data).
+ ASSERT_EQ(sizeof(expected), buf.getLength());
+ // Verify the contents of the option.
+ EXPECT_EQ(0, memcmp(expected, buf.getData(), sizeof(expected)));
}
// This test verifies if the selectSubnet() method works as expected.
diff --git a/src/lib/dhcp/option_custom.cc b/src/lib/dhcp/option_custom.cc
index 3aece6c..dccac84 100644
--- a/src/lib/dhcp/option_custom.cc
+++ b/src/lib/dhcp/option_custom.cc
@@ -32,7 +32,17 @@ OptionCustom::OptionCustom(const OptionDefinition& def,
const OptionBuffer& data)
: Option(u, def.getCode(), data.begin(), data.end()),
definition_(def) {
- createBuffers(data_);
+ // It is possible that no data is provided if an option
+ // is being created on a server side. In such case a bunch
+ // of buffers with default values is first created and then
+ // the values are replaced using writeXXX functions. Thus
+ // we need to detect that no data has been specified and
+ // take a different code path.
+ if (!data_.empty()) {
+ createBuffers(data_);
+ } else {
+ createBuffers();
+ }
}
OptionCustom::OptionCustom(const OptionDefinition& def,
diff --git a/src/lib/dhcp/option_definition.cc b/src/lib/dhcp/option_definition.cc
index 1d1d75b..434c6a2 100644
--- a/src/lib/dhcp/option_definition.cc
+++ b/src/lib/dhcp/option_definition.cc
@@ -136,7 +136,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
return (factoryIAAddr6(type, begin, end));
}
}
- return (OptionPtr(new OptionCustom(*this, u, begin, end)));
+ return (OptionPtr(new OptionCustom(*this, u, OptionBuffer(begin, end))));
} catch (const Exception& ex) {
isc_throw(InvalidOptionValue, ex.what());
diff --git a/src/lib/dhcp/option_definition.h b/src/lib/dhcp/option_definition.h
index 3d48ef2..ca40428 100644
--- a/src/lib/dhcp/option_definition.h
+++ b/src/lib/dhcp/option_definition.h
@@ -246,7 +246,7 @@ public:
/// @throw MalformedOptionDefinition if option definition is invalid.
/// @throw InvalidOptionValue if data for the option is invalid.
OptionPtr optionFactory(Option::Universe u, uint16_t type,
- const OptionBuffer& buf) const;
+ const OptionBuffer& buf = OptionBuffer()) const;
/// @brief Option factory.
///
diff --git a/src/lib/dhcp/tests/option_custom_unittest.cc b/src/lib/dhcp/tests/option_custom_unittest.cc
index 5b8cf79..562336e 100644
--- a/src/lib/dhcp/tests/option_custom_unittest.cc
+++ b/src/lib/dhcp/tests/option_custom_unittest.cc
@@ -1129,6 +1129,70 @@ TEST_F(OptionCustomTest, setIpv6AddressDataArray) {
);
}
+TEST_F(OptionCustomTest, setRecordData) {
+ OptionDefinition opt_def("OPTION_FOO", 1000, "record");
+
+ ASSERT_NO_THROW(opt_def.addRecordField("uint16"));
+ ASSERT_NO_THROW(opt_def.addRecordField("boolean"));
+ ASSERT_NO_THROW(opt_def.addRecordField("fqdn"));
+ ASSERT_NO_THROW(opt_def.addRecordField("ipv4-address"));
+ ASSERT_NO_THROW(opt_def.addRecordField("ipv6-address"));
+ ASSERT_NO_THROW(opt_def.addRecordField("string"));
+
+ // Create an option and let the data field be initialized
+ // to default value (do not provide any data buffer).
+ boost::scoped_ptr<OptionCustom> option;
+ ASSERT_NO_THROW(
+ option.reset(new OptionCustom(opt_def, Option::V6));
+ );
+ ASSERT_TRUE(option);
+
+ // The number of elements should be equal to number of elements
+ // in the record.
+ ASSERT_EQ(6, option->getDataFieldsNum());
+
+ // Check that the default values have been correctly set.
+ uint16_t value0;
+ ASSERT_NO_THROW(value0 = option->readInteger<uint16_t>(0));
+ EXPECT_EQ(0, value0);
+ bool value1 = true;
+ ASSERT_NO_THROW(value1 = option->readBoolean(1));
+ EXPECT_FALSE(value1);
+ std::string value2;
+ ASSERT_NO_THROW(value2 = option->readFqdn(2));
+ EXPECT_EQ(".", value2);
+ IOAddress value3("127.0.0.1");
+ ASSERT_NO_THROW(value3 = option->readAddress(3));
+ EXPECT_EQ("0.0.0.0", value3.toText());
+ IOAddress value4("2001:db8:1::1");
+ ASSERT_NO_THROW(value4 = option->readAddress(4));
+ EXPECT_EQ("::", value4.toText());
+ std::string value5 = "xyz";
+ ASSERT_NO_THROW(value5 = option->readString(5));
+ EXPECT_TRUE(value5.empty());
+
+ // Override each value with a new value.
+ ASSERT_NO_THROW(option->writeInteger<uint16_t>(1234, 0));
+ ASSERT_NO_THROW(option->writeBoolean(true, 1));
+ ASSERT_NO_THROW(option->writeFqdn("example.com", 2));
+ ASSERT_NO_THROW(option->writeAddress(IOAddress("192.168.0.1"), 3));
+ ASSERT_NO_THROW(option->writeAddress(IOAddress("2001:db8:1::100"), 4));
+ ASSERT_NO_THROW(option->writeString("hello world", 5));
+
+ // Check that the new values have been correctly set.
+ ASSERT_NO_THROW(value0 = option->readInteger<uint16_t>(0));
+ EXPECT_EQ(1234, value0);
+ ASSERT_NO_THROW(value1 = option->readBoolean(1));
+ EXPECT_TRUE(value1);
+ ASSERT_NO_THROW(value2 = option->readFqdn(2));
+ EXPECT_EQ("example.com.", value2);
+ ASSERT_NO_THROW(value3 = option->readAddress(3));
+ EXPECT_EQ("192.168.0.1", value3.toText());
+ ASSERT_NO_THROW(value4 = option->readAddress(4));
+ EXPECT_EQ("2001:db8:1::100", value4.toText());
+ ASSERT_NO_THROW(value5 = option->readString(5));
+ EXPECT_EQ(value5, "hello world");
+}
// The purpose of this test is to verify that pack function for
// DHCPv4 custom option works correctly.
More information about the bind10-changes
mailing list