2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-01 06:25:34 +00:00

[#3074] introduce new OPT_CUSTOM_TYPE

This commit is contained in:
Piotrek Zadroga
2023-11-21 22:09:26 +01:00
parent e936f2d376
commit 475a349a16
7 changed files with 108 additions and 86 deletions

View File

@@ -18,8 +18,10 @@ namespace isc {
namespace dhcp { namespace dhcp {
OptionClasslessStaticRoute::OptionClasslessStaticRoute(OptionBufferConstIter begin, OptionClasslessStaticRoute::OptionClasslessStaticRoute(OptionBufferConstIter begin,
OptionBufferConstIter end) OptionBufferConstIter end,
: Option(V4, DHO_CLASSLESS_STATIC_ROUTE), static_routes_(), data_len_(0) { bool convenient_notation)
: Option(V4, DHO_CLASSLESS_STATIC_ROUTE), static_routes_(), data_len_(0),
convenient_notation_(convenient_notation) {
unpack(begin, end); unpack(begin, end);
} }
@@ -51,30 +53,17 @@ OptionClasslessStaticRoute::unpack(OptionBufferConstIter begin, OptionBufferCons
<< ", must be at least 5."); << ", must be at least 5.");
} }
// As an alternative to the binary format, if (convenient_notation_) {
// we provide convenience option definition as a string in format: // As an alternative to the binary format,
// subnet1 - router1 IP addr, subnet2 - router2 IP addr, ... // we provide convenience option definition as a string in format:
// e.g.: // subnet1 - router1 IP addr, subnet2 - router2 IP addr, ...
// 10.0.0.0/8 - 10.2.3.1, 10.229.0.128/25 - 10.1.0.3, ... // e.g.:
// where destination descriptors will be encoded as per RFC3442. // 10.0.0.0/8 - 10.2.3.1, 10.229.0.128/25 - 10.1.0.3, ...
// We need to determine if OptionBuffer contains dash `-` separator (0x2d). // where destination descriptors will be encoded as per RFC3442.
// If not, we assume this is binary format.
auto begin_copy = begin;
while (begin_copy != end) {
if (*begin_copy == '-') {
break;
}
++begin_copy;
}
if (begin_copy == end) {
// no separator found, assuming this is a hex on-wire data
parseWireData(begin, end);
} else {
// separator was found, assuming this is option data string from config
std::string config_txt = std::string(begin, end); std::string config_txt = std::string(begin, end);
parseConfigData(config_txt); parseConfigData(config_txt);
} else {
parseWireData(begin, end);
} }
calcDataLen(); calcDataLen();

View File

@@ -22,7 +22,8 @@ class OptionClasslessStaticRoute : public Option {
public: public:
/// @brief Empty Constructor /// @brief Empty Constructor
OptionClasslessStaticRoute() OptionClasslessStaticRoute()
: Option(V4, DHO_CLASSLESS_STATIC_ROUTE), static_routes_(), data_len_(0) { : Option(V4, DHO_CLASSLESS_STATIC_ROUTE), static_routes_(), data_len_(0),
convenient_notation_(false) {
} }
/// @brief Constructor of the %Option from on-wire data. /// @brief Constructor of the %Option from on-wire data.
@@ -33,7 +34,10 @@ public:
/// @param begin Iterator pointing to the beginning of the buffer holding an /// @param begin Iterator pointing to the beginning of the buffer holding an
/// option. /// option.
/// @param end Iterator pointing to the end of the buffer holding an option. /// @param end Iterator pointing to the end of the buffer holding an option.
OptionClasslessStaticRoute(OptionBufferConstIter begin, OptionBufferConstIter end); /// @param convenient_notation
OptionClasslessStaticRoute(OptionBufferConstIter begin,
OptionBufferConstIter end,
bool convenient_notation = false);
/// @brief Copies this option and returns a pointer to the copy. /// @brief Copies this option and returns a pointer to the copy.
/// ///
@@ -83,6 +87,9 @@ private:
/// @brief Length in octets of all encoded static routes. /// @brief Length in octets of all encoded static routes.
uint16_t data_len_; uint16_t data_len_;
/// @brief
bool convenient_notation_;
/// @brief Encodes destination descriptor as per RFC3442. /// @brief Encodes destination descriptor as per RFC3442.
/// @param route static route tuple /// @param route static route tuple
/// @return Contents of the destination descriptor as a vector /// @return Contents of the destination descriptor as a vector

View File

@@ -59,6 +59,7 @@ enum OptionDataType {
OPT_STRING_TYPE, OPT_STRING_TYPE,
OPT_TUPLE_TYPE, OPT_TUPLE_TYPE,
OPT_FQDN_TYPE, OPT_FQDN_TYPE,
OPT_CUSTOM_TYPE,
OPT_RECORD_TYPE, OPT_RECORD_TYPE,
OPT_UNKNOWN_TYPE OPT_UNKNOWN_TYPE
}; };

