Browse Source

[2313] Add option spaces into configuration manager.

Marcin Siodelski 12 years ago
parent
commit
d4eda56344

+ 30 - 3
src/lib/dhcpsrv/cfgmgr.cc

@@ -21,15 +21,42 @@ using namespace isc::util;
 namespace isc {
 namespace dhcp {
 
-
-
-
 CfgMgr&
 CfgMgr::instance() {
     static CfgMgr cfg_mgr;
     return (cfg_mgr);
 }
 
+void
+CfgMgr::addOptionSpace4(const OptionSpacePtr& space) {
+    if (!space) {
+        isc_throw(InvalidOptionSpace,
+                  "provided option space object is NULL.");
+    }
+    OptionSpaceCollection::iterator it = spaces4_.find(space->getName());
+    if (it != spaces4_.end()) {
+        isc_throw(InvalidOptionSpace, "option space " << space->getName()
+                  << " already added.");
+    }
+    spaces4_.insert(std::pair<std::string,
+                              OptionSpacePtr>(space->getName(), space));
+}
+
+void
+CfgMgr::addOptionSpace6(const OptionSpacePtr& space) {
+    if (!space) {
+        isc_throw(InvalidOptionSpace,
+                  "provided option space object is NULL.");
+    }
+    OptionSpaceCollection::iterator it = spaces6_.find(space->getName());
+    if (it != spaces6_.end()) {
+        isc_throw(InvalidOptionSpace, "option space " << space->getName()
+                  << " already added.");
+    }
+    spaces6_.insert(std::pair<std::string,
+                              OptionSpacePtr>(space->getName(), space));
+}
+
 Subnet6Ptr
 CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint) {
 

+ 37 - 0
src/lib/dhcpsrv/cfgmgr.h

@@ -17,6 +17,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcp/option.h>
+#include <dhcpsrv/option_space.h>
 #include <dhcpsrv/pool.h>
 #include <dhcpsrv/subnet.h>
 #include <util/buffer.h>
@@ -77,6 +78,36 @@ public:
     /// accessing it.
     static CfgMgr& instance();
 
+    /// @brief Adds new DHCPv4 option space to the collection.
+    ///
+    /// @param space option space to be added.
+    ///
+    /// @throw isc::dhcp::InvalidOptionSpace invalid option space
+    /// has been specified.
+    void addOptionSpace4(const OptionSpacePtr& space);
+
+    /// @brief Adds new DHCPv6 option space to the collection.
+    ///
+    /// @param space option space to be added.
+    ///
+    /// @throw isc::dhcp::InvalidOptionSpace invalid option space
+    /// has been specified.
+    void addOptionSpace6(const OptionSpacePtr& space);
+
+    /// @brief Return option spaces for DHCPv4.
+    ///
+    /// @return A collection of option spaces.
+    const OptionSpaceCollection& getOptionSpaces4() const {
+        return (spaces4_);
+    }
+
+    /// @brief Return option spaces for DHCPv6.
+    ///
+    /// @return A collection of option spaces.
+    const OptionSpaceCollection& getOptionSpaces6() const {
+        return (spaces6_);
+    }
+
     /// @brief get IPv6 subnet by address
     ///
     /// Finds a matching subnet, based on an address. This can be used
@@ -169,6 +200,12 @@ protected:
     /// pattern will use calling inRange() method on each subnet until
     /// a match is found.
     Subnet4Collection subnets4_;
+
+    /// @brief Container for defined DHCPv6 option spaces.
+    OptionSpaceCollection spaces6_;
+
+    /// @brief Container for defined DHCPv4 option spaces.
+    OptionSpaceCollection spaces4_;
 };
 
 } // namespace isc::dhcp

+ 14 - 1
src/lib/dhcpsrv/option_space.h

@@ -15,15 +15,28 @@
 #ifndef OPTION_SPACE_H
 #define OPTION_SPACE_H
 
+#include <exceptions/exceptions.h>
 #include <boost/shared_ptr.hpp>
+#include <map>
 #include <string>
 
 namespace isc {
 namespace dhcp {
 
-class OptionSpace;
+/// @brief Exception to be thrown when invalid option space
+/// is specified.
+class InvalidOptionSpace : public Exception {
+public:
+    InvalidOptionSpace(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) { };
+};
 
+/// OptionSpace forward declaration.
+class OptionSpace;
+/// A pointer to OptionSpace object.
 typedef boost::shared_ptr<OptionSpace> OptionSpacePtr;
+/// A collection of option spaces.
+typedef std::map<std::string, OptionSpacePtr> OptionSpaceCollection;
 
 /// @brief Option code space.
 ///

+ 66 - 0
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc

@@ -112,4 +112,70 @@ TEST_F(CfgMgrTest, subnet6) {
     EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("4000::123")));
 }
 
+// This test verifies that new DHCPv4 option spaces can be added to
+// the configuration manager and that duplicated option space is
+// rejected.
+TEST_F(CfgMgrTest, optionSpace4) {
+    CfgMgr& cfg_mgr = CfgMgr::instance();
+
+    // Create some option spaces.
+    OptionSpacePtr space1(new OptionSpace("isc", false));
+    OptionSpacePtr space2(new OptionSpace("xyz", true));
+
+    // Add option spaces with different names and expect they
+    // are accepted.
+    ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space1));
+    ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space2));
+
+    // Validate that the option spaces have been added correctly.
+    const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces4();
+
+    ASSERT_EQ(2, spaces.size());
+    EXPECT_FALSE(spaces.find("isc") == spaces.end());
+    EXPECT_FALSE(spaces.find("xyz") == spaces.end());
+
+    // Create another option space with the name that duplicates
+    // the existing option space.
+    OptionSpacePtr space3(new OptionSpace("isc", true));
+    // Expect that the duplicate option space is rejected.
+    ASSERT_THROW(
+        cfg_mgr.addOptionSpace4(space3), isc::dhcp::InvalidOptionSpace
+    );
+
+    // @todo decode if a duplicate vendor space is allowed.
+}
+
+// This test verifies that new DHCPv6 option spaces can be added to
+// the configuration manager and that duplicated option space is
+// rejected.
+TEST_F(CfgMgrTest, optionSpace6) {
+    CfgMgr& cfg_mgr = CfgMgr::instance();
+
+    // Create some option spaces.
+    OptionSpacePtr space1(new OptionSpace("isc", false));
+    OptionSpacePtr space2(new OptionSpace("xyz", true));
+
+    // Add option spaces with different names and expect they
+    // are accepted.
+    ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space1));
+    ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space2));
+
+    // Validate that the option spaces have been added correctly.
+    const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces6();
+
+    ASSERT_EQ(2, spaces.size());
+    EXPECT_FALSE(spaces.find("isc") == spaces.end());
+    EXPECT_FALSE(spaces.find("xyz") == spaces.end());
+
+    // Create another option space with the name that duplicates
+    // the existing option space.
+    OptionSpacePtr space3(new OptionSpace("isc", true));
+    // Expect that the duplicate option space is rejected.
+    ASSERT_THROW(
+        cfg_mgr.addOptionSpace6(space3), isc::dhcp::InvalidOptionSpace
+    );
+
+    // @todo decide if a duplicate vendor space is allowed.
+}
+
 } // end of anonymous namespace