From: Marcin Siodelski Date: Tue, 19 Aug 2014 12:56:58 +0000 (+0200) Subject: [3512] Bare bones implementation of the iface selecting class. X-Git-Tag: trac3482_base~11^2~2^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d40f97625e9252784245c44128b8acbc6ead660e;p=thirdparty%2Fkea.git [3512] Bare bones implementation of the iface selecting class. --- diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am index b10d269a4f..b68924b648 100644 --- a/src/lib/dhcpsrv/Makefile.am +++ b/src/lib/dhcpsrv/Makefile.am @@ -55,6 +55,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h libkea_dhcpsrv_la_SOURCES += cfgmgr.cc cfgmgr.h libkea_dhcpsrv_la_SOURCES += dhcp_config_parser.h libkea_dhcpsrv_la_SOURCES += dhcp_parsers.cc dhcp_parsers.h +libkea_dhcpsrv_la_SOURCES += iface_cfg.cc iface_cfg.h libkea_dhcpsrv_la_SOURCES += key_from_key.h libkea_dhcpsrv_la_SOURCES += lease.cc lease.h libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h diff --git a/src/lib/dhcpsrv/iface_cfg.cc b/src/lib/dhcpsrv/iface_cfg.cc new file mode 100644 index 0000000000..42273d0537 --- /dev/null +++ b/src/lib/dhcpsrv/iface_cfg.cc @@ -0,0 +1,110 @@ +// Copyright (C) 2014 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 +#include +#include + +namespace isc { +namespace dhcp { + +const char* IfaceCfg::ALL_IFACES_KEYWORD = "*"; + +IfaceCfg::IfaceCfg(Family family) + : family_(family), + wildcard_used_(false) { +} + +void +IfaceCfg::closeSockets() { + IfaceMgr::instance().closeSockets(); +} + +void +IfaceCfg::openSockets(const uint16_t /* port */) { + if (!wildcard_used_) { + setState(true); + for (IfaceSet::const_iterator iface_name = iface_set_.begin(); + iface_name != iface_set_.end(); ++iface_name) { + Iface* iface = IfaceMgr::instance().getIface(*iface_name); + if (iface == NULL) { + isc_throw(Unexpected, + "fail to open socket on interface '" + << *iface_name << "' as this interface doesn't" + " exist"); + + } else if (getFamily() == V4) { + iface->inactive4_ = false; + + } else { + iface->inactive6_ = false; + } + } + + } else { + setState(false); + } + + // @todo open sockets here. + +} + +void +IfaceCfg::setState(const bool inactive) { + const IfaceCollection& ifaces = IfaceMgr::instance().getIfaces(); + for (IfaceCollection::iterator iface = ifaces.begin(); + iface != ifaces.end(); ++iface) { + if (getFamily() == V4) { + (*iface)->inactive4_ = inactive; + } else { + (*iface)->inactive6_ = inactive; + } + } +} + +void +IfaceCfg::use(const std::string& iface_name) { + // In theory the configuration parser should strip extraneous spaces but + // since this is a common library it may be better to make sure that it + // is really the case. + std::string name = util::str::trim(iface_name); + if (name.empty()) { + isc_throw(InvalidIfaceName, + "empty interface name used in configuration"); + } + + if (name != ALL_IFACES_KEYWORD) { + if (IfaceMgr::instance().getIface(name) == NULL) { + isc_throw(NoSuchIface, "interface '" << name + << "' doesn't exist in the system"); + } + + std::pair res = iface_set_.insert(name); + if (!res.second) { + isc_throw(DuplicateIfaceName, "interface '" << name + << "' has already been specified"); + } + + } else if (wildcard_used_) { + isc_throw(DuplicateIfaceName, "the wildcard interface '" + << ALL_IFACES_KEYWORD << "' can only be specified once"); + + } else { + wildcard_used_ = true; + + } +} + +} // end of isc::dhcp namespace +} // end of isc namespace diff --git a/src/lib/dhcpsrv/iface_cfg.h b/src/lib/dhcpsrv/iface_cfg.h new file mode 100644 index 0000000000..006d4ac4da --- /dev/null +++ b/src/lib/dhcpsrv/iface_cfg.h @@ -0,0 +1,77 @@ +// Copyright (C) 2014 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 IFACE_CFG_H +#define IFACE_CFG_H + +#include + +namespace isc { +namespace dhcp { + +/// @brief Exception thrown when duplicated interface names specified. +class DuplicateIfaceName : public Exception { +public: + DuplicateIfaceName(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + +/// @brief Exception thrown when specified interface name is invalid. +class InvalidIfaceName : public Exception { +public: + InvalidIfaceName(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + +/// @brief Exception thrown when specified interface doesn't exist in a system. +class NoSuchIface : public Exception { +public: + NoSuchIface(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + +class IfaceCfg { +public: + static const char* ALL_IFACES_KEYWORD; + + enum Family { + V4, V6 + }; + + IfaceCfg(Family family); + + void closeSockets(); + + Family getFamily() const { + return (family_); + } + + void openSockets(const uint16_t port); + + void use(const std::string& iface_name); + +private: + + void setState(const bool inactive); + + Family family_; + typedef std::set IfaceSet; + IfaceSet iface_set_; + bool wildcard_used_; +}; + +} +} + +#endif // IFACE_CFG_H diff --git a/src/lib/dhcpsrv/tests/Makefile.am b/src/lib/dhcpsrv/tests/Makefile.am index a99375c4c7..ef41cb1262 100644 --- a/src/lib/dhcpsrv/tests/Makefile.am +++ b/src/lib/dhcpsrv/tests/Makefile.am @@ -63,6 +63,7 @@ libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc libdhcpsrv_unittests_SOURCES += daemon_unittest.cc libdhcpsrv_unittests_SOURCES += dbaccess_parser_unittest.cc +libdhcpsrv_unittests_SOURCES += iface_cfg_unittest.cc libdhcpsrv_unittests_SOURCES += lease_file_io.cc lease_file_io.h libdhcpsrv_unittests_SOURCES += lease_unittest.cc libdhcpsrv_unittests_SOURCES += lease_mgr_factory_unittest.cc diff --git a/src/lib/dhcpsrv/tests/iface_cfg_unittest.cc b/src/lib/dhcpsrv/tests/iface_cfg_unittest.cc new file mode 100644 index 0000000000..db7c004051 --- /dev/null +++ b/src/lib/dhcpsrv/tests/iface_cfg_unittest.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2014 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 +#include +#include +#include + +using namespace isc; +using namespace isc::dhcp; +using namespace isc::dhcp::test; + +namespace { + +/// @brief Test fixture class for testing the @c IfaceCfg class. +class IfaceCfgTest : public ::testing::Test { +public: + + /// @brief Constructor. + /// + /// By initializing the @c IfaceMgrTestConfig object it creates a set of + /// fake interfaces: lo, eth0, eth1. + IfaceCfgTest() : + iface_mgr_test_config_(true) { + } + + /// @brief Holds a fake configuration of the interfaces. + IfaceMgrTestConfig iface_mgr_test_config_; + +}; + +TEST_F(IfaceCfgTest, explicitNames) { + IfaceCfg cfg; + ASSERT_NO_THROW(cfg.use("eth0")); + ASSERT_NO_THROW(cfg.use("eth1")); +} + +} // end of anonymous namespace