]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3477] Moved to control-sockets
authorFrancis Dupont <fdupont@isc.org>
Thu, 4 Jul 2024 14:33:30 +0000 (16:33 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 1 Aug 2024 07:23:53 +0000 (09:23 +0200)
src/bin/dhcp4/json_config_parser.cc
src/bin/dhcp4/tests/get_config_unittest.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/tests/get_config_unittest.cc
src/bin/dhcp6/tests/parser_unittest.cc
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
src/lib/dhcpsrv/parsers/dhcp_parsers.h
src/lib/dhcpsrv/parsers/simple_parser4.cc
src/lib/dhcpsrv/parsers/simple_parser6.cc
src/lib/dhcpsrv/srv_config.cc
src/lib/dhcpsrv/srv_config.h

index 40fc565277740aec253439160376eb0199c44271..9b8a22d6d59299c35157082ac9209c37cff3c025 100644 (file)
@@ -389,9 +389,17 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
 
         ConstElementPtr control_socket = mutable_cfg->get("control-socket");
         if (control_socket) {
-            parameter_name = "control-socket";
-            ControlSocketParser parser;
-            parser.parse(*srv_config, control_socket);
+            mutable_cfg->remove("control-socket");
+            ElementPtr l = Element::createList();
+            l->add(UserContext::toElement(control_socket));
+            mutable_cfg->set("control-sockets", l);
+        }
+
+        ConstElementPtr control_sockets = mutable_cfg->get("control-sockets");
+        if (control_sockets) {
+            parameter_name = "control-sockets";
+            ControlSocketsParser parser;
+            parser.parse(*srv_config, control_sockets);
         }
 
         ConstElementPtr multi_threading = mutable_cfg->get("multi-threading");
index 5e3149b9c58be2516b3c206ab65ac589ebb8707e..891a28881112873cbae99d93776f99d6fd485049 100644 (file)
@@ -10895,13 +10895,15 @@ const char* UNPARSED_CONFIGS[] = {
 "                }\n"
 "            }\n"
 "        ],\n"
-"        \"control-socket\": {\n"
-"            \"socket-name\": \"/tmp/kea4-ctrl-socket\",\n"
-"            \"socket-type\": \"unix\",\n"
-"            \"user-context\": {\n"
-"                \"comment\": \"Indirect comment\"\n"
+"        \"control-sockets\": [\n"
+"            {\n"
+"                \"socket-name\": \"/tmp/kea4-ctrl-socket\",\n"
+"                \"socket-type\": \"unix\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"Indirect comment\"\n"
+"                }\n"
 "            }\n"
-"        },\n"
+"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
index 80d5f1f34cd5fc28f32a4ded2ed74082791e4d88..7eb9c48d16649bd03dc70dc2593e660deecfbbf8 100644 (file)
@@ -506,11 +506,18 @@ processDhcp6Config(isc::data::ConstElementPtr config_set) {
 
         ConstElementPtr control_socket = mutable_cfg->get("control-socket");
         if (control_socket) {
-            parameter_name = "control-socket";
-            ControlSocketParser parser;
-            parser.parse(*srv_config, control_socket);
+            mutable_cfg->remove("control-socket");
+            ElementPtr l = Element::createList();
+            l->add(UserContext::toElement(control_socket));
+            mutable_cfg->set("control-sockets", l);
         }
 
+        ConstElementPtr control_sockets = mutable_cfg->get("control-sockets");
+        if (control_sockets) {
+            parameter_name = "control-sockets";
+            ControlSocketsParser parser;
+            parser.parse(*srv_config, control_sockets);
+        }
         ConstElementPtr multi_threading = mutable_cfg->get("multi-threading");
         if (multi_threading) {
             parameter_name = "multi-threading";
index 83c306f56c97cc841e1a4cbd3550ca70921ff487..63a7d066909a3f26f7aebc240c777cc32730ae44 100644 (file)
@@ -9594,13 +9594,15 @@ const char* UNPARSED_CONFIGS[] = {
 "                }\n"
 "            }\n"
 "        ],\n"
-"        \"control-socket\": {\n"
-"            \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n"
-"            \"socket-type\": \"unix\",\n"
-"            \"user-context\": {\n"
-"                \"comment\": \"Indirect comment\"\n"
+"        \"control-sockets\": [\n"
+"            {\n"
+"                \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n"
+"                \"socket-type\": \"unix\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"Indirect comment\"\n"
+"                }\n"
 "            }\n"
-"        },\n"
+"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
index 78091d32d6066250606a3b7ce5fb01883affdb7c..5ff99d3d793db065a74cdeda1876b0a8af24ec30 100644 (file)
@@ -985,7 +985,7 @@ TEST_F(TrailingCommasTest, tests) {
     addLog("<string>:40.12");
     addLog("<string>:42.28");
     addLog("<string>:43.8");
-    addLog("<string>:54.37");
+    addLog("<string>:54.38");
     addLog("<string>:55.12");
     addLog("<string>:58.16");
     addLog("<string>:59.8");
index aeb794250025dfa501707208bd9eba1a23d50487..56e17509fcdf9c046247ec2b81ffa95fb3824427 100644 (file)
@@ -73,19 +73,54 @@ MACSourcesListConfigParser::parse(CfgMACSource& mac_sources, ConstElementPtr val
     }
 }
 
-// ******************** ControlSocketParser *************************
-void ControlSocketParser::parse(SrvConfig& srv_cfg, isc::data::ConstElementPtr value) {
-    if (!value) {
+// ******************** ControlSocketsParser *************************
+void ControlSocketsParser::parse(SrvConfig& srv_cfg, ConstElementPtr value) {
+    if (value->getType() != Element::list) {
         // Sanity check: not supposed to fail.
-        isc_throw(DhcpConfigError, "Logic error: specified control-socket is null");
+        isc_throw(DhcpConfigError,
+                  "Specified control-sockets is expected to be a list");
     }
-
-    if (value->getType() != Element::map) {
-        // Sanity check: not supposed to fail.
-        isc_throw(DhcpConfigError, "Specified control-socket is expected to be a map"
-                  ", i.e. a structure defined within { }");
+    bool seen_unix(false);
+    bool seen_http(false);
+    for (ConstElementPtr socket : value->listValue()) {
+        if (socket->getType() != Element::map) {
+            // Sanity check: not supposed to fail.
+            isc_throw(DhcpConfigError,
+                      "Specified control-sockets is expected to be a list of maps");
+        }
+        ConstElementPtr socket_type = socket->get("socket-type");
+        if (!socket_type) {
+            isc_throw(DhcpConfigError,
+                      "'socket-type' parameter is mandatory in control-sockets items");
+        }
+        if (socket_type->getType() != Element::string) {
+            // Sanity check: not supposed to fail.
+            isc_throw(DhcpConfigError,
+                      "'socket-type' parameter is expected to be a string");
+        }
+        string type = socket_type->stringValue();
+        if (type == "unix") {
+            if (seen_unix) {
+                isc_throw(DhcpConfigError,
+                          "control socket of type 'unix' already configured");
+            }
+            seen_unix = true;
+            srv_cfg.setControlSocketInfo(socket);
+        } else if ((type == "http") || (type == "https")) {
+            if (seen_http) {
+                isc_throw(DhcpConfigError,
+                          "control socket of type 'http' or 'https'"
+                          " already configured");
+            }
+            seen_http = true;
+            srv_cfg.setHttpControlSocketInfo(socket);
+        } else {
+            // Sanity check: not supposed to fail.
+            isc_throw(DhcpConfigError,
+                      "unsupported 'socket-type': '" << type
+                      << "' not 'unix', 'http' or 'https'");
+        }
     }
-    srv_cfg.setControlSocketInfo(value);
 }
 
 // ******************************** OptionDefParser ****************************
index 577271fcd1d3501e024e46dcae1f4e6407e2e148..5dda030fb2b65e2f1026856f3ccbcdf806d32c7b 100644 (file)
@@ -204,18 +204,18 @@ public:
     void parse(CfgMACSource& mac_sources, isc::data::ConstElementPtr value);
 };
 
-/// @brief Parser for the control-socket structure
+/// @brief Parser for the control-sockets structure
 ///
-/// It does not parse anything, simply stores the element in
+/// It does not parse anything, simply stores elements in
 /// the staging config.
-class ControlSocketParser : public isc::data::SimpleParser {
+class ControlSocketsParser : public isc::data::SimpleParser {
 public:
-    /// @brief "Parses" control-socket structure
+    /// @brief "Parses" control-sockets structure
     ///
-    /// Since the SrvConfig structure takes the socket definition
+    /// Since the SrvConfig structure takes the socket definitions
     /// as ConstElementPtr, there's really nothing to parse here.
     /// It only does basic sanity checks and throws DhcpConfigError
-    /// if the value is null or is not a map.
+    /// if the syntax is not valid.
     ///
     /// @param srv_cfg parsed values will be stored here
     /// @param value pointer to the content of parsed values
index 845025e234b4dadb52894a8e142cb9c51d248016..16664194416ba08716567710b9f464420b33344f 100644 (file)
@@ -54,7 +54,6 @@ const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
     { "hooks-libraries",                  Element::list },
     { "expired-leases-processing",        Element::map },
     { "dhcp4o6-port",                     Element::integer },
-    { "control-socket",                   Element::map },
     { "control-sockets",                  Element::list },
     { "dhcp-queue-control",               Element::map },
     { "dhcp-ddns",                        Element::map },
index e5b0c079e07c40febb94c75850510a2d381a619c..c0a2d349ec39550f91fa5b485514fe04149676ef 100644 (file)
@@ -60,7 +60,6 @@ const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = {
     { "expired-leases-processing",        Element::map },
     { "server-id",                        Element::map },
     { "dhcp4o6-port",                     Element::integer },
-    { "control-socket",                   Element::map },
     { "control-sockets",                  Element::list },
     { "dhcp-queue-control",               Element::map },
     { "dhcp-ddns",                        Element::map },
index 0227f64b4bb6b791ac72ad3bdd44041e55be29ae..57d6f1617cba05064abf61d7acf74652b7c92ee9 100644 (file)
@@ -295,13 +295,6 @@ SrvConfig::mergeGlobalMaps(SrvConfig& other) {
             parser.parse(compatibility, *this);
             addConfiguredGlobal("compatibility", compatibility);
         }
-        ConstElementPtr control_socket = config->get("control-socket");
-        parameter_name = "control-socket";
-        if (control_socket) {
-            ControlSocketParser parser;
-            parser.parse(*this, control_socket);
-            addConfiguredGlobal("control-socket", control_socket);
-        }
         ElementPtr dhcp_ddns = boost::const_pointer_cast<Element>(config->get("dhcp-ddns"));
         parameter_name = "dhcp-ddns";
         if (dhcp_ddns) {
@@ -900,9 +893,16 @@ SrvConfig::toElement() const {
     if (family == AF_INET6) {
         dhcp->set("mac-sources", cfg_mac_source_.toElement());
     }
-    // Set control-socket (skip if null as empty is not legal)
-    if (!isNull(control_socket_)) {
-        dhcp->set("control-socket", UserContext::toElement(control_socket_));
+    // Set control-sockets.
+    ElementPtr control_sockets = Element::createList();
+    if (!isNull(unix_control_socket_)) {
+        control_sockets->add(UserContext::toElement(unix_control_socket_));
+    }
+    if (!isNull(http_control_socket_)) {
+        control_sockets->add(UserContext::toElement(http_control_socket_));
+    }
+    if (!control_sockets->empty()) {
+        dhcp->set("control-sockets", control_sockets);
     }
     // Set client-classes
     ConstElementPtr client_classes = class_dictionary_->toElement();
index 69c6cb9318f7edccecd08339ac13aa396f50b63b..6384b9601a810cad4e82ceea472b64317daa0791 100644 (file)
@@ -530,18 +530,32 @@ public:
         return (cfg_mac_source_);
     }
 
-    /// @brief Returns information about control socket
+    /// @brief Returns information about UNIX control socket
     ///
     /// @return pointer to the Element that holds control-socket map
     const isc::data::ConstElementPtr getControlSocketInfo() const {
-        return (control_socket_);
+        return (unix_control_socket_);
     }
 
-    /// @brief Sets information about the control socket
+    /// @brief Sets information about the UNIX control socket
     ///
     /// @param control_socket Element that holds control-socket map
     void setControlSocketInfo(const isc::data::ConstElementPtr& control_socket) {
-        control_socket_ = control_socket;
+        unix_control_socket_ = control_socket;
+    }
+
+    /// @brief Returns information about HTTP/HTTPS control socket
+    ///
+    /// @return pointer to the Element that holds control-socket map
+    const isc::data::ConstElementPtr getHttpControlSocketInfo() const {
+        return (http_control_socket_);
+    }
+
+    /// @brief Sets information about the HTTP/HTTPS control socket
+    ///
+    /// @param control_socket Element that holds control-socket map
+    void setHttpControlSocketInfo(const isc::data::ConstElementPtr& control_socket) {
+        http_control_socket_ = control_socket;
     }
 
     /// @brief Returns DHCP queue control information
@@ -897,7 +911,8 @@ public:
         ignore_dhcp_server_identifier_ = false;
         ignore_rai_link_selection_ = false;
         exclude_first_last_24_ = false;
-        control_socket_.reset();
+        unix_control_socket_.reset();
+        http_control_socket_.reset();
         d2_client_config_.reset(new D2ClientConfig());
         cfg_expiration_.reset(new CfgExpiration());
         dhcp_multi_threading_.reset();
@@ -1175,8 +1190,11 @@ private:
     /// DHCPv6.
     CfgHostOperationsPtr cfg_host_operations6_;
 
-    /// @brief Pointer to the control-socket information
-    isc::data::ConstElementPtr control_socket_;
+    /// @brief Pointer to the UNIX control-socket information
+    isc::data::ConstElementPtr unix_control_socket_;
+
+    /// @brief Pointer to the HTTP control-socket information
+    isc::data::ConstElementPtr http_control_socket_;
 
     /// @brief Pointer to the dhcp-queue-control information
     isc::data::ConstElementPtr dhcp_queue_control_;