2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

[#2536] Implementing DNRv4v6 Option with TDD

This commit is contained in:
Piotrek Zadroga
2023-04-20 13:49:56 +02:00
parent 2b9f19ceae
commit 5f3e779760
6 changed files with 340 additions and 44 deletions

View File

@@ -6,15 +6,10 @@
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcp/dhcp4.h>
#include <dhcp/dhcp6.h>
#include <dhcp/opaque_data_tuple.h>
#include <dhcp/option4_dnr.h>
#include <dhcp/option6_dnr.h>
#include <dhcp/option_data_types.h>
#include <dns/labelsequence.h>
#include <util/strutil.h>
#include <set>
using namespace isc::asiolink;
@@ -34,7 +29,7 @@ Option4Dnr::clone() const {
}
void
Option4Dnr::pack(util::OutputBuffer& buf, bool check) const {
Option4Dnr::pack(OutputBuffer& buf, bool check) const {
packHeader(buf, check);
for (const DnrInstance& dnr_instance : dnr_instances_) {
buf.writeUint16(dnr_instance.getDnrInstanceDataLength());
@@ -62,7 +57,7 @@ Option4Dnr::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
}
// Unpack DnrInstanceDataLength.
dnr_instance.unpackDnrInstanceDataLength(begin);
dnr_instance.unpackDnrInstanceDataLength(begin, end);
const OptionBufferConstIter dnr_instance_end = begin +
dnr_instance.getDnrInstanceDataLength();
@@ -413,9 +408,15 @@ DnrInstance::addIpAddress(const IOAddress& ip_address) {
}
void
DnrInstance::unpackDnrInstanceDataLength(OptionBufferConstIter& begin) {
DnrInstance::unpackDnrInstanceDataLength(OptionBufferConstIter& begin, OptionBufferConstIter end) {
dnr_instance_data_length_ = readUint16(&*begin, getDnrInstanceDataLengthSize());
begin += getDnrInstanceDataLengthSize();
if (std::distance(begin, end) < dnr_instance_data_length_) {
isc_throw(OutOfRange, getLogPrefix()
<< " malformed: DNR instance data truncated to size "
<< std::distance(begin, end) << " but it was supposed to be "
<< dnr_instance_data_length_);
}
}
void
@@ -438,8 +439,9 @@ DnrInstance::unpackAddresses(OptionBufferConstIter& begin, const OptionBufferCon
// If additional data is supplied (i.e. not ADN only mode),
// the option includes at least one valid IP address.
if (addr_length_ == 0) {
isc_throw(OutOfRange, getLogPrefix() << " malformed: Addr Len=" << addr_length_
<< " is not greater than 0");
isc_throw(OutOfRange, getLogPrefix()
<< " malformed: Addr Len=" << addr_length_
<< " but it must contain at least one valid IP address");
}
begin += getAddrLengthSize();

View File

@@ -9,12 +9,30 @@
#include <asiolink/io_address.h>
#include <dhcp/dhcp4.h>
#include <dhcp/dhcp6.h>
#include <dhcp/option.h>
#include <dhcp/option_data_types.h>
#include <dns/name.h>
namespace isc {
namespace dhcp {
/// @brief Exception thrown when invalid domain name is specified.
class InvalidOptionDnrDomainName : public Exception {
public:
InvalidOptionDnrDomainName(const char* file, size_t line, const char* what)
: isc::Exception(file, line, what) {
}
};
/// @brief Exception thrown when Service parameters have wrong format.
class InvalidOptionDnrSvcParams : public Exception {
public:
InvalidOptionDnrSvcParams(const char* file, size_t line, const char* what)
: isc::Exception(file, line, what) {
}
};
/// @brief Represents DNR Instance which is used both in DHCPv4
/// and DHCPv6 Encrypted DNS %Option.
///
@@ -208,24 +226,37 @@ public:
/// @brief Unpacks DNR Instance Data Length from wire data buffer and stores
/// it in @c dnr_instance_data_length_.
///
/// It may throw in case of malformed data detected during parsing.
///
/// @param begin beginning of the buffer from which the field will be read
void unpackDnrInstanceDataLength(OptionBufferConstIter& begin);
/// @param end end of the buffer from which the field will be read
void unpackDnrInstanceDataLength(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks Service Priority from wire data buffer and stores it in @c service_priority_.
/// @param begin beginning of the buffer from which the field will be read
void unpackServicePriority(OptionBufferConstIter& begin);
/// @brief Unpacks the ADN from given wire data buffer and stores it in @c adn_ field.
///
/// It may throw in case of malformed data detected during parsing.
///
/// @param begin beginning of the buffer from which the ADN will be read
/// @param end end of the buffer from which the ADN will be read
void unpackAdn(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks IP address(es) from wire data and stores it/them in @c ip_addresses_.
///
/// It may throw in case of malformed data detected during parsing.
///
/// @param begin beginning of the buffer from which the field will be read
/// @param end end of the buffer from which the field will be read
virtual void unpackAddresses(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks Service Parameters from wire data buffer and stores it in @c svc_params_.
///
/// It may throw in case of malformed data detected during parsing.
///
/// @param begin beginning of the buffer from which the field will be read
/// @param end end of the buffer from which the field will be read
void unpackSvcParams(OptionBufferConstIter& begin, OptionBufferConstIter end);

View File

@@ -6,8 +6,6 @@
#include <config.h>
#include <dhcp/dhcp6.h>
#include <dhcp/opaque_data_tuple.h>
#include <dhcp/option6_dnr.h>
using namespace isc::asiolink;
@@ -111,8 +109,9 @@ Option6Dnr::unpackAddresses(OptionBufferConstIter& begin, OptionBufferConstIter
// If additional data is supplied (i.e. not ADN only mode),
// the option includes at least one valid IP address.
if (addr_length_ == 0) {
isc_throw(OutOfRange, getLogPrefix() << " malformed: Addr Len=" << addr_length_
<< " is not greater than 0");
isc_throw(OutOfRange, getLogPrefix()
<< " malformed: Addr Len=" << addr_length_
<< " but it must contain at least one valid IP address");
}
// Check if IPv6 Address(es) field is not truncated.

View File

@@ -7,28 +7,11 @@
#ifndef OPTION6_DNR_H
#define OPTION6_DNR_H
#include <dhcp/option.h>
#include <dhcp/option4_dnr.h>
namespace isc {
namespace dhcp {
/// @brief Exception thrown when invalid domain name is specified.
class InvalidOptionDnrDomainName : public Exception {
public:
InvalidOptionDnrDomainName(const char* file, size_t line, const char* what)
: isc::Exception(file, line, what) {
}
};
/// @brief Exception thrown when Service parameters have wrong format.
class InvalidOptionDnrSvcParams : public Exception {
public:
InvalidOptionDnrSvcParams(const char* file, size_t line, const char* what)
: isc::Exception(file, line, what) {
}
};
/// @brief Represents DHCPv6 Encrypted DNS %Option (code 144).
///
/// This option has been defined in the @c draft-ietf-add-dnr (to be replaced

View File

@@ -6,13 +6,9 @@
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcp/dhcp4.h>
#include <dhcp/opaque_data_tuple.h>
#include <dhcp/option4_dnr.h>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
using namespace isc;
@@ -22,6 +18,7 @@ using boost::scoped_ptr;
namespace {
// This test verifies constructor of the empty Option4Dnr class.
TEST(Option4DnrTest, emptyCtor) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
@@ -33,7 +30,9 @@ TEST(Option4DnrTest, emptyCtor) {
EXPECT_EQ(DHO_V4_DNR, option->getType());
}
TEST(Option4DnrTest, oneDnrOnlyModeInstance) {
// This test verifies constructor of the empty Option4Dnr class together
// with adding ADN-only-mode DNR instance to option's DNR instances.
TEST(Option4DnrTest, oneAdnOnlyModeInstance) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
EXPECT_NO_THROW(option.reset(new Option4Dnr()));
@@ -70,7 +69,9 @@ TEST(Option4DnrTest, oneDnrOnlyModeInstance) {
option->toText());
}
TEST(Option4DnrTest, multipleDnrOnlyModeInstances) {
// This test verifies constructor of the empty Option4Dnr class together
// with adding multiple ADN-only-mode DNR instances to option's DNR instances.
TEST(Option4DnrTest, multipleAdnOnlyModeInstances) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
EXPECT_NO_THROW(option.reset(new Option4Dnr()));
@@ -129,6 +130,10 @@ TEST(Option4DnrTest, multipleDnrOnlyModeInstances) {
option->toText());
}
// This test verifies constructor of the empty Option4Dnr class together
// with adding to option's DNR instances:
// 1. ADN-only-mode DNR instance
// 2. All fields included (IP addresses and service params also) DNR instance.
TEST(Option4DnrTest, mixedDnrInstances) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
@@ -186,7 +191,10 @@ TEST(Option4DnrTest, mixedDnrInstances) {
option->toText());
}
TEST(Option4DnrTest, packOneDnrOnlyModeInstance) {
// This test verifies option packing into wire data.
// Provided data to pack contains 1 DNR instance:
// 1. ADN only mode
TEST(Option4DnrTest, packOneAdnOnlyModeInstance) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
EXPECT_NO_THROW(option.reset(new Option4Dnr()));
@@ -222,7 +230,12 @@ TEST(Option4DnrTest, packOneDnrOnlyModeInstance) {
EXPECT_EQ(0, memcmp(ref_data, buf.getData(), buf.getLength()));
}
TEST(Option4DnrTest, packMultipleDnrOnlyModeInstances) {
// This test verifies option packing into wire data.
// Provided data to pack contains 3 DNR instances:
// 1. ADN only mode
// 2. ADN only mode
// 3. ADN only mode
TEST(Option4DnrTest, packMultipleAdnOnlyModeInstances) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
EXPECT_NO_THROW(option.reset(new Option4Dnr()));
@@ -278,6 +291,10 @@ TEST(Option4DnrTest, packMultipleDnrOnlyModeInstances) {
EXPECT_EQ(0, memcmp(ref_data, buf.getData(), buf.getLength()));
}
// This test verifies option packing into wire data.
// Provided data to pack contains 2 DNR instances:
// 1. ADN only mode
// 2. All fields included (IP addresses and service params also).
TEST(Option4DnrTest, packMixedDnrInstances) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
@@ -334,6 +351,7 @@ TEST(Option4DnrTest, packMixedDnrInstances) {
EXPECT_EQ(0, memcmp(ref_data, buf.getData(), buf.getLength()));
}
// This test verifies option constructor from wire data.
TEST(Option4DnrTest, onWireDataCtor) {
// Prepare data to decode - ADN only mode 1 DNR instance.
const uint8_t buf_data[] = {
@@ -351,6 +369,10 @@ TEST(Option4DnrTest, onWireDataCtor) {
ASSERT_TRUE(option);
}
// This test verifies option constructor from wire data in terms
// of proper data unpacking.
// Provided wire data contains 1 DNR instance:
// 1. ADN only mode
TEST(Option4DnrTest, unpackOneAdnOnly) {
// Prepare data to decode - ADN only mode 1 DNR instance.
const uint8_t buf_data[] = {
@@ -396,6 +418,10 @@ TEST(Option4DnrTest, unpackOneAdnOnly) {
option->toText());
}
// This test verifies option constructor from wire data in terms
// of proper data unpacking.
// Provided wire data contains 1 DNR instance:
// 1. All fields included (IP addresses and service params also).
TEST(Option4DnrTest, unpackOneDnrInstance) {
// Prepare data to decode - 1 DNR instance.
const uint8_t buf_data[] = {
@@ -438,6 +464,11 @@ TEST(Option4DnrTest, unpackOneDnrInstance) {
EXPECT_EQ(66, option->len());
}
// This test verifies option constructor from wire data in terms
// of proper data unpacking.
// Provided wire data contains 2 DNR instances:
// 1. ADN only mode
// 2. All fields included (IP addresses and service params also).
TEST(Option4DnrTest, unpackMixedDnrInstances) {
// Prepare data to decode - 2 DNR instances.
const uint8_t buf_data[] = {
@@ -495,4 +526,257 @@ TEST(Option4DnrTest, unpackMixedDnrInstances) {
EXPECT_EQ(92, option->len());
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - mandatory fields are truncated - Service Priority and ADN Len truncated.
TEST(Option4DnrTest, unpackTruncatedDnrInstanceDataLen) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 62 // DNR Instance Data Len truncated
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OutOfRange);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - DNR instance data truncated when compared to DNR Instance Data Len field.
TEST(Option4DnrTest, unpackTruncatedDnrInstanceData) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 62, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21 // ADN Length is 21 dec
// the rest of DNR instance data is truncated
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OutOfRange);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - ADN field data truncated.
TEST(Option4DnrTest, unpackTruncatedAdn) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 3, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21 // ADN Length is 21 dec
// ADN data is missing.
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OpaqueDataTupleError);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - ADN FQDN contains only whitespace - non valid FQDN.
TEST(Option4DnrTest, unpackInvalidFqdnAdn) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 4, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
1, // ADN Length is 1 dec
' ' // ADN contains only whitespace
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), InvalidOptionDnrDomainName);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - ADN Length is 0 and no ADN FQDN at all.
TEST(Option4DnrTest, unpackNoFqdnAdn) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 3, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
0 // ADN Length is 0 dec
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), InvalidOptionDnrDomainName);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - IPv4 address(es) field data truncated.
TEST(Option4DnrTest, unpackTruncatedIpAddress) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 25, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '2', // FQDN: myhost2.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
8 // Addr Len
// the rest of DNR instance data is truncated.
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OpaqueDataTupleError);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - Addr length is 0 and no IPv4 addresses at all.
TEST(Option4DnrTest, unpackNoIpAddress) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 25, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '2', // FQDN: myhost2.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0 // Addr Len = 0
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OutOfRange);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - Addr length is not a multiple of 4.
TEST(Option4DnrTest, unpackIpAddressNon4Modulo) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 32, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '2', // FQDN: myhost2.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
7, // Addr Len
192, 168, 0, 1, // IP address 1
192, 168, 0 // IP address 2 truncated
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), OutOfRange);
ASSERT_FALSE(option);
}
// Test checks that exception is thrown when trying to unpack malformed wire data
// - SvcParams Key contains char that is not allowed.
TEST(Option4DnrTest, unpackvcParamsInvalidCharKey) {
// Prepare malformed data to decode.
const uint8_t buf_data[] = {
0x00, 24, // DNR Instance Data Len
0x00, 0x01, // Service priority is 1 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '1', // FQDN: myhost1.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
0x00, 39, // DNR Instance Data Len
0x00, 0x02, // Service priority is 2 dec
21, // ADN Length is 21 dec
0x07, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, '2', // FQDN: myhost2.
0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example.
0x03, 0x63, 0x6F, 0x6D, 0x00, // com.
8, // Addr Len
192, 168, 0, 1, // IP address 1
192, 168, 0, 2, // IP address 2 truncated
'k', 'e', 'y', '+', '2', '3' // Svc Params key has forbidden char +
};
OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
// Create option instance. Check that constructor throws an exception while doing unpack.
scoped_ptr<Option4Dnr> option;
EXPECT_THROW(option.reset(new Option4Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams);
ASSERT_FALSE(option);
}
// This test verifies that string representation of the option returned by
// toText method is correctly formatted.
TEST(Option4DnrTest, toText) {
// Create option instance. Check that constructor doesn't throw.
scoped_ptr<Option4Dnr> option;
EXPECT_NO_THROW(option.reset(new Option4Dnr()));
ASSERT_TRUE(option);
// Prepare example DNR instance to add.
DnrInstance dnr_1 = DnrInstance(Option::V4, 1, "myhost1.example.com.");
// Add DNR instance.
option->addDnrInstance(dnr_1);
// Let's check if toText() works ok.
// toText() len does not count in headers len.
const int indent = 4;
std::string expected = " type=162(V4_DNR), len=26, " // the indentation of 4 spaces
"DNR Instance 1(Instance len=24, service_priority=1, "
"adn_length=21, adn='myhost1.example.com.')";
EXPECT_EQ(expected, option->toText(indent));
}
} // namespace

View File

@@ -6,9 +6,6 @@
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcp/dhcp6.h>
#include <dhcp/opaque_data_tuple.h>
#include <dhcp/option6_dnr.h>
#include <boost/scoped_ptr.hpp>