#include <stats/stats_mgr.h>
#include <cfgrpt/config_report.h>
#include <signal.h>
+#include <sstream>
using namespace isc::config;
using namespace isc::dhcp;
return (checkConfig(dhcp6));
}
+ConstElementPtr
+ControlledDhcpv6Srv::commandDhcpDisableHandler(const std::string&,
+ ConstElementPtr args) {
+ std::ostringstream message;
+ int64_t max_period = 0;
+
+ // Parse arguments to see if the 'max-period' parameter has been specified.
+ if (args) {
+ // Arguments must be a map.
+ if (args->getType() != Element::map) {
+ message << "arguments for the 'dhcp-disable' command must be a map";
+
+ } else {
+ ConstElementPtr max_period_element = args->get("max-period");
+ // max-period is optional.
+ if (max_period_element) {
+ // It must be an integer, if specified.
+ if (max_period_element->getType() != Element::integer) {
+ message << "'max-period' argument must be a number";
+
+ } else {
+ // It must be positive integer.
+ max_period = max_period_element->intValue();
+ if (max_period <= 0) {
+ message << "'max-period' must be positive integer";
+ }
+
+ // The user specified that the DHCP service should resume not
+ // later than in max-period seconds. If the 'dhcp-enable' command
+ // is not sent, the DHCP service will resume automatically.
+ network_state_.delayedEnableAll(static_cast<unsigned>(max_period));
+ }
+ }
+ }
+ }
+
+ // No error occurred, so let's disable the service.
+ if (message.tellp() == 0) {
+ network_state_.disableService();
+
+ message << "DHCPv4 service disabled";
+ if (max_period > 0) {
+ message << " for " << max_period << " seconds";
+ }
+ // Success.
+ return (config::createAnswer(CONTROL_RESULT_SUCCESS, message.str()));
+ }
+
+ // Failure.
+ return (config::createAnswer(CONTROL_RESULT_ERROR, message.str()));
+}
+
+ConstElementPtr
+ControlledDhcpv6Srv::commandDhcpEnableHandler(const std::string&, ConstElementPtr) {
+ network_state_.enableService();
+ return (config::createAnswer(CONTROL_RESULT_SUCCESS, "DHCP service successfully enabled"));
+}
+
ConstElementPtr
ControlledDhcpv6Srv::commandVersionGetHandler(const string&, ConstElementPtr) {
ElementPtr extended = Element::create(Dhcpv6Srv::getVersion(true));
} else if (command == "config-test") {
return (srv->commandConfigTestHandler(command, args));
+ } else if (command == "dhcp-disable") {
+ return (srv->commandDhcpDisableHandler(command, args));
+
+ } else if (command == "dhcp-enable") {
+ return (srv->commandDhcpEnableHandler(command, args));
+
} else if (command == "version-get") {
return (srv->commandVersionGetHandler(command, args));
CommandMgr::instance().registerCommand("config-write",
boost::bind(&ControlledDhcpv6Srv::commandConfigWriteHandler, this, _1, _2));
+ CommandMgr::instance().registerCommand("dhcp-disable",
+ boost::bind(&ControlledDhcpv6Srv::commandDhcpDisableHandler, this, _1, _2));
+
+ CommandMgr::instance().registerCommand("dhcp-enable",
+ boost::bind(&ControlledDhcpv6Srv::commandDhcpEnableHandler, this, _1, _2));
+
CommandMgr::instance().registerCommand("leases-reclaim",
boost::bind(&ControlledDhcpv6Srv::commandLeasesReclaimHandler, this, _1, _2));
CommandMgr::instance().deregisterCommand("config-reload");
CommandMgr::instance().deregisterCommand("config-test");
CommandMgr::instance().deregisterCommand("config-write");
+ CommandMgr::instance().deregisterCommand("dhcp-disable");
+ CommandMgr::instance().deregisterCommand("dhcp-enable");
CommandMgr::instance().deregisterCommand("leases-reclaim");
CommandMgr::instance().deregisterCommand("libreload");
CommandMgr::instance().deregisterCommand("shutdown");
commandConfigTestHandler(const std::string& command,
isc::data::ConstElementPtr args);
+ /// @brief A handler for processing 'dhcp-disable' command.
+ ///
+ /// @param command command name (ignored).
+ /// @param args aguments for the command. It must be a map and
+ /// it may include optional 'max-period' parameter.
+ ///
+ /// @return result of the command.
+ isc::data::ConstElementPtr
+ commandDhcpDisableHandler(const std::string& command,
+ isc::data::ConstElementPtr args);
+
+ /// @brief A handler for processing 'dhcp-enable' command.
+ ///
+ /// @param command command name (ignored)
+ /// @param args arguments for the command (ignored).
+ ///
+ /// @return result of the command.
+ isc::data::ConstElementPtr
+ commandDhcpEnableHandler(const std::string& command,
+ isc::data::ConstElementPtr args);
+
/// @Brief handler for processing 'version-get' command
///
/// This handler processes version-get command, which returns
/// Expose internal methods for the sake of testing
using Dhcpv6Srv::receivePacket;
+ using Dhcpv6Srv::network_state_;
};
/// @brief Default control connection timeout.
::remove("test8.json");
}
+// This test verifies if it is possible to disable DHCP service via command.
+TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisable) {
+ createUnixChannelServer();
+ std::string response;
+
+ sendUnixCommand("{ \"command\": \"dhcp-disable\" }", response);
+ ConstElementPtr rsp;
+
+ // The response should be a valid JSON.
+ EXPECT_NO_THROW(rsp = Element::fromJSON(response));
+ ASSERT_TRUE(rsp);
+
+ int status;
+ ConstElementPtr cfg = parseAnswer(status, rsp);
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status);
+
+ EXPECT_FALSE(server_->network_state_.isServiceEnabled());
+}
+
+// This test verifies that it is possible to disable DHCP service for a short
+// period of time, after which the service is automatically enabled.
+TEST_F(CtrlChannelDhcpv6SrvTest, dhcpDisableTemporarily) {
+ createUnixChannelServer();
+ std::string response;
+
+ // Send a command to disable DHCP service for 3 seconds.
+ sendUnixCommand("{"
+ " \"command\": \"dhcp-disable\","
+ " \"arguments\": {"
+ " \"max-period\": 3"
+ " }"
+ "}", response);
+ ConstElementPtr rsp;
+
+ // The response should be a valid JSON.
+ EXPECT_NO_THROW(rsp = Element::fromJSON(response));
+ ASSERT_TRUE(rsp);
+
+ int status;
+ ConstElementPtr cfg = parseAnswer(status, rsp);
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status);
+
+ // The service should be disabled.
+ EXPECT_FALSE(server_->network_state_.isServiceEnabled());
+ // And the timer should be scheduled which counts the time to automatic
+ // enabling of the service.
+ EXPECT_TRUE(server_->network_state_.isDelayedEnableAll());
+}
+
+// This test verifies if it is possible to enable DHCP service via command.
+TEST_F(CtrlChannelDhcpv6SrvTest, dhcpEnable) {
+ createUnixChannelServer();
+ std::string response;
+
+ sendUnixCommand("{ \"command\": \"dhcp-enable\" }", response);
+ ConstElementPtr rsp;
+
+ // The response should be a valid JSON.
+ EXPECT_NO_THROW(rsp = Element::fromJSON(response));
+ ASSERT_TRUE(rsp);
+
+ int status;
+ ConstElementPtr cfg = parseAnswer(status, rsp);
+ EXPECT_EQ(CONTROL_RESULT_SUCCESS, status);
+
+ EXPECT_TRUE(server_->network_state_.isServiceEnabled());
+}
+
/// Verify that concurrent connections over the control channel can be
/// established.
/// @todo Future Kea 1.3 tickets will modify the behavior of the CommandMgr