Commit fe5f2029 authored by Marcin Siodelski's avatar Marcin Siodelski

[3874] Added storage class for DUID configuration.

parent 6172b66d
......@@ -78,6 +78,7 @@ libkea_dhcpsrv_la_SOURCES += alloc_engine.cc alloc_engine.h
libkea_dhcpsrv_la_SOURCES += alloc_engine_log.cc alloc_engine_log.h
libkea_dhcpsrv_la_SOURCES += base_host_data_source.h
libkea_dhcpsrv_la_SOURCES += callout_handle_store.h
libkea_dhcpsrv_la_SOURCES += cfg_duid.cc cfg_duid.h
libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
libkea_dhcpsrv_la_SOURCES += cfg_iface.cc cfg_iface.h
libkea_dhcpsrv_la_SOURCES += cfg_expiration.cc cfg_expiration.h
......
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/cfg_duid.h>
#include <util/encode/hex.h>
#include <util/strutil.h>
#include <iostream>
using namespace isc;
using namespace isc::util::encode;
using namespace isc::util::str;
namespace isc {
namespace dhcp {
CfgDUID::CfgDUID()
: type_(DUID::DUID_LLT), identifier_(), htype_(0), time_(0),
enterprise_id_(0) {
}
void
CfgDUID::setIdentifier(const std::string& identifier_as_hex) {
// Remove whitespaces.
const std::string identifier = trim(identifier_as_hex);
// Temporary result of parsing.
std::vector<uint8_t> binary;
if (!identifier.empty()) {
try {
// Decode identifier specified as a string of hexadecimal digits.
decodeHex(identifier, binary);
// All went ok, so let's replace identifier with a new value.
identifier_.swap(binary);
} catch (const std::exception& ex) {
isc_throw(BadValue, "identifier specified in the DUID"
" configuration '" << identifier
<< "' is not a valid string of hexadecimal digits");
}
} else {
// If specified identifier is empty, clear our internal identifier.
identifier_.clear();
}
}
}
}
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef CFG_DUID_H
#define CFG_DUID_H
#include <dhcp/duid.h>
#include <boost/shared_ptr.hpp>
#include <stdint.h>
#include <vector>
namespace isc {
namespace dhcp {
/// @brief Holds manual configuration of the server identifier (DUID).
///
/// The DHCPv6 server uses DHCPv6 Unique Identifier (DUID) to identify itself
/// to the clients. Typically, the server generates the DUID on the first
/// startup and writes it to the persistent storage so as it doesn't change
/// across restarts of the server. RFC3315 and RFC6355 define different DUID
/// types. Kea allows for selecting a type of DUID that the server should
/// generate. It also allows for overriding entire default DUID or parts of
/// it via configuration file. This class holds the DUID configuration
/// specified in the server configuration file.
class CfgDUID {
public:
/// @brief Constructor.
CfgDUID();
/// @brief Returns DUID type.
DUID::DUIDType getType() const {
return (type_);
}
/// @brief Sets DUID type.
void setType(const DUID::DUIDType& type) {
type_ = type;
}
/// @brief Returns identifier.
///
/// Identifier is a link layer address for the DUID-LLT and DUID-LL. It
/// is also a variable length identifier in DUID-EN. It may be used for
/// all other existing and future DUID types when there is a need to
/// represent some variable length identifier.
///
/// @return Vector holding an identifier belonging to a particular
/// DUID type.
std::vector<uint8_t> getIdentifier() const {
return (identifier_);
}
/// @brief Sets new identifier as hex string.
///
/// @param identifier_as_hex String of hexadecimal digits representing
/// variable length identifier within a DUID.
void setIdentifier(const std::string& identifier_as_hex);
/// @brief Returns hardware type for DUID-LLT and DUID-LL.
uint16_t getHType() const {
return (htype_);
}
/// @brief Sets new hardware type for DUID-LLT and DUID-LL.
void setHType(const uint16_t htype) {
htype_ = htype;
}
/// @brief Returns time for the DUID-LLT.
uint32_t getTime() const {
return (time_);
}
/// @brief Sets new time for DUID-LLT.
void setTime(const uint32_t new_time) {
time_ = new_time;
}
/// @brief Returns enterprise id for the DUID-EN.
uint32_t getEnterpriseId() const {
return (enterprise_id_);
}
/// @brief Sets new enterprise id.
///
/// @param enterprise_id New enterprise id.
void setEnterpriseId(const uint32_t enterprise_id) {
enterprise_id_ = enterprise_id;
}
private:
/// @brief DUID type.
DUID::DUIDType type_;
/// @brief Variable length identifier in a DUID.
std::vector<uint8_t> identifier_;
/// @brief Hardware type.
uint16_t htype_;
/// @brief Time used for DUID-LLT.
uint32_t time_;
/// @brief Enterprise id used for DUID-EN.
uint32_t enterprise_id_;
};
/// @name Pointers to the @c CfgDUID objects.
//@{
/// @brief Pointer to the Non-const object.
typedef boost::shared_ptr<CfgDUID> CfgDUIDPtr;
/// @brief Pointer to the const object.
typedef boost::shared_ptr<const CfgDUID> ConstCfgDUIDPtr;
//@}
}
}
#endif // CFG_DUID_H
......@@ -31,7 +31,7 @@ SrvConfig::SrvConfig()
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
cfg_expiration_(new CfgExpiration()),
cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
decline_timer_(0) {
}
......@@ -40,7 +40,7 @@ SrvConfig::SrvConfig(const uint32_t sequence)
cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
cfg_expiration_(new CfgExpiration()),
cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
decline_timer_(0) {
}
......
......@@ -15,6 +15,7 @@
#ifndef DHCPSRV_CONFIG_H
#define DHCPSRV_CONFIG_H
#include <dhcpsrv/cfg_duid.h>
#include <dhcpsrv/cfg_expiration.h>
#include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/cfg_iface.h>
......@@ -272,6 +273,18 @@ public:
return (cfg_expiration_);
}
/// @brief Returns pointer to the object holding configuration of the
/// server identifier.
CfgDUIDPtr getCfgDUID() {
return (cfg_duid_);
}
/// @brief Returns const pointer to the object holding configuration
/// of the server identifier.
ConstCfgDUIDPtr getCfgDUID() const {
return (cfg_duid_);
}
//@}
/// @brief Returns non-const reference to an array that stores
......@@ -458,6 +471,9 @@ private:
/// expired leases.
CfgExpirationPtr cfg_expiration_;
/// @brief Pointer to the configuration of the server identifier.
CfgDUIDPtr cfg_duid_;
/// @brief Pointer to the control-socket information
isc::data::ConstElementPtr control_socket_;
......
......@@ -65,6 +65,7 @@ libdhcpsrv_unittests_SOURCES += alloc_engine_hooks_unittest.cc
libdhcpsrv_unittests_SOURCES += alloc_engine4_unittest.cc
libdhcpsrv_unittests_SOURCES += alloc_engine6_unittest.cc
libdhcpsrv_unittests_SOURCES += callout_handle_store_unittest.cc
libdhcpsrv_unittests_SOURCES += cfg_duid_unittest.cc
libdhcpsrv_unittests_SOURCES += cfg_expiration_unittest.cc
libdhcpsrv_unittests_SOURCES += cfg_hosts_unittest.cc
libdhcpsrv_unittests_SOURCES += cfg_iface_unittest.cc
......
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <dhcp/dhcp4.h>
#include <dhcp/duid.h>
#include <dhcpsrv/cfg_duid.h>
#include <exceptions/exceptions.h>
#include <util/encode/hex.h>
#include <gtest/gtest.h>
#include <stdint.h>
#include <string>
#include <vector>
using namespace isc;
using namespace isc::dhcp;
namespace {
/// @brief Converts vector to string of hexadecimal digits.
///
/// @param vec Input vector.
/// @return String of hexadecimal digits converted from vector.
std::string toString(const std::vector<uint8_t>& vec) {
try {
return (util::encode::encodeHex(vec));
} catch (...) {
ADD_FAILURE() << "toString: unable to encode vector to"
" hexadecimal string";
}
return ("");
}
// This test verifies default values of the DUID configuration.
TEST(CfgDUIDTest, defaults) {
CfgDUID cfg_duid;
EXPECT_EQ(DUID::DUID_LLT, cfg_duid.getType());
EXPECT_TRUE(cfg_duid.getIdentifier().empty())
<< "expected empty identifier, found: "
<< toString(cfg_duid.getIdentifier());
EXPECT_EQ(0, cfg_duid.getHType());
EXPECT_EQ(0, cfg_duid.getTime());
EXPECT_EQ(0, cfg_duid.getEnterpriseId());
}
// This test verifies that it is possible to set values for the CfgDUID.
TEST(CfgDUIDTest, setValues) {
CfgDUID cfg_duid;
// Set values.
ASSERT_NO_THROW(cfg_duid.setType(DUID::DUID_EN));
ASSERT_NO_THROW(cfg_duid.setIdentifier("ABCDEF"));
ASSERT_NO_THROW(cfg_duid.setHType(100));
ASSERT_NO_THROW(cfg_duid.setTime(32100));
ASSERT_NO_THROW(cfg_duid.setEnterpriseId(10));
// Check that values have been set correctly.
EXPECT_EQ(DUID::DUID_EN, cfg_duid.getType());
EXPECT_EQ("ABCDEF", toString(cfg_duid.getIdentifier()));
EXPECT_EQ(100, cfg_duid.getHType());
EXPECT_EQ(32100, cfg_duid.getTime());
EXPECT_EQ(10, cfg_duid.getEnterpriseId());
}
// This test checks positive scenarios for setIdentifier.
TEST(CfgDUIDTest, setIdentifier) {
CfgDUID cfg_duid;
// Check that hexadecimal characters may be lower case.
ASSERT_NO_THROW(cfg_duid.setIdentifier("a1b2c3"));
EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
// Check that whitespaces are allowed.
ASSERT_NO_THROW(cfg_duid.setIdentifier(" ABC DEF "));
EXPECT_EQ("ABCDEF", toString(cfg_duid.getIdentifier()));
// Check that identifier including only whitespaces is ignored.
ASSERT_NO_THROW(cfg_duid.setIdentifier(" "));
EXPECT_TRUE(cfg_duid.getIdentifier().empty())
<< "expected empty identifier, found: "
<< toString(cfg_duid.getIdentifier());
}
TEST(CfgDUIDTest, setInvalidIdentifier) {
CfgDUID cfg_duid;
// Check that hexadecimal characters may be lower case.
ASSERT_NO_THROW(cfg_duid.setIdentifier("a1b2c3"));
EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
// Try to set invalid value. This should not modify original
// value.
ASSERT_THROW(cfg_duid.setIdentifier("hola!"), isc::BadValue);
EXPECT_EQ("A1B2C3", toString(cfg_duid.getIdentifier()));
}
} // end of anonymous namespace
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