BIND 10 trac2318, updated. a582a2143369f6848cae1bb82301f5a657293f17 [2318] Create empty options in a parser and adding them to Subnet.

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Oct 24 18:39:07 UTC 2012


The branch, trac2318 has been updated
       via  a582a2143369f6848cae1bb82301f5a657293f17 (commit)
      from  41fa47c50d302aa71e9aee629c28ed9cb4fcd065 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a582a2143369f6848cae1bb82301f5a657293f17
Author: Marcin Siodelski <marcin at isc.org>
Date:   Wed Oct 24 20:38:58 2012 +0200

    [2318] Create empty options in a parser and adding them to Subnet.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/dhcp6/config_parser.cc                |   71 +++++++++++++++++++++++--
 src/bin/dhcp6/tests/config_parser_unittest.cc |   21 ++++++--
 2 files changed, 82 insertions(+), 10 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index b4c8aba..72a1013 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -60,6 +60,8 @@ typedef std::map<string, string> StringStorage;
 /// no subnet object created yet to store them.
 typedef std::vector<Pool6Ptr> PoolStorage;
 
+typedef std::vector<OptionPtr> OptionStorage;
+
 /// @brief Global uint32 parameters that will be used as defaults.
 Uint32Storage uint32_defaults;
 
@@ -451,6 +453,10 @@ public:
     OptionDataParser(const std::string&) {
     }
 
+    void setStorage(OptionStorage* storage) {
+        options_ = storage;
+    }
+
     void build(ConstElementPtr option_value) {
         BOOST_FOREACH(ConfigPair param, option_value->mapValue()) {
             ParserPtr parser;
@@ -461,7 +467,6 @@ public:
                     name_parser->setStorage(&string_values_);
                     parser = name_parser;
                 }
-                // @todo: what if this is NULL pointer. Shouldn't we throw exception?
             } else if (param.first == "code") {
                 boost::shared_ptr<Uint32Parser>
                     code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
@@ -484,6 +489,7 @@ public:
             parser->build(param.second);
             parsers_.push_back(parser);
         }
+        createOption();
     }
 
     void commit() {
@@ -491,9 +497,49 @@ public:
 
 private:
 
+    void createOption() {
+        uint32_t option_code = getUint32Param("code");
+        if (option_code > std::numeric_limits<uint16_t>::max()) {
+            isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
+                      << " exceed " << std::numeric_limits<uint16_t>::max());
+        }
+        std::string option_name = getStringParam("name");
+        if (option_name.empty()) {
+            isc_throw(Dhcp6ConfigError, "Parser error: option name must not be"
+                      << " empty");
+        } else if (option_name.find(" ") != std::string::npos) {
+            isc_throw(Dhcp6ConfigError, "Parser error: option name must not contain"
+                      << " spaces");
+        }
+        /// @todo more sanity checks on option name are needed.
+        OptionPtr option(new Option(Option::V6, static_cast<uint16_t>(option_code),
+                                    OptionBuffer()));
+        options_->push_back(option);
+    }
+
+    std::string getStringParam(const std::string& param_id) const {
+        StringStorage::const_iterator param = string_values_.find(param_id);
+        if (param == string_values_.end()) {
+            isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
+                      << " '" << param_id << "' not specified");
+        }
+        return (param->second);
+    }
+
+    uint32_t getUint32Param(const std::string& param_id) const {
+        Uint32Storage::const_iterator param = uint32_values_.find(param_id);
+        if (param == uint32_values_.end()) {
+            isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
+                      << " '" << param_id << "' not specified");
+        }
+        return (param->second);
+    }
+
     Uint32Storage uint32_values_;
     StringStorage string_values_;
 
+    OptionStorage* options_;
+
     ParserCollection parsers_;
 };
 
@@ -519,15 +565,20 @@ public:
 
         // No need to define FactoryMap here. There's only one type
         // used: Subnet6ConfigParser
-
         BOOST_FOREACH(ConstElementPtr option_value, option_value_list->listValue()) {
 
-            ParserPtr parser(new OptionDataParser("option-data"));
+            boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
+            parser->setStorage(options_);
             parser->build(option_value);
             option_values_.push_back(parser);
         }
     }
 
+    void setStorage(OptionStorage* storage) {
+        options_ = storage;
+    }
+
+
     /// @brief commits subnets definitions.
     ///
     /// Iterates over all Subnet6 parsers. Each parser contains definitions
@@ -552,6 +603,8 @@ public:
         return (new OptionDataListParser(param_name));
     }
 
+    OptionStorage* options_;
+
     ParserCollection option_values_;
 };
 
@@ -596,8 +649,9 @@ public:
                     if (poolParser) {
                         poolParser->setStorage(&pools_);
                     } else {
-                        boost::shared_ptr<OptionDataParser> option_data_parser =
-                            boost::dynamic_pointer_cast<OptionDataParser>(parser);
+                        boost::shared_ptr<OptionDataListParser> option_data_list_parser =
+                            boost::dynamic_pointer_cast<OptionDataListParser>(parser);
+                        option_data_list_parser->setStorage(&options_);
                     }
                 }
             }
@@ -653,6 +707,10 @@ public:
             subnet->addPool6(*it);
         }
 
+        BOOST_FOREACH(OptionPtr option, options_) {
+            subnet->addOption(option);
+        }
+
         CfgMgr::instance().addSubnet6(subnet);
     }
 
@@ -739,6 +797,9 @@ protected:
     /// storage for pools belonging to this subnet
     PoolStorage pools_;
 
+    /// storage for options belonging to this subnet
+    OptionStorage options_;
+
     /// parsers are stored here
     ParserCollection parsers_;
 };
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index f2caff1..f31370f 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -240,7 +240,7 @@ TEST_F(Dhcp6ParserTest, pool_prefix_len) {
     EXPECT_EQ(4000, subnet->getValid());
 }
 
-TEST_F(Dhcp6ParserTest, globalOptionValues) {
+TEST_F(Dhcp6ParserTest, multipleOptionValues) {
     ConstElementPtr x;
     string config = "{ \"interface\": [ \"all\" ],"
         "\"preferred-lifetime\": 3000,"
@@ -249,10 +249,16 @@ TEST_F(Dhcp6ParserTest, globalOptionValues) {
         "\"subnet6\": [ { "
         "    \"pool\": [ \"2001:db8:1::/80\" ],"
         "    \"subnet\": \"2001:db8:1::/64\", "
-        "    \"option-value\": [ { "
-        "        \"name\": \"option_foo\","
-        "        \"code\": 100,"
-        "        \"data\": \"XYZ, 1, 5\" } ]"
+        "    \"option-data\": [ { "
+        "          \"name\": \"option_foo\","
+        "          \"code\": 100,"
+        "          \"data\": \"ABCDEF 01 05\""
+        "        },"
+        "        {"
+        "          \"name\": \"option_foo2\","
+        "          \"code\": 101,"
+        "          \"data\": \"1\""
+        "        } ]"
         " } ],"
         "\"valid-lifetime\": 4000 }";
     cout << config << endl;
@@ -262,6 +268,11 @@ TEST_F(Dhcp6ParserTest, globalOptionValues) {
     EXPECT_NO_THROW(x = configureDhcp6Server(*srv_, json));
 
     ASSERT_TRUE(x);
+
+    Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
+    ASSERT_TRUE(subnet);
+    const Subnet::OptionContainer& options = subnet->getOptions();
+    ASSERT_EQ(2, options.size());
 }
 
 };



More information about the bind10-changes mailing list