Parcourir la source

[3436] D2CfgMgr now validates top level params

D2CfgMgr::buildParams now validates all of the
top level params prior to calling the D2Params
constructor.  This allows element position info
to be included in error logging.
Thomas Markwalder il y a 11 ans
Parent
commit
1e69c03467
3 fichiers modifiés avec 80 ajouts et 11 suppressions
  1. 65 11
      src/bin/d2/d2_cfg_mgr.cc
  2. 11 0
      src/bin/d2/d2_cfg_mgr.h
  3. 4 0
      src/bin/d2/tests/d2_cfg_mgr_unittests.cc

+ 65 - 11
src/bin/d2/d2_cfg_mgr.cc

@@ -202,31 +202,85 @@ D2CfgMgr::buildParams(isc::data::ConstElementPtr params_config) {
     // This populate the context scalar stores with all of the parameters.
     DCfgMgrBase::buildParams(params_config);
 
-    // Fetch the parameters from the context to create the D2Params.
+    // Fetch and validate the parameters from the context to create D2Params.
+    // We validate them here rather than just relying on D2Param constructor
+    // so we can spit out config text position info with errors.
+
+    // Fetch and validate io_address.
     D2CfgContextPtr context = getD2CfgContext();
     isc::dhcp::StringStoragePtr strings = context->getStringStorage();
     asiolink::IOAddress ip_address(strings->
                                    getOptionalParam("ip_address",
                                                     D2Params::DFT_IP_ADDRESS));
 
+    if ((ip_address.toText() == "0.0.0.0") || (ip_address.toText() == "::")) {
+        isc_throw(D2CfgError, "IP address cannot be \"" << ip_address << "\" : "
+                   << strings->getPosition("ip_address"));
+    }
+
+    // Fetch and validate port.
     isc::dhcp::Uint32StoragePtr ints = context->getUint32Storage();
     uint32_t port = ints->getOptionalParam("port", D2Params::DFT_PORT);
 
+    if (port == 0) {
+        isc_throw(D2CfgError, "port cannot be 0 : "
+                  << ints->getPosition("port"));
+    }
+
+    // Fetch and validate dns_server_timeout.
     uint32_t dns_server_timeout
         = ints->getOptionalParam("dns_server_timeout",
                                  D2Params::DFT_DNS_SERVER_TIMEOUT);
 
-    dhcp_ddns::NameChangeProtocol ncr_protocol
-        = dhcp_ddns::stringToNcrProtocol(strings->
-                                         getOptionalParam("ncr_protocol",
-                                                          D2Params::
-                                                          DFT_NCR_PROTOCOL));
-    dhcp_ddns::NameChangeFormat ncr_format
-        = dhcp_ddns::stringToNcrFormat(strings->
+    if (dns_server_timeout < 1) {
+        isc_throw(D2CfgError, "DNS server timeout must be larger than 0 : "
+                  << ints->getPosition("dns_server_timeout"));
+    }
+
+    // Fetch and validate ncr_protocol.
+    dhcp_ddns::NameChangeProtocol ncr_protocol;
+    try {
+        ncr_protocol = dhcp_ddns::
+                       stringToNcrProtocol(strings->
+                                           getOptionalParam("ncr_protocol",
+                                                            D2Params::
+                                                            DFT_NCR_PROTOCOL));
+    } catch (const std::exception& ex) {
+        isc_throw(D2CfgError, "ncr_protocol : "
+                  << ex.what() << " : "
+                  << strings->getPosition("ncr_protocol"));
+    }
+
+    if (ncr_protocol != dhcp_ddns::NCR_UDP) {
+        isc_throw(D2CfgError, "ncr_protocol : "
+                  << dhcp_ddns::ncrProtocolToString(ncr_protocol)
+                  << " is not yet supported : "
+                  << strings->getPosition("ncr_protocol"));
+    }
+
+    // Fetch and validate ncr_format.
+    dhcp_ddns::NameChangeFormat ncr_format;
+    try {
+        ncr_format = dhcp_ddns::
+                     stringToNcrFormat(strings->
                                        getOptionalParam("ncr_format",
-                                                          D2Params::
-                                                          DFT_NCR_FORMAT));
-    // Attempt to create the new client config.
+                                                        D2Params::
+                                                        DFT_NCR_FORMAT));
+    } catch (const std::exception& ex) {
+        isc_throw(D2CfgError, "ncr_format : "
+                  << ex.what() << " : "
+                  << strings->getPosition("ncr_format"));
+    }
+
+    if (ncr_format != dhcp_ddns::FMT_JSON) {
+        isc_throw(D2CfgError, "NCR Format:"
+                  << dhcp_ddns::ncrFormatToString(ncr_format)
+                  << " is not yet supported : "
+                  << strings->getPosition("ncr_format"));
+    }
+
+    // Attempt to create the new client config. This ought to fly as
+    // we already validated everything.
     D2ParamsPtr params(new D2Params(ip_address, port, dns_server_timeout,
                                     ncr_protocol, ncr_format));
 

+ 11 - 0
src/bin/d2/d2_cfg_mgr.h

@@ -245,7 +245,18 @@ protected:
     /// parameter's id and then invoking its build method passing in the
     /// parameter's configuration value.
     ///
+    /// It then fetches the parameters, validating their values and if
+    /// valid instantiates a D2Params instance.  Invalid values result in
+    /// a throw.
+    ///
     /// @param params_config set of scalar configuration elements to parse
+    ///
+    /// @throw D2CfgError if any of the following are true:
+    /// -# ip_address is 0.0.0.0 or ::
+    /// -# port is 0
+    /// -# dns_server_timeout is < 1
+    /// -# ncr_protocol is invalid, currently only NCR_UDP is supported
+    /// -# ncr_format is invalid, currently only FMT_JSON is supported
     virtual void buildParams(isc::data::ConstElementPtr params_config);
 
     /// @brief Given an element_id returns an instance of the appropriate

+ 4 - 0
src/bin/d2/tests/d2_cfg_mgr_unittests.cc

@@ -472,6 +472,10 @@ TEST_F(D2CfgMgrTest, invalidEntry) {
     config = makeParamsConfigString ("127.0.0.1", 777, 333, "BOGUS", "JSON");
     runConfig(config, SHOULD_FAIL);
 
+    // Unsupported protocol
+    config = makeParamsConfigString ("127.0.0.1", 777, 333, "TCP", "JSON");
+    runConfig(config, SHOULD_FAIL);
+
     // Invalid format
     config = makeParamsConfigString ("127.0.0.1", 777, 333, "UDP", "BOGUS");
     runConfig(config, SHOULD_FAIL);