View File

@@ -33,6 +33,7 @@
#include <dns/name.h> #include <dns/name.h>
#include <util/strutil.h> #include <util/strutil.h>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/dynamic_bitset.hpp> #include <boost/dynamic_bitset.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
@@ -182,9 +183,11 @@ OptionDefinition::addRecordField(const OptionDataType data_type) {
} }
OptionPtr OptionPtr
OptionDefinition::optionFactory(Option::Universe u, uint16_t type, OptionDefinition::optionFactory(Option::Universe u,
uint16_t type,
OptionBufferConstIter begin, OptionBufferConstIter begin,
OptionBufferConstIter end) const { OptionBufferConstIter end,
bool custom_data) const {
try { try {
// Some of the options are represented by the specialized classes derived // Some of the options are represented by the specialized classes derived
@@ -193,7 +196,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
// type to be returned. Therefore, we first check that if we are dealing // type to be returned. Therefore, we first check that if we are dealing
// with such an option. If the instance is returned we just exit at this // with such an option. If the instance is returned we just exit at this
// point. If not, we will search for a generic option type to return. // point. If not, we will search for a generic option type to return.
OptionPtr option = factorySpecialFormatOption(u, begin, end); OptionPtr option = factorySpecialFormatOption(u, begin, end, custom_data);
if (option) { if (option) {
return (option); return (option);
} }
@@ -207,6 +210,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
} }
case OPT_BINARY_TYPE: case OPT_BINARY_TYPE:
case OPT_CUSTOM_TYPE:
return (factoryGeneric(u, type, begin, end)); return (factoryGeneric(u, type, begin, end));
case OPT_UINT8_TYPE: case OPT_UINT8_TYPE:
@@ -306,6 +310,8 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
if (type_ != OPT_EMPTY_TYPE) { if (type_ != OPT_EMPTY_TYPE) {
isc_throw(InvalidOptionValue, "no option value specified"); isc_throw(InvalidOptionValue, "no option value specified");
} }
} else if (type_ == OPT_CUSTOM_TYPE) {
writeToBuffer(u, boost::algorithm::join(values, ","), OPT_STRING_TYPE, buf);
} else { } else {
writeToBuffer(u, util::str::trim(values[0]), type_, buf); writeToBuffer(u, util::str::trim(values[0]), type_, buf);
} }
@@ -330,7 +336,7 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
} }
} }
} }
return (optionFactory(u, type, buf.begin(), buf.end())); return (optionFactory(u, type, buf.begin(), buf.end(), (type_ == OPT_CUSTOM_TYPE)));
} }
void void
@@ -824,7 +830,8 @@ OptionDefinition::factoryFqdnList(Option::Universe u,
OptionPtr OptionPtr
OptionDefinition::factorySpecialFormatOption(Option::Universe u, OptionDefinition::factorySpecialFormatOption(Option::Universe u,
OptionBufferConstIter begin, OptionBufferConstIter begin,
OptionBufferConstIter end) const { OptionBufferConstIter end,
bool custom_data) const {
if ((u == Option::V6) && haveSpace(DHCP6_OPTION_SPACE)) { if ((u == Option::V6) && haveSpace(DHCP6_OPTION_SPACE)) {
switch (getCode()) { switch (getCode()) {
case D6O_IA_NA: case D6O_IA_NA:
@@ -886,7 +893,7 @@ OptionDefinition::factorySpecialFormatOption(Option::Universe u,
return (OptionPtr(new Option4ClientFqdn(begin, end))); return (OptionPtr(new Option4ClientFqdn(begin, end)));
case DHO_CLASSLESS_STATIC_ROUTE: case DHO_CLASSLESS_STATIC_ROUTE:
return (OptionPtr(new OptionClasslessStaticRoute(begin, end))); return (OptionPtr(new OptionClasslessStaticRoute(begin, end, custom_data)));
case DHO_VIVCO_SUBOPTIONS: case DHO_VIVCO_SUBOPTIONS:
// Record of uint32 followed by binary. // Record of uint32 followed by binary.

View File

@@ -433,12 +433,15 @@ public:
/// @param type option type. /// @param type option type.
/// @param begin beginning of the option buffer. /// @param begin beginning of the option buffer.
/// @param end end of the option buffer. /// @param end end of the option buffer.
/// @param custom_data
/// ///
/// @return instance of the DHCP option. /// @return instance of the DHCP option.
/// @throw InvalidOptionValue if data for the option is invalid. /// @throw InvalidOptionValue if data for the option is invalid.
OptionPtr optionFactory(Option::Universe u, uint16_t type, OptionPtr optionFactory(Option::Universe u,
uint16_t type,
OptionBufferConstIter begin, OptionBufferConstIter begin,
OptionBufferConstIter end) const; OptionBufferConstIter end,
bool custom_data = false) const;
/// @brief Option factory. /// @brief Option factory.
/// ///
@@ -670,13 +673,15 @@ private:
/// @param u A universe (V4 or V6). /// @param u A universe (V4 or V6).
/// @param begin beginning of the option buffer. /// @param begin beginning of the option buffer.
/// @param end end of the option buffer. /// @param end end of the option buffer.
/// @param custom_data
/// ///
/// @return An instance of the option having special format or NULL if /// @return An instance of the option having special format or NULL if
/// such an option can't be created because an option with the given /// such an option can't be created because an option with the given
/// option code hasn't got the special format. /// option code hasn't got the special format.
OptionPtr factorySpecialFormatOption(Option::Universe u, OptionPtr factorySpecialFormatOption(Option::Universe u,
OptionBufferConstIter begin, OptionBufferConstIter begin,
OptionBufferConstIter end) const; OptionBufferConstIter end,
bool custom_data = false) const;
/// @brief Check if specified type matches option definition type. /// @brief Check if specified type matches option definition type.
/// ///

View File

@@ -332,7 +332,7 @@ const OptionDefParams STANDARD_V4_OPTION_DEFINITIONS[] = {
OPT_IPV4_ADDRESS_TYPE, false, NO_RECORD_DEF, "" }, OPT_IPV4_ADDRESS_TYPE, false, NO_RECORD_DEF, "" },
{ "domain-search", DHO_DOMAIN_SEARCH, DHCP4_OPTION_SPACE, OPT_FQDN_TYPE, { "domain-search", DHO_DOMAIN_SEARCH, DHCP4_OPTION_SPACE, OPT_FQDN_TYPE,
true, NO_RECORD_DEF, "" }, true, NO_RECORD_DEF, "" },
{ "classless-static-route", DHO_CLASSLESS_STATIC_ROUTE, DHCP4_OPTION_SPACE, OPT_BINARY_TYPE, { "classless-static-route", DHO_CLASSLESS_STATIC_ROUTE, DHCP4_OPTION_SPACE, OPT_CUSTOM_TYPE,
false, NO_RECORD_DEF, "" }, false, NO_RECORD_DEF, "" },
{ "vivco-suboptions", DHO_VIVCO_SUBOPTIONS, DHCP4_OPTION_SPACE, { "vivco-suboptions", DHO_VIVCO_SUBOPTIONS, DHCP4_OPTION_SPACE,
OPT_RECORD_TYPE, false, RECORD_DEF(VIVCO_RECORDS), "" }, OPT_RECORD_TYPE, false, RECORD_DEF(VIVCO_RECORDS), "" },

View File

@@ -79,12 +79,13 @@ TEST(OptionClasslessStaticRouteTest, emptyCtorAddMoreRoutes) {
// Only one static route is defined. // Only one static route is defined.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithOneRoute) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithOneRoute) {
// Prepare data to decode - one route with mask width = 8. // Prepare data to decode - one route with mask width = 8.
const std::string config = "'10.0.0.0/8 - 10.198.122.1'"; const std::string config = "10.0.0.0/8 - 10.198.122.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here. // Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end()))); EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)));
ASSERT_TRUE(option); ASSERT_TRUE(option);
// Expected len: 2 (option code + option len headers) + 6 (2 dest descriptor + 4 router addr). // Expected len: 2 (option code + option len headers) + 6 (2 dest descriptor + 4 router addr).
@@ -100,13 +101,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithOneRoute) {
// 3 static routes are defined. // 3 static routes are defined.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithMoreRoutes) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithMoreRoutes) {
// Prepare data to decode - 3 static routes // Prepare data to decode - 3 static routes
const std::string config = "'0.0.0.0/0 - 10.17.0.1,10.229.0.128/25-10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,10.229.0.128/25-10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here. // Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end()))); EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)));
ASSERT_TRUE(option); ASSERT_TRUE(option);
// Expected len: 2 (option code + option len headers) + 5 (1 dest descriptor + 4 router addr) // Expected len: 2 (option code + option len headers) + 5 (1 dest descriptor + 4 router addr)
@@ -125,13 +127,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorWithMoreRoutes) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingDash) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingDash) {
// Prepare data to decode - second route has missing dash separator // Prepare data to decode - second route has missing dash separator
const std::string config = "'0.0.0.0/0 - 10.17.0.1,10.229.0.128/25 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,10.229.0.128/25 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -140,13 +143,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingDash) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingPrefixLen) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingPrefixLen) {
// Prepare data to decode - second route has missing "/prefix len" // Prepare data to decode - second route has missing "/prefix len"
const std::string config = "'0.0.0.0/0 - 10.17.0.1,10.229.0.128 - 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,10.229.0.128 - 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -155,13 +159,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorMissingPrefixLen) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestIpV6Given) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestIpV6Given) {
// Prepare data to decode - second route has IPv6 prefix // Prepare data to decode - second route has IPv6 prefix
const std::string config = "'0.0.0.0/0 - 10.17.0.1,3001::5/64 - 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,3001::5/64 - 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -170,13 +175,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestIpV6Given) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestInvalidAddr) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestInvalidAddr) {
// Prepare data to decode - second route has invalid IP address // Prepare data to decode - second route has invalid IP address
const std::string config = "'0.0.0.0/0 - 10.17.0.1,1.2.3.a/32 - 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,1.2.3.a/32 - 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -185,13 +191,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDestInvalidAddr) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorInvalidPrefixLen) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorInvalidPrefixLen) {
// Prepare data to decode - second route has invalid prefix len // Prepare data to decode - second route has invalid prefix len
const std::string config = "'0.0.0.0/0 - 10.17.0.1,1.2.3.4/a - 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,1.2.3.4/a - 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -200,13 +207,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorInvalidPrefixLen) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorPrefixLenTooBig) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorPrefixLenTooBig) {
// Prepare data to decode - second route has prefix len too big for IPv4 // Prepare data to decode - second route has prefix len too big for IPv4
const std::string config = "'0.0.0.0/0 - 10.17.0.1,1.2.3.4/64 - 10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,1.2.3.4/64 - 10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -215,13 +223,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorPrefixLenTooBig) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterInvalidAddr) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterInvalidAddr) {
// Prepare data to decode - second route has invalid router IP address // Prepare data to decode - second route has invalid router IP address
const std::string config = "'0.0.0.0/0 - 10.17.0.1,1.2.3.4/31 - 10.229.0.a, " const std::string config = "0.0.0.0/0 - 10.17.0.1,1.2.3.4/31 - 10.229.0.a, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -230,13 +239,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterInvalidAddr) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterIpV6Given) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterIpV6Given) {
// Prepare data to decode - second route has IPv6 router address // Prepare data to decode - second route has IPv6 router address
const std::string config = "'0.0.0.0/0 - 10.17.0.1,1.2.3.4/31 - 3001::5, " const std::string config = "0.0.0.0/0 - 10.17.0.1,1.2.3.4/31 - 3001::5, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -245,13 +255,14 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorRouterIpV6Given) {
// when data in the buffer has wrong format. // when data in the buffer has wrong format.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorCommaMissing) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorCommaMissing) {
// Prepare data to decode - comma separators are missing // Prepare data to decode - comma separators are missing
const std::string config = "'0.0.0.0/0 - 10.17.0.1 1.2.3.4/31 - 1.2.3.4 " const std::string config = "0.0.0.0/0 - 10.17.0.1 1.2.3.4/31 - 1.2.3.4 "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws BadValue during Unpack. // Create option instance. Check that constructor throws BadValue during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::BadValue); isc::BadValue);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -260,12 +271,13 @@ TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorCommaMissing) {
// when data in the buffer is truncated. // when data in the buffer is truncated.
TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDataTruncated) { TEST(OptionClasslessStaticRouteTest, bufferFromStrCtorDataTruncated) {
// Prepare data to decode - truncated data // Prepare data to decode - truncated data
const std::string config = "'0.0.'"; const std::string config = "0.0.";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Create option instance. Check that constructor throws OutOfRange during Unpack. // Create option instance. Check that constructor throws OutOfRange during Unpack.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end())), EXPECT_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)),
isc::OutOfRange); isc::OutOfRange);
ASSERT_FALSE(option); ASSERT_FALSE(option);
} }
@@ -420,9 +432,10 @@ TEST(OptionClasslessStaticRouteTest, toText) {
// This test verifies pack() method // This test verifies pack() method
TEST(OptionClasslessStaticRouteTest, pack) { TEST(OptionClasslessStaticRouteTest, pack) {
// Prepare data to decode - 3 static routes // Prepare data to decode - 3 static routes
const std::string config = "'0.0.0.0/0 - 10.17.0.1,10.229.0.128/25-10.229.0.1, " const std::string config = "0.0.0.0/0 - 10.17.0.1,10.229.0.128/25-10.229.0.1, "
"10.27.129.0/24 - 10.27.129.1'"; "10.27.129.0/24 - 10.27.129.1";
OptionBuffer buf = isc::util::str::quotedStringToBinary(config); OptionBuffer buf;
buf.assign(config.begin(), config.end());
// Prepare expected packed data // Prepare expected packed data
const uint8_t ref_data[] = { const uint8_t ref_data[] = {
@@ -442,7 +455,7 @@ TEST(OptionClasslessStaticRouteTest, pack) {
// Create option instance. Check that constructor doesn't throw. Unpack is also tested here. // Create option instance. Check that constructor doesn't throw. Unpack is also tested here.
OptionClasslessStaticRoutePtr option; OptionClasslessStaticRoutePtr option;
EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end()))); EXPECT_NO_THROW(option.reset(new OptionClasslessStaticRoute(buf.begin(), buf.end(), true)));
ASSERT_TRUE(option); ASSERT_TRUE(option);
// Prepare on-wire format of the option. // Prepare on-wire format of the option.