From: Tomek Mrugalski Date: Thu, 13 Sep 2012 17:09:13 +0000 (+0200) Subject: [2238] CfgMgr work in progress: Triplet, Pool6, Subnet6 classes X-Git-Tag: trac2402_base~5^2~17^2~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e9498651c8bc59ba17f353f196c0675dd7b8e2ff;p=thirdparty%2Fkea.git [2238] CfgMgr work in progress: Triplet, Pool6, Subnet6 classes --- diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am index fbd4eb53b5..3bcb3988d8 100644 --- a/src/lib/dhcp/Makefile.am +++ b/src/lib/dhcp/Makefile.am @@ -13,7 +13,7 @@ AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG) CLEANFILES = *.gcno *.gcda -lib_LTLIBRARIES = libb10-dhcp++.la +lib_LTLIBRARIES = libb10-dhcp++.la libb10-dhcpsrv.la libb10_dhcp___la_SOURCES = libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h libb10_dhcp___la_SOURCES += iface_mgr.cc iface_mgr.h @@ -29,8 +29,14 @@ libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h +libb10_dhcpsrv_la_SOURCES = cfgmgr.cc cfgmgr.h +libb10_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS) +libb10_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES) +libb10_dhcpsrv_la_LIBADD = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la +libb10_dhcpsrv_la_LIBADD += $(top_builddir)/src/lib/util/libb10-util.la +libb10_dhcpsrv_la_LDFLAGS = -no-undefined -version-info 2:0:0 + EXTRA_DIST = README -#EXTRA_DIST += log_messages.mes libb10_dhcp___la_CXXFLAGS = $(AM_CXXFLAGS) libb10_dhcp___la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES) diff --git a/src/lib/dhcp/README b/src/lib/dhcp/README index 6bd6384b6c..c5e70f2234 100644 --- a/src/lib/dhcp/README +++ b/src/lib/dhcp/README @@ -1,11 +1,9 @@ -This directory holds implementation for libdhcp++. +This directory holds implementation for DHCP libraries: +libdhcp++ - this is a generic purpose DHCP library. Please be careful +what is put here. It is going to be shared by various servers (the "regular" +one and the embedded as well), clients, relays and performance tools. -Basic Ideas -=========== +libdhcpsrv - Server specific code goes in here. It will be used by +dhcp4 and dhcp6 server. - -Notes -===== -This work just begun. Don't expect to see much useful code here. -We are working on it. diff --git a/src/lib/dhcp/cfgmgr.cc b/src/lib/dhcp/cfgmgr.cc new file mode 100644 index 0000000000..4b3084a349 --- /dev/null +++ b/src/lib/dhcp/cfgmgr.cc @@ -0,0 +1,24 @@ +// Copyright (C) 2012 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 + +namespace isc { +namespace dhcp { + + + + +}; // end of isc::dhcp namespace +}; // end of isc namespace diff --git a/src/lib/dhcp/cfgmgr.h b/src/lib/dhcp/cfgmgr.h new file mode 100644 index 0000000000..b377732844 --- /dev/null +++ b/src/lib/dhcp/cfgmgr.h @@ -0,0 +1,204 @@ +// Copyright (C) 2012 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 CFGMGR_H +#define CFGMGR_H + +#include +#include +#include +#include +#include +#include + +namespace isc { +namespace dhcp { + +class Pool6; +class Subnet6; + +/// @brief this class specifes parameter value +/// +/// This class is used to store configuration parameters, like lifetime or T1. +/// It defines 3 parameters: min/default/max values. There are 2 constructors: +/// - simple (just one value that sets all parameters) +/// - extended (that sets default value and two thresholds) +template +class Triplet { +public: + + /// @brief base type to Triple conversion + /// + /// Typically: uint32_t to Triplet assignment. It is very convenient + /// to be able to simply write Triplet x = 7; + Triplet& operator = (T base_type) { + return Triplet(base_type); + } + + /// @brief triplet to base type conversion + /// + /// Typically: Triplet to uint32_t assignment. It is very convenient + /// to be able to simply write uint32_t z = x; (where x is a Triplet) + operator T () const { + return (default_); + } + + /// @brief sets a fixed value + Triplet(T value) + :min_(value), default_(value), max_(value) { + } + + /// @brief sets the default value and thresholds + /// + /// @throw BadValue if min <= def <= max rule is violated + Triplet(T min, T def, T max) + :min_(min), default_(def), max_(max) { + if ( (min_>def) || (def > max_) ) { + isc_throw(BadValue, "Invalid triplet values."); + } + } + + /// @brief returns a minimum allowed value + T getMin() const { return min_;} + + /// @brief returns the default value + T get() const { return default_;} + + /// @brief returns value with a hint + /// + /// DHCP protocol treats any values sent by a client as hints. + /// This is a method that implements that. We can assign any value + /// from configured range that client asks. + T get(T hint) const { + if (hint <= min_) { + return (min_); + } + + if (hint >= max_) { + return (max_); + } + + return (hint); + } + + /// @brief returns a maximum allowed value + T getMax() const { return max_; } + +protected: + + /// @brief the minimum value + T min_; + + /// @brief the default value + T default_; + + /// @brief the maximum value + T max_; +}; + +class Pool6 { +public: + typedef enum { + TYPE_IA, + TYPE_TA, + TYPE_PD + } Pool6Type; + + Pool6(Pool6Type type, const isc::asiolink::IOAddress first, + const isc::asiolink::IOAddress last, + const Triplet& t1, + const Triplet& t2, + const Triplet& preferred_lifetime, + const Triplet& valid_lifetime); + + uint32_t getId() const { + return (id_); + } + + Pool6Type getType() const { + return (type_); + } + + const isc::asiolink::IOAddress& getFirstAddress() const { + return (first_); + } + + const isc::asiolink::IOAddress& getLastAddress() const { + return (last_); + } + + Triplet getT1() const { + return (t1_); + } + + Triplet getT2() const { + return (t2_); + } + + Triplet getPreferred() const { + return (preferred_); + } + + Triplet getValid() const { + return (valid_); + } + +protected: + /// @brief pool-id + /// + /// This ID is used to indentify this specific pool. + uint32_t id_; + + Pool6Type type_; + + isc::asiolink::IOAddress first_; + + isc::asiolink::IOAddress last_; + + Triplet t1_; + + Triplet t2_; + + Triplet preferred_; + + Triplet valid_; + + ///uint128_t available_leases_; + + ///uint128_t total_leases_; + + std::string comments_; +}; + +typedef boost::shared_ptr Pool6Ptr; + +typedef std::vector Pool6Collection; + +class Subnet6 { +public: + /// @brief subnet-id + uint32_t id_; + + isc::asiolink::IOAddress addr_; + + uint8_t prefix_len_; + + /// collection of pools in that list + Pool6Collection pools_; +}; + +} // namespace isc::dhcp +} // namespace isc + +#endif diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am index eba7e81f14..74751cc4ed 100644 --- a/src/lib/dhcp/tests/Makefile.am +++ b/src/lib/dhcp/tests/Makefile.am @@ -24,7 +24,7 @@ TESTS_ENVIRONMENT = \ TESTS = if HAVE_GTEST -TESTS += libdhcp++_unittests +TESTS += libdhcp++_unittests libdhcpsrv_unittests libdhcp___unittests_SOURCES = run_unittests.cc libdhcp___unittests_SOURCES += ../libdhcp++.h ../libdhcp++.cc libdhcp___unittests_SOURCES += libdhcp++_unittest.cc @@ -42,17 +42,26 @@ libdhcp___unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) libdhcp___unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) - libdhcp___unittests_CXXFLAGS = $(AM_CXXFLAGS) +libdhcpsrv_unittests_SOURCES = run_unittests.cc +libdhcpsrv_unittests_SOURCES += ../cfgmgr.cc ../cfgmgr.h cfgmgr_unittest.cc + +libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) +libdhcpsrv_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) +libdhcpsrv_unittests_CXXFLAGS = $(AM_CXXFLAGS) +libdhcpsrv_unittests_LDADD = $(GTEST_LDADD) +libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la + + if USE_CLANGPP # This is to workaround unused variables tcout and tcerr in # log4cplus's streams.h and unused parameters from some of the # Boost headers. libdhcp___unittests_CXXFLAGS += -Wno-unused-variable -Wno-unused-parameter +libdhcpsrv_unittests_CXXFLAGS += -Wno-unused-variable -Wno-unused-parameter endif libdhcp___unittests_LDADD = $(GTEST_LDADD) -libdhcp___unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la libdhcp___unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la libdhcp___unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la libdhcp___unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la diff --git a/src/lib/dhcp/tests/cfgmgr_unittest.cc b/src/lib/dhcp/tests/cfgmgr_unittest.cc new file mode 100644 index 0000000000..fad5c57f7f --- /dev/null +++ b/src/lib/dhcp/tests/cfgmgr_unittest.cc @@ -0,0 +1,102 @@ +// Copyright (C) 2012 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 +#include +#include +#include + +using namespace std; +using namespace isc::asiolink; +using namespace isc::dhcp; +using namespace isc::util; +using namespace isc; + +// don't import the entire boost namespace. It will unexpectedly hide uint8_t +// for some systems. +using boost::scoped_ptr; + +namespace { + +// constructor validation +TEST(TripletTest, constructor) { + + uint32_t min = 10; + uint32_t value = 20; + uint32_t max = 30; + + Triplet x(min, value, max); + + EXPECT_EQ(10, x.getMin()); + EXPECT_EQ(20, x.get()); + EXPECT_EQ(30, x.getMax()); + + // requested values below min should return allowed min value + EXPECT_EQ(10, x.get(5)); + + EXPECT_EQ(10, x.get(10)); + + // requesting a value from within the range (min < x < max) should + // return the requested value + EXPECT_EQ(17, x.get(17)); + + EXPECT_EQ(30, x.get(30)); + + EXPECT_EQ(30, x.get(35)); + + // this will be boring. It is expected to return 42 no matter what + Triplet y(42); + + EXPECT_EQ(42, y.getMin()); // min, default and max are equal to 42 + EXPECT_EQ(42, y.get()); // it returns ... + EXPECT_EQ(42, y.getMax()); // the exact value... + + // requested values below or above are ignore + EXPECT_EQ(42, y.get(5)); // all... + EXPECT_EQ(42, y.get(42)); // the... + EXPECT_EQ(42, y.get(80)); // time! +} + +// triplets must be easy to use +// simple int conversions must be done on the fly +TEST(TripletTest, operator) { + + uint32_t x = 47; + + // assignment operator: uint32_t => triplet + Triplet y = x; + + EXPECT_EQ(47, y.get()); + + // let's try the other way around: triplet => uint32_t + uint32_t z = y; + + EXPECT_EQ(47, z); +} + +// check if specified values are sane +TEST(TripletTest, sanity_check) { + + // min is larger than default + EXPECT_THROW(Triplet(6,5,5), BadValue); + + // max is smaller than default + EXPECT_THROW(Triplet(5,5,4), BadValue); + +} + +} // end of anonymous namespace diff --git a/src/lib/dhcp/tests/run_unittests.cc b/src/lib/dhcp/tests/run_unittests.cc index db27f767d7..d3dd12e867 100644 --- a/src/lib/dhcp/tests/run_unittests.cc +++ b/src/lib/dhcp/tests/run_unittests.cc @@ -14,12 +14,9 @@ #include -#include - int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv); - isc::log::initLogger(); int result = RUN_ALL_TESTS();