45 namespace ph = std::placeholders;
50 struct CtrlDhcp6Hooks {
51 int hooks_index_dhcp6_srv_configured_;
55 hooks_index_dhcp6_srv_configured_ = HooksManager::registerHook(
"dhcp6_srv_configured");
67 static const char* SERVER_DUID_FILE =
"kea-dhcp6-serverid";
78 void signalHandler(
int signo) {
80 if (signo == SIGHUP) {
81 ControlledDhcpv6Srv::processCommand(
"config-reload",
83 }
else if ((signo == SIGTERM) || (signo == SIGINT)) {
84 ControlledDhcpv6Srv::processCommand(
"shutdown",
97 ControlledDhcpv6Srv::init(
const std::string& file_name) {
99 start_ = boost::posix_time::second_clock::universal_time();
107 string reason = comment ? comment->stringValue() :
108 "no details available";
119 signal_set_.reset(
new IOSignalSet(getIOService(), signalHandler));
121 signal_set_->add(SIGINT);
122 signal_set_->add(SIGHUP);
123 signal_set_->add(SIGTERM);
126 void ControlledDhcpv6Srv::cleanup() {
128 getIOService()->poll();
132 ControlledDhcpv6Srv::loadConfigFile(
const std::string& file_name) {
141 if (file_name.empty()) {
144 " Please use -c command line option.");
149 json = parser.
parseFile(file_name, Parser6Context::PARSER_DHCP6);
158 "a map, i.e., start with { and end with } and contain "
159 "at least an entry called 'Dhcp6' that itself is a map. "
161 <<
" is a valid JSON, but its top element is not a map."
162 " Did you forget to add { } around your configuration?");
166 result = ControlledDhcpv6Srv::processCommand(
"config-set", json);
172 "processCommand(\"config-set\", json)");
180 string reason = comment ? comment->stringValue() :
181 "no details available";
184 }
catch (
const std::exception& ex) {
187 CfgMgr::instance().rollback();
190 .arg(file_name).arg(ex.what());
192 << file_name <<
"': " << ex.
what());
196 .arg(MultiThreadingMgr::instance().getMode() ?
"yes" :
"no")
197 .arg(MultiThreadingMgr::instance().getThreadPoolSize())
198 .arg(MultiThreadingMgr::instance().getPacketQueueSize());
204 ControlledDhcpv6Srv::commandShutdownHandler(
const string&,
ConstElementPtr args) {
205 if (!ControlledDhcpv6Srv::getInstance()) {
213 if (args->getType() != Element::map) {
219 if (param->getType() != Element::integer) {
221 "parameter 'exit-value' is not an integer"));
224 exit_value = param->intValue();
228 ControlledDhcpv6Srv::getInstance()->shutdownServer(exit_value);
233 ControlledDhcpv6Srv::commandLibReloadHandler(
const string&,
ConstElementPtr) {
240 MultiThreadingMgr::instance().getThreadPool().reset();
245 HooksManager::prepareUnloadLibraries();
246 static_cast<void>(HooksManager::unloadLibraries());
247 bool multi_threading_enabled =
true;
248 uint32_t thread_count = 0;
249 uint32_t queue_size = 0;
250 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
251 multi_threading_enabled, thread_count, queue_size);
252 bool status = HooksManager::loadLibraries(loaded, multi_threading_enabled);
254 isc_throw(Unexpected,
"Failed to reload hooks libraries "
255 "(WARNING: libreload is deprecated).");
257 }
catch (
const std::exception& ex) {
263 "Hooks libraries successfully reloaded "
264 "(WARNING: libreload is deprecated).");
269 ControlledDhcpv6Srv::commandConfigReloadHandler(
const string&,
272 string file = ControlledDhcpv6Srv::getInstance()->getConfigFile();
275 auto result = loadConfigFile(file);
278 }
catch (
const std::exception& ex) {
285 "Config reload failed: " +
string(ex.what())));
290 ControlledDhcpv6Srv::commandConfigGetHandler(
const string&,
292 ElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
293 string hash = BaseCommandMgr::getHash(config);
294 config->set(
"hash", Element::create(hash));
300 ControlledDhcpv6Srv::commandConfigHashGetHandler(
const string&,
302 ConstElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
303 string hash = BaseCommandMgr::getHash(config);
306 params->set(
"hash", Element::create(hash));
311 ControlledDhcpv6Srv::commandConfigWriteHandler(
const string&,
316 if (args->getType() != Element::map) {
320 if (filename_param) {
321 if (filename_param->getType() != Element::string) {
323 "passed parameter 'filename' is not a string"));
325 filename = filename_param->stringValue();
329 if (filename.empty()) {
332 filename = getConfigFile();
335 if (filename.empty()) {
337 "Please specify filename explicitly."));
344 size = writeConfigFile(filename, cfg);
356 params->set(
"size", Element::create(
static_cast<long long>(size)));
357 params->set(
"filename", Element::create(filename));
360 + filename +
" successful", params));
364 ControlledDhcpv6Srv::commandConfigSetHandler(
const string&,
373 message =
"Missing mandatory 'arguments' parameter.";
375 dhcp6 = args->get(
"Dhcp6");
377 message =
"Missing mandatory 'Dhcp6' parameter.";
378 }
else if (dhcp6->getType() != Element::map) {
379 message =
"'Dhcp6' parameter expected to be a map.";
384 if (message.empty()) {
385 for (
auto obj : args->mapValue()) {
386 const string& obj_name = obj.first;
387 if (obj_name !=
"Dhcp6") {
390 if (message.empty()) {
391 message =
"Unsupported '" + obj_name +
"' parameter";
393 message +=
" (and '" + obj_name +
"')";
397 if (!message.empty()) {
402 if (!message.empty()) {
415 CfgMgr::instance().rollback();
421 Daemon::configureLogger(dhcp6, CfgMgr::instance().getStagingCfg());
425 CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
436 CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
439 CfgMgr::instance().commit();
440 }
else if (CfgMgr::instance().getCurrentCfg()->getSequence() != 0) {
447 CfgMgr::instance().getCurrentCfg()->applyLoggingCfg();
459 ControlledDhcpv6Srv::commandConfigTestHandler(
const string&,
468 message =
"Missing mandatory 'arguments' parameter.";
470 dhcp6 = args->get(
"Dhcp6");
472 message =
"Missing mandatory 'Dhcp6' parameter.";
473 }
else if (dhcp6->getType() != Element::map) {
474 message =
"'Dhcp6' parameter expected to be a map.";
479 if (message.empty()) {
480 for (
auto obj : args->mapValue()) {
481 const string& obj_name = obj.first;
482 if (obj_name !=
"Dhcp6") {
485 if (message.empty()) {
486 message =
"Unsupported '" + obj_name +
"' parameter";
488 message +=
" (and '" + obj_name +
"')";
492 if (!message.empty()) {
497 if (!message.empty()) {
510 CfgMgr::instance().rollback();
513 return (checkConfig(dhcp6));
517 ControlledDhcpv6Srv::commandDhcpDisableHandler(
const std::string&,
519 std::ostringstream message;
520 int64_t max_period = 0;
531 if (args->getType() != Element::map) {
532 message <<
"arguments for the 'dhcp-disable' command must be a map";
537 if (max_period_element) {
539 if (max_period_element->getType() != Element::integer) {
540 message <<
"'max-period' argument must be a number";
544 max_period = max_period_element->intValue();
545 if (max_period <= 0) {
546 message <<
"'max-period' must be positive integer";
552 if (origin_element) {
554 if (origin_element->getType() != Element::string) {
555 message <<
"'origin' argument must be a string";
558 origin = origin_element->stringValue();
559 if (origin ==
"ha-partner") {
560 type = NetworkState::Origin::HA_COMMAND;
561 }
else if (origin !=
"user") {
562 if (origin.empty()) {
563 origin =
"(empty string)";
565 message <<
"invalid value used for 'origin' parameter: "
574 if (message.tellp() == 0) {
575 message <<
"DHCPv6 service disabled";
576 if (max_period > 0) {
577 message <<
" for " << max_period <<
" seconds";
582 network_state_->delayedEnableAll(
static_cast<unsigned>(max_period),
585 network_state_->disableService(type);
596 ControlledDhcpv6Srv::commandDhcpEnableHandler(
const std::string&,
598 std::ostringstream message;
608 if (args->getType() != Element::map) {
609 message <<
"arguments for the 'dhcp-enable' command must be a map";
614 if (origin_element) {
616 if (origin_element->getType() != Element::string) {
617 message <<
"'origin' argument must be a string";
620 origin = origin_element->stringValue();
621 if (origin ==
"ha-partner") {
622 type = NetworkState::Origin::HA_COMMAND;
623 }
else if (origin !=
"user") {
624 if (origin.empty()) {
625 origin =
"(empty string)";
627 message <<
"invalid value used for 'origin' parameter: "
636 if (message.tellp() == 0) {
637 network_state_->enableService(type);
641 "DHCP service successfully enabled"));
649 ControlledDhcpv6Srv::commandVersionGetHandler(
const string&,
ConstElementPtr) {
650 ElementPtr extended = Element::create(Dhcpv6Srv::getVersion(
true));
652 arguments->set(
"extended", extended);
654 Dhcpv6Srv::getVersion(
false),
660 ControlledDhcpv6Srv::commandBuildReportHandler(
const string&,
668 ControlledDhcpv6Srv::commandLeasesReclaimHandler(
const string&,
675 message =
"Missing mandatory 'remove' parameter.";
679 message =
"Missing mandatory 'remove' parameter.";
680 }
else if (remove_name->getType() != Element::boolean) {
681 message =
"'remove' parameter expected to be a boolean.";
683 bool remove_lease = remove_name->boolValue();
684 server_->alloc_engine_->reclaimExpiredLeases6(0, 0, remove_lease);
686 message =
"Reclamation of expired leases is complete.";
694 ControlledDhcpv6Srv::commandServerTagGetHandler(
const std::string&,
696 const std::string& tag =
697 CfgMgr::instance().getCurrentCfg()->getServerTag();
699 response->set(
"server-tag", Element::create(tag));
705 ControlledDhcpv6Srv::commandConfigBackendPullHandler(
const std::string&,
707 auto ctl_info = CfgMgr::instance().getCurrentCfg()->getConfigControlInfo();
716 if (TimerMgr::instance()->isTimerRegistered(
"Dhcp6CBFetchTimer")) {
717 TimerMgr::instance()->cancel(
"Dhcp6CBFetchTimer");
718 TimerMgr::instance()->setup(
"Dhcp6CBFetchTimer");
725 auto srv_cfg = CfgMgr::instance().getCurrentCfg();
726 auto mode = CBControlDHCPv6::FetchMode::FETCH_UPDATE;
727 server_->getCBControl()->databaseConfigFetch(srv_cfg, mode);
728 }
catch (
const std::exception& ex) {
732 "On demand configuration update failed: " +
736 "On demand configuration update successful."));
740 ControlledDhcpv6Srv::commandStatusGetHandler(
const string&,
743 status->set(
"pid", Element::create(
static_cast<int>(getpid())));
745 auto now = boost::posix_time::second_clock::universal_time();
747 if (!start_.is_not_a_date_time()) {
748 auto uptime = now - start_;
749 status->set(
"uptime", Element::create(uptime.total_seconds()));
752 auto last_commit = CfgMgr::instance().getCurrentCfg()->getLastCommitTime();
753 if (!last_commit.is_not_a_date_time()) {
754 auto reload = now - last_commit;
755 status->set(
"reload", Element::create(reload.total_seconds()));
758 auto& mt_mgr = MultiThreadingMgr::instance();
759 if (mt_mgr.getMode()) {
760 status->set(
"multi-threading-enabled", Element::create(
true));
761 status->set(
"thread-pool-size", Element::create(
static_cast<int32_t
>(
762 MultiThreadingMgr::instance().getThreadPoolSize())));
763 status->set(
"packet-queue-size", Element::create(
static_cast<int32_t
>(
764 MultiThreadingMgr::instance().getPacketQueueSize())));
765 ElementPtr queue_stats = Element::createList();
766 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(10)));
767 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(100)));
768 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(1000)));
769 status->set(
"packet-queue-statistics", queue_stats);
772 status->set(
"multi-threading-enabled", Element::create(
false));
775 status->set(
"extended-info-tables",
776 Element::create(LeaseMgrFactory::instance().getExtendedInfoTablesEnabled()));
779 ElementPtr socket_errors(Element::createList());
780 for (
IfacePtr const& interface : IfaceMgr::instance().getIfaces()) {
781 for (std::string
const&
error : interface->getErrors()) {
782 socket_errors->add(Element::create(
error));
788 if (socket_errors->empty()) {
789 sockets->set(
"status", Element::create(
"ready"));
792 CfgMgr::instance().getCurrentCfg()->getCfgIface()->getReconnectCtl());
793 if (reconnect_ctl && reconnect_ctl->retriesLeft()) {
794 sockets->set(
"status", Element::create(
"retrying"));
796 sockets->set(
"status", Element::create(
"failed"));
798 sockets->set(
"errors", socket_errors);
800 status->set(
"sockets", sockets);
806 ControlledDhcpv6Srv::commandStatisticSetMaxSampleCountAllHandler(
const string&,
808 StatsMgr& stats_mgr = StatsMgr::instance();
812 CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal(
813 "statistic-default-sample-count", Element::create(max_samples));
818 ControlledDhcpv6Srv::commandStatisticSetMaxSampleAgeAllHandler(
const string&,
820 StatsMgr& stats_mgr = StatsMgr::instance();
825 CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal(
826 "statistic-default-sample-age", Element::create(max_age));
831 ControlledDhcpv6Srv::processCommand(
const string& command,
833 string txt = args ? args->str() :
"(none)";
836 .arg(command).arg(txt);
842 "Server object not initialized, so can't process command '" +
843 command +
"', arguments: '" + txt +
"'.");
848 if (command ==
"shutdown") {
849 return (srv->commandShutdownHandler(command, args));
851 }
else if (command ==
"libreload") {
852 return (srv->commandLibReloadHandler(command, args));
854 }
else if (command ==
"config-reload") {
855 return (srv->commandConfigReloadHandler(command, args));
857 }
else if (command ==
"config-set") {
858 return (srv->commandConfigSetHandler(command, args));
860 }
else if (command ==
"config-get") {
861 return (srv->commandConfigGetHandler(command, args));
863 }
else if (command ==
"config-hash-get") {
864 return (srv->commandConfigHashGetHandler(command, args));
866 }
else if (command ==
"config-test") {
867 return (srv->commandConfigTestHandler(command, args));
869 }
else if (command ==
"dhcp-disable") {
870 return (srv->commandDhcpDisableHandler(command, args));
872 }
else if (command ==
"dhcp-enable") {
873 return (srv->commandDhcpEnableHandler(command, args));
875 }
else if (command ==
"version-get") {
876 return (srv->commandVersionGetHandler(command, args));
878 }
else if (command ==
"build-report") {
879 return (srv->commandBuildReportHandler(command, args));
881 }
else if (command ==
"leases-reclaim") {
882 return (srv->commandLeasesReclaimHandler(command, args));
884 }
else if (command ==
"config-write") {
885 return (srv->commandConfigWriteHandler(command, args));
887 }
else if (command ==
"server-tag-get") {
888 return (srv->commandServerTagGetHandler(command, args));
890 }
else if (command ==
"config-backend-pull") {
891 return (srv->commandConfigBackendPullHandler(command, args));
893 }
else if (command ==
"status-get") {
894 return (srv->commandStatusGetHandler(command, args));
902 + command +
"': " + ex.
what() +
903 ", params: '" + txt +
"'"));
912 std::ostringstream err;
915 err <<
"Server object not initialized, can't process config.";
932 }
catch (
const std::exception& ex) {
933 err <<
"Failed to process configuration:" << ex.what();
939 DatabaseConnection::db_lost_callback_ =
940 std::bind(&ControlledDhcpv6Srv::dbLostCallback, srv, ph::_1);
942 DatabaseConnection::db_recovered_callback_ =
943 std::bind(&ControlledDhcpv6Srv::dbRecoveredCallback, srv, ph::_1);
945 DatabaseConnection::db_failed_callback_ =
946 std::bind(&ControlledDhcpv6Srv::dbFailedCallback, srv, ph::_1);
948 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
949 string params =
"universe=6";
950 if (cfg_db->getExtendedInfoTablesEnabled()) {
951 params +=
" extended-info-tables=true";
953 cfg_db->setAppendedParameters(params);
954 cfg_db->createManagers();
957 }
catch (
const std::exception& ex) {
958 err <<
"Unable to open database: " << ex.what();
964 const std::string duid_file =
965 std::string(CfgMgr::instance().getDataDir()) +
"/" +
966 std::string(SERVER_DUID_FILE);
967 DuidPtr duid = CfgMgr::instance().getStagingCfg()->getCfgDUID()->create(duid_file);
975 }
catch (
const std::exception& ex) {
976 err <<
"unable to configure server identifier: " << ex.what();
983 }
catch (
const std::exception& ex) {
984 err <<
"Error starting DHCP_DDNS client after server reconfiguration: "
991 Dhcp6to4Ipc::instance().open();
992 }
catch (
const std::exception& ex) {
993 err <<
"error starting DHCPv4-over-DHCPv6 IPC "
994 " after server reconfiguration: " << ex.what();
1001 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
1002 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET6, qc)) {
1004 .arg(IfaceMgr::instance().getPacketQueue6()->getInfoStr());
1007 }
catch (
const std::exception& ex) {
1008 err <<
"Error setting packet queue controls after server reconfiguration: "
1015 CfgIface::open_sockets_failed_callback_ =
1016 std::bind(&ControlledDhcpv6Srv::openSocketsFailedCallback, srv, ph::_1);
1025 CfgMgr::instance().getStagingCfg()->getCfgIface()->
1030 CfgMgr::instance().getStagingCfg()->getCfgExpiration()->
1031 setupTimers(&ControlledDhcpv6Srv::reclaimExpiredLeases,
1032 &ControlledDhcpv6Srv::deleteExpiredReclaimedLeases,
1035 }
catch (
const std::exception& ex) {
1036 err <<
"unable to setup timers for periodically running the"
1037 " reclamation of the expired leases: "
1038 << ex.what() <<
".";
1043 auto ctl_info = CfgMgr::instance().getStagingCfg()->getConfigControlInfo();
1045 long fetch_time =
static_cast<long>(ctl_info->getConfigFetchWaitTime());
1048 if (fetch_time > 0) {
1054 if (!server_->inTestMode()) {
1055 fetch_time = 1000 * fetch_time;
1058 boost::shared_ptr<unsigned> failure_count(
new unsigned(0));
1059 TimerMgr::instance()->
1060 registerTimer(
"Dhcp6CBFetchTimer",
1061 std::bind(&ControlledDhcpv6Srv::cbFetchUpdates,
1062 server_, CfgMgr::instance().getStagingCfg(),
1066 TimerMgr::instance()->setup(
"Dhcp6CBFetchTimer");
1072 LibDHCP::commitRuntimeOptionDefs();
1074 auto notify_libraries = ControlledDhcpv6Srv::finishConfigHookLibraries(config);
1075 if (notify_libraries) {
1076 return (notify_libraries);
1083 CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->initAllocatorsAfterConfigure();
1085 }
catch (
const std::exception& ex) {
1086 err <<
"Error initializing the lease allocators: " << ex.what();
1094 CfgMultiThreading::apply(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading());
1095 }
catch (
const std::exception& ex) {
1096 err <<
"Error applying multi threading settings: "
1112 if (HooksManager::calloutsPresent(
Hooks.hooks_index_dhcp6_srv_configured_)) {
1115 callout_handle->setArgument(
"io_context", srv->
getIOService());
1117 callout_handle->setArgument(
"json_config", config);
1118 callout_handle->setArgument(
"server_config", CfgMgr::instance().getStagingCfg());
1120 HooksManager::callCallouts(
Hooks.hooks_index_dhcp6_srv_configured_,
1124 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1127 callout_handle->getArgument(
"error",
error);
1129 error =
"unknown error";
1144 "Server object not initialized, can't process config.");
1154 ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port ,
1155 uint16_t client_port )
1159 "There is another Dhcpv6Srv instance already.");
1177 CommandMgr::instance().registerCommand(
"build-report",
1178 std::bind(&ControlledDhcpv6Srv::commandBuildReportHandler,
this, ph::_1, ph::_2));
1180 CommandMgr::instance().registerCommand(
"config-backend-pull",
1181 std::bind(&ControlledDhcpv6Srv::commandConfigBackendPullHandler,
this, ph::_1, ph::_2));
1183 CommandMgr::instance().registerCommand(
"config-get",
1184 std::bind(&ControlledDhcpv6Srv::commandConfigGetHandler,
this, ph::_1, ph::_2));
1186 CommandMgr::instance().registerCommand(
"config-hash-get",
1187 std::bind(&ControlledDhcpv6Srv::commandConfigHashGetHandler,
this, ph::_1, ph::_2));
1189 CommandMgr::instance().registerCommand(
"config-reload",
1190 std::bind(&ControlledDhcpv6Srv::commandConfigReloadHandler,
this, ph::_1, ph::_2));
1192 CommandMgr::instance().registerCommand(
"config-set",
1193 std::bind(&ControlledDhcpv6Srv::commandConfigSetHandler,
this, ph::_1, ph::_2));
1195 CommandMgr::instance().registerCommand(
"config-test",
1196 std::bind(&ControlledDhcpv6Srv::commandConfigTestHandler,
this, ph::_1, ph::_2));
1198 CommandMgr::instance().registerCommand(
"config-write",
1199 std::bind(&ControlledDhcpv6Srv::commandConfigWriteHandler,
this, ph::_1, ph::_2));
1201 CommandMgr::instance().registerCommand(
"dhcp-enable",
1202 std::bind(&ControlledDhcpv6Srv::commandDhcpEnableHandler,
this, ph::_1, ph::_2));
1204 CommandMgr::instance().registerCommand(
"dhcp-disable",
1205 std::bind(&ControlledDhcpv6Srv::commandDhcpDisableHandler,
this, ph::_1, ph::_2));
1207 CommandMgr::instance().registerCommand(
"libreload",
1208 std::bind(&ControlledDhcpv6Srv::commandLibReloadHandler,
this, ph::_1, ph::_2));
1210 CommandMgr::instance().registerCommand(
"leases-reclaim",
1211 std::bind(&ControlledDhcpv6Srv::commandLeasesReclaimHandler,
this, ph::_1, ph::_2));
1213 CommandMgr::instance().registerCommand(
"server-tag-get",
1214 std::bind(&ControlledDhcpv6Srv::commandServerTagGetHandler,
this, ph::_1, ph::_2));
1216 CommandMgr::instance().registerCommand(
"shutdown",
1217 std::bind(&ControlledDhcpv6Srv::commandShutdownHandler,
this, ph::_1, ph::_2));
1219 CommandMgr::instance().registerCommand(
"status-get",
1220 std::bind(&ControlledDhcpv6Srv::commandStatusGetHandler,
this, ph::_1, ph::_2));
1222 CommandMgr::instance().registerCommand(
"version-get",
1223 std::bind(&ControlledDhcpv6Srv::commandVersionGetHandler,
this, ph::_1, ph::_2));
1226 CommandMgr::instance().registerCommand(
"statistic-get",
1227 std::bind(&StatsMgr::statisticGetHandler, ph::_1, ph::_2));
1229 CommandMgr::instance().registerCommand(
"statistic-reset",
1230 std::bind(&StatsMgr::statisticResetHandler, ph::_1, ph::_2));
1232 CommandMgr::instance().registerCommand(
"statistic-remove",
1233 std::bind(&StatsMgr::statisticRemoveHandler, ph::_1, ph::_2));
1235 CommandMgr::instance().registerCommand(
"statistic-get-all",
1236 std::bind(&StatsMgr::statisticGetAllHandler, ph::_1, ph::_2));
1238 CommandMgr::instance().registerCommand(
"statistic-reset-all",
1239 std::bind(&StatsMgr::statisticResetAllHandler, ph::_1, ph::_2));
1241 CommandMgr::instance().registerCommand(
"statistic-remove-all",
1242 std::bind(&StatsMgr::statisticRemoveAllHandler, ph::_1, ph::_2));
1244 CommandMgr::instance().registerCommand(
"statistic-sample-age-set",
1245 std::bind(&StatsMgr::statisticSetMaxSampleAgeHandler, ph::_1, ph::_2));
1247 CommandMgr::instance().registerCommand(
"statistic-sample-age-set-all",
1248 std::bind(&ControlledDhcpv6Srv::commandStatisticSetMaxSampleAgeAllHandler,
this, ph::_1, ph::_2));
1250 CommandMgr::instance().registerCommand(
"statistic-sample-count-set",
1251 std::bind(&StatsMgr::statisticSetMaxSampleCountHandler, ph::_1, ph::_2));
1253 CommandMgr::instance().registerCommand(
"statistic-sample-count-set-all",
1254 std::bind(&ControlledDhcpv6Srv::commandStatisticSetMaxSampleCountAllHandler,
this, ph::_1, ph::_2));
1265 MultiThreadingMgr::instance().apply(
false, 0, 0);
1276 timer_mgr_->unregisterTimers();
1279 CommandMgr::instance().closeCommandSocket();
1282 CommandMgr::instance().deregisterCommand(
"build-report");
1283 CommandMgr::instance().deregisterCommand(
"config-backend-pull");
1284 CommandMgr::instance().deregisterCommand(
"config-get");
1285 CommandMgr::instance().deregisterCommand(
"config-hash-get");
1286 CommandMgr::instance().deregisterCommand(
"config-reload");
1287 CommandMgr::instance().deregisterCommand(
"config-set");
1288 CommandMgr::instance().deregisterCommand(
"config-test");
1289 CommandMgr::instance().deregisterCommand(
"config-write");
1290 CommandMgr::instance().deregisterCommand(
"dhcp-disable");
1291 CommandMgr::instance().deregisterCommand(
"dhcp-enable");
1292 CommandMgr::instance().deregisterCommand(
"leases-reclaim");
1293 CommandMgr::instance().deregisterCommand(
"libreload");
1294 CommandMgr::instance().deregisterCommand(
"server-tag-get");
1295 CommandMgr::instance().deregisterCommand(
"shutdown");
1296 CommandMgr::instance().deregisterCommand(
"statistic-get");
1297 CommandMgr::instance().deregisterCommand(
"statistic-get-all");
1298 CommandMgr::instance().deregisterCommand(
"statistic-remove");
1299 CommandMgr::instance().deregisterCommand(
"statistic-remove-all");
1300 CommandMgr::instance().deregisterCommand(
"statistic-reset");
1301 CommandMgr::instance().deregisterCommand(
"statistic-reset-all");
1302 CommandMgr::instance().deregisterCommand(
"statistic-sample-age-set");
1303 CommandMgr::instance().deregisterCommand(
"statistic-sample-age-set-all");
1304 CommandMgr::instance().deregisterCommand(
"statistic-sample-count-set");
1305 CommandMgr::instance().deregisterCommand(
"statistic-sample-count-set-all");
1306 CommandMgr::instance().deregisterCommand(
"status-get");
1307 CommandMgr::instance().deregisterCommand(
"version-get");
1325 ControlledDhcpv6Srv::reclaimExpiredLeases(
const size_t max_leases,
1326 const uint16_t timeout,
1327 const bool remove_lease,
1328 const uint16_t max_unwarned_cycles) {
1330 server_->
alloc_engine_->reclaimExpiredLeases6(max_leases, timeout,
1332 max_unwarned_cycles);
1333 }
catch (
const std::exception& ex) {
1342 ControlledDhcpv6Srv::deleteExpiredReclaimedLeases(
const uint32_t secs) {
1343 server_->
alloc_engine_->deleteExpiredReclaimedLeases6(secs);
1349 ControlledDhcpv6Srv::dbLostCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1350 if (!db_reconnect_ctl) {
1357 if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries() &&
1358 db_reconnect_ctl->alterServiceState()) {
1366 if (!db_reconnect_ctl->retriesLeft() ||
1367 !db_reconnect_ctl->retryInterval()) {
1369 .arg(db_reconnect_ctl->retriesLeft())
1370 .arg(db_reconnect_ctl->retryInterval());
1371 if (db_reconnect_ctl->exitOnFailure()) {
1381 ControlledDhcpv6Srv::dbRecoveredCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1382 if (!db_reconnect_ctl) {
1389 if (db_reconnect_ctl->alterServiceState()) {
1395 db_reconnect_ctl->resetRetries();
1401 ControlledDhcpv6Srv::dbFailedCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1402 if (!db_reconnect_ctl) {
1409 .arg(db_reconnect_ctl->maxRetries());
1411 if (db_reconnect_ctl->exitOnFailure()) {
1419 ControlledDhcpv6Srv::openSocketsFailedCallback(
ReconnectCtlPtr reconnect_ctl) {
1420 if (!reconnect_ctl) {
1427 .arg(reconnect_ctl->maxRetries());
1429 if (reconnect_ctl->exitOnFailure()) {
1435 ControlledDhcpv6Srv::cbFetchUpdates(
const SrvConfigPtr& srv_cfg,
1436 boost::shared_ptr<unsigned> failure_count) {
1444 (*failure_count) = 0;
1446 }
catch (
const std::exception& ex) {
1453 if (++(*failure_count) > 10) {
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
Implements an asynchronous "signal" for IOService driven processing.
static DbCallback db_recovered_callback_
Optional callback function to invoke if an opened connection recovery succeeded.
static DbCallback db_failed_callback_
Optional callback function to invoke if an opened connection recovery failed.
static DbCallback db_lost_callback_
Optional callback function to invoke if an opened connection is lost.
static const std::string FLUSH_RECLAIMED_TIMER_NAME
Name of the timer for flushing reclaimed leases.
static const std::string RECLAIM_EXPIRED_TIMER_NAME
Name of the timer for reclaiming expired leases.
Controlled version of the DHCPv6 server.
void cleanup()
Performs cleanup, immediately before termination.
virtual ~ControlledDhcpv6Srv()
Destructor.
virtual void shutdownServer(int exit_value)
Initiates shutdown procedure for the whole DHCPv6 server.
static ControlledDhcpv6Srv * getInstance()
Returns pointer to the sole instance of Dhcpv6Srv.
void shutdown() override
Instructs the server to shut down.
NetworkStatePtr & getNetworkState()
Returns pointer to the network state used by the server.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
uint16_t getServerPort() const
Get UDP port on which server should listen.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
CBControlDHCPv6Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
static void setIOService(const isc::asiolink::IOServicePtr &io_service)
Sets IO service to be used by the Host Manager.
static void create()
Creates new instance of the HostMgr.
static void destroy()
Destroy lease manager.
static void setIOService(const isc::asiolink::IOServicePtr &io_service)
Sets IO service to be used by the Lease Manager.
Origin
Origin of the network state transition.
@ DB_CONNECTION
The network state is being altered by the DB connection recovery mechanics.
Evaluation context, an interface to the expression evaluation.
isc::data::ElementPtr parseFile(const std::string &filename, ParserType parser_type)
Run the parser on the file specified.
Manages a pool of asynchronous interval timers.
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
void setExitValue(int value)
Sets the exit value.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
Statistics Manager class.
RAII class creating a critical section.
This file contains several functions and constants that are used for handling commands and responses ...
Defines the Dhcp6to4Ipc class.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
isc::data::ConstElementPtr statisticSetMaxSampleCountAllHandler(const isc::data::ConstElementPtr ¶ms)
Handles statistic-sample-count-set-all command.
isc::data::ConstElementPtr statisticSetMaxSampleAgeAllHandler(const isc::data::ConstElementPtr ¶ms)
Handles statistic-sample-age-set-all command.
uint32_t getMaxSampleCountDefault() const
Get default count limit.
const StatsDuration & getMaxSampleAgeDefault() const
Get default duration limit.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_FATAL(LOGGER, MESSAGE)
Macro to conveniently test fatal output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
std::string getConfigReport()
const isc::log::MessageID DHCP6_DB_RECONNECT_NO_DB_CTL
const isc::log::MessageID DHCP6_OPEN_SOCKETS_NO_RECONNECT_CTL
const isc::log::MessageID DHCP6_USING_SERVERID
const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL
const isc::log::MessageID DHCP6_DB_RECONNECT_SUCCEEDED
isc::data::ConstElementPtr configureDhcp6Server(Dhcpv6Srv &server, isc::data::ConstElementPtr config_set, bool check_only, bool extra_checks)
Configure DHCPv6 server (Dhcpv6Srv) with a set of configuration values.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
boost::shared_ptr< DUID > DuidPtr
const int DBG_DHCP6_COMMAND
Debug level used to log receiving commands.
const isc::log::MessageID DHCP6_CB_PERIODIC_FETCH_UPDATES_FAIL
const isc::log::MessageID DHCP6_RECLAIM_EXPIRED_LEASES_FAIL
const isc::log::MessageID DHCP6_OPEN_SOCKETS_FAILED
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
const isc::log::MessageID DHCP6_DYNAMIC_RECONFIGURATION_SUCCESS
const isc::log::MessageID DHCP6_CB_ON_DEMAND_FETCH_UPDATES_FAIL
const isc::log::MessageID DHCP6_COMMAND_RECEIVED
const isc::log::MessageID DHCP6_CB_PERIODIC_FETCH_UPDATES_RETRIES_EXHAUSTED
const isc::log::MessageID DHCP6_NOT_RUNNING
const isc::log::MessageID DHCP6_DYNAMIC_RECONFIGURATION_FAIL
const isc::log::MessageID DHCP6_CONFIG_UNSUPPORTED_OBJECT
const isc::log::MessageID DHCP6_CONFIG_UNRECOVERABLE_ERROR
const isc::log::MessageID DHCP6_CONFIG_RECEIVED
const isc::log::MessageID DHCP6_DB_RECONNECT_DISABLED
const isc::log::MessageID DHCP6_DYNAMIC_RECONFIGURATION
const isc::log::MessageID DHCP6_DEPRECATED
const isc::log::MessageID DHCP6_DB_RECONNECT_LOST_CONNECTION
const isc::log::MessageID DHCP6_HOOKS_LIBS_RELOAD_FAIL
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
const isc::log::MessageID DHCP6_MULTI_THREADING_INFO
const isc::log::MessageID DHCP6_DB_RECONNECT_FAILED
const isc::log::MessageID DHCP6_CONFIG_PACKET_QUEUE
std::vector< HookLibInfo > HookLibsCollection
A storage for information about hook libraries.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
long toSeconds(const StatsDuration &dur)
Returns the number of seconds in a duration.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.