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
--- /dev/null
+// 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();
+ }
+}
+
+
+}
+}
--- /dev/null
+// 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
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) {
}
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) {
}
#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>
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
/// 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_;
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
--- /dev/null
+// 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