#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
+#include <list>
+
using namespace std;
using namespace isc::dhcp;
using namespace isc::util;
return (OptionDefinitionPtr());
}
+OptionDefinitionPtr
+LibDHCP::getRuntimeOptionDef(const std::string& space, const uint16_t code) {
+ OptionDefContainerPtr container = runtime_option_defs_.getItems(space);
+ const OptionDefContainerTypeIndex& index = container->get<1>();
+ const OptionDefContainerTypeRange& range = index.equal_range(code);
+ if (range.first != range.second) {
+ return (*range.first);
+ }
+
+ return (OptionDefinitionPtr());
+}
+
+OptionDefinitionPtr
+LibDHCP::getRuntimeOptionDef(const std::string& space, const std::string& name) {
+ OptionDefContainerPtr container = runtime_option_defs_.getItems(space);
+ const OptionDefContainerNameIndex& index = container->get<2>();
+ const OptionDefContainerNameRange& range = index.equal_range(name);
+ if (range.first != range.second) {
+ return (*range.first);
+ }
+
+ return (OptionDefinitionPtr());
+}
+
+OptionDefContainerPtr
+LibDHCP::getRuntimeOptionDefs(const std::string& space) {
+ return (runtime_option_defs_.getItems(space));
+}
+
void
LibDHCP::setRuntimeOptionDefs(const OptionDefSpaceContainer& defs) {
-
+ std::list<std::string> option_space_names = defs.getOptionSpaceNames();
+ for (std::list<std::string>::const_iterator name = option_space_names.begin();
+ name != option_space_names.end(); ++name) {
+ OptionDefContainerPtr container = defs.getItems(*name);
+ for (OptionDefContainer::const_iterator def = container->begin();
+ def != container->end(); ++def) {
+ OptionDefinitionPtr def_copy(new OptionDefinition(**def));
+ runtime_option_defs_.addItem(def_copy, *name);
+ }
+ }
}
void
OptionDefContainer option_defs;
if (option_space == "dhcp6") {
option_defs = LibDHCP::getOptionDefs(Option::V6);
+ } else {
+ OptionDefContainerPtr option_defs_ptr =
+ LibDHCP::getRuntimeOptionDefs(option_space);
+ if (option_defs_ptr) {
+ option_defs = *option_defs_ptr;
+ }
}
+
// @todo Once we implement other option spaces we should add else clause
// here and gather option definitions for them. For now leaving option_defs
// empty will imply creation of generic Option.
const uint32_t vendor_id,
const std::string& name);
+
+ /// @brief Returns runtime (non-standard) option definition by space and
+ /// option code.
+ ///
+ /// @param space Option space name.
+ /// @param code Option code.
+ ///
+ /// @return Pointer to option definition or NULL if it doesn't exist.
+ static OptionDefinitionPtr getRuntimeOptionDef(const std::string& space,
+ const uint16_t code);
+
+ /// @brief Returns runtime (non-standard) option definition by space and
+ /// option name.
+ ///
+ /// @param space Option space name.
+ /// @param name Option name.
+ ///
+ /// @return Pointer to option definition or NULL if it doesn't exist.
+ static OptionDefinitionPtr getRuntimeOptionDef(const std::string& space,
+ const std::string& name);
+
+ /// @brief Returns runtime (non-standard) option definitions for specified
+ /// option space name.
+ ///
+ /// @param space Option space name.
+ ///
+ /// @return Pointer to the container holding option definitions or NULL.
+ static OptionDefContainerPtr
+ getRuntimeOptionDefs(const std::string& space);
+
+
/// @brief Check if the specified option is a standard option.
///
/// @param u universe (V4 or V6)
return (OptionBuffer(opt_data, opt_data + sizeof(opt_data)));
}
+ /// @brief Create option definitions and store in the container.
+ ///
+ /// @param spaces_num Number of option spaces to be created.
+ /// @param defs_num Number of option definitions to be created for
+ /// each option space.
+ /// @param [out] defs Container to which option definitions should be
+ /// added.
+ static void createRuntimeOptionDefs(const uint16_t spaces_num,
+ const uint16_t defs_num,
+ OptionDefSpaceContainer& defs) {
+ for (uint16_t space = 0; space < spaces_num; ++space) {
+ std::ostringstream space_name;
+ space_name << "option-space-" << space;
+ for (uint16_t code = 0; code < defs_num; ++code) {
+ std::ostringstream name;
+ name << "name-for-option-" << code;
+ OptionDefinitionPtr opt_def(new OptionDefinition(name.str(),
+ code, "string"));
+ defs.addItem(opt_def, space_name.str());
+ }
+ }
+ }
+
+ /// @brief Test if runtime option definitions have been added.
+ ///
+ /// This method uses the same naming conventions for space names and
+ /// options names as @c createRuntimeOptionDefs method.
+ ///
+ /// @param spaces_num Number of option spaces to be tested.
+ /// @param defs_num Number of option definitions that should exist
+ /// in each option space.
+ /// @param should_exist Boolean value which indicates if option
+ /// definitions should exist. If this is false, this function will
+ /// check that they don't exist.
+ static void testRuntimeOptionDefs(const uint16_t spaces_num,
+ const uint16_t defs_num,
+ const bool should_exist) {
+ for (uint16_t space = 0; space < spaces_num; ++space) {
+ std::ostringstream space_name;
+ space_name << "option-space-" << space;
+ for (uint16_t code = 0; code < defs_num; ++code) {
+ std::ostringstream name;
+ name << "name-for-option-" << code;
+ OptionDefinitionPtr opt_def =
+ LibDHCP::getRuntimeOptionDef(space_name.str(), name.str());
+ if (should_exist) {
+ ASSERT_TRUE(opt_def);
+ } else {
+ ASSERT_FALSE(opt_def);
+ }
+ }
+ }
+ }
+
private:
/// @brief Test DHCPv4 or DHCPv6 option definition.
EXPECT_EQ("eRouter1.0", vclass->getTuple(0).getText());
}
+// This test verifies that it is possible to add runtime option definitions,
+// retrieve them and remove them.
+TEST_F(LibDhcpTest, setRuntimeOptionDefs) {
+ // Create option definitions in 5 namespaces.
+ OptionDefSpaceContainer defs;
+ createRuntimeOptionDefs(5, 100, defs);
+
+ // Apply option definitions.
+ ASSERT_NO_THROW(LibDHCP::setRuntimeOptionDefs(defs));
+
+ // Retrieve all inserted option definitions.
+ testRuntimeOptionDefs(5, 100, true);
+
+ // Attempting to retrieve non existing definitions.
+ EXPECT_FALSE(LibDHCP::getRuntimeOptionDef("option-space-non-existent", 1));
+ EXPECT_FALSE(LibDHCP::getRuntimeOptionDef("option-space-0", 145));
+
+ // Remove all runtime option definitions.
+ ASSERT_NO_THROW(LibDHCP::clearRuntimeOptionDefs());
+
+ // All option definitions should be gone now.
+ testRuntimeOptionDefs(5, 100, false);
+}
+
} // end of anonymous space