45 namespace ph = std::placeholders;
50 struct CtrlDhcp4Hooks {
51 int hooks_index_dhcp4_srv_configured_;
55 hooks_index_dhcp4_srv_configured_ = HooksManager::registerHook(
"dhcp4_srv_configured");
75 void signalHandler(
int signo) {
77 if (signo == SIGHUP) {
78 ControlledDhcpv4Srv::processCommand(
"config-reload",
80 }
else if ((signo == SIGTERM) || (signo == SIGINT)) {
81 ControlledDhcpv4Srv::processCommand(
"shutdown",
94 ControlledDhcpv4Srv::init(
const std::string& file_name) {
96 start_ = boost::posix_time::second_clock::universal_time();
104 string reason = comment ? comment->stringValue() :
105 "no details available";
116 signal_set_.reset(
new IOSignalSet(getIOService(), signalHandler));
118 signal_set_->add(SIGINT);
119 signal_set_->add(SIGHUP);
120 signal_set_->add(SIGTERM);
123 void ControlledDhcpv4Srv::cleanup() {
125 getIOService()->poll();
129 ControlledDhcpv4Srv::loadConfigFile(
const std::string& file_name) {
138 if (file_name.empty()) {
141 " Please use -c command line option.");
146 json = parser.
parseFile(file_name, Parser4Context::PARSER_DHCP4);
155 "a map, i.e., start with { and end with } and contain "
156 "at least an entry called 'Dhcp4' that itself is a map. "
158 <<
" is a valid JSON, but its top element is not a map."
159 " Did you forget to add { } around your configuration?");
163 result = ControlledDhcpv4Srv::processCommand(
"config-set", json);
169 "processCommand(\"config-set\", json)");
177 string reason = comment ? comment->stringValue() :
178 "no details available";
181 }
catch (
const std::exception& ex) {
184 CfgMgr::instance().rollback();
187 .arg(file_name).arg(ex.what());
189 << file_name <<
"': " << ex.
what());
193 .arg(MultiThreadingMgr::instance().getMode() ?
"yes" :
"no")
194 .arg(MultiThreadingMgr::instance().getThreadPoolSize())
195 .arg(MultiThreadingMgr::instance().getPacketQueueSize());
201 ControlledDhcpv4Srv::commandShutdownHandler(
const string&,
ConstElementPtr args) {
202 if (!ControlledDhcpv4Srv::getInstance()) {
210 if (args->getType() != Element::map) {
216 if (param->getType() != Element::integer) {
218 "parameter 'exit-value' is not an integer"));
221 exit_value = param->intValue();
225 ControlledDhcpv4Srv::getInstance()->shutdownServer(exit_value);
230 ControlledDhcpv4Srv::commandLibReloadHandler(
const string&,
ConstElementPtr) {
237 MultiThreadingMgr::instance().getThreadPool().reset();
242 HooksManager::prepareUnloadLibraries();
243 static_cast<void>(HooksManager::unloadLibraries());
244 bool multi_threading_enabled =
true;
245 uint32_t thread_count = 0;
246 uint32_t queue_size = 0;
247 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
248 multi_threading_enabled, thread_count, queue_size);
249 bool status = HooksManager::loadLibraries(loaded, multi_threading_enabled);
251 isc_throw(Unexpected,
"Failed to reload hooks libraries "
252 "(WARNING: libreload is deprecated).");
254 }
catch (
const std::exception& ex) {
260 "Hooks libraries successfully reloaded "
261 "(WARNING: libreload is deprecated).");
266 ControlledDhcpv4Srv::commandConfigReloadHandler(
const string&,
269 string file = ControlledDhcpv4Srv::getInstance()->getConfigFile();
272 auto result = loadConfigFile(file);
275 }
catch (
const std::exception& ex) {
282 "Config reload failed: " +
string(ex.what())));
287 ControlledDhcpv4Srv::commandConfigGetHandler(
const string&,
289 ElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
290 string hash = BaseCommandMgr::getHash(config);
291 config->set(
"hash", Element::create(hash));
297 ControlledDhcpv4Srv::commandConfigHashGetHandler(
const string&,
299 ConstElementPtr config = CfgMgr::instance().getCurrentCfg()->toElement();
301 string hash = BaseCommandMgr::getHash(config);
304 params->set(
"hash", Element::create(hash));
309 ControlledDhcpv4Srv::commandConfigWriteHandler(
const string&,
314 if (args->getType() != Element::map) {
318 if (filename_param) {
319 if (filename_param->getType() != Element::string) {
321 "passed parameter 'filename' is not a string"));
323 filename = filename_param->stringValue();
327 if (filename.empty()) {
330 filename = getConfigFile();
333 if (filename.empty()) {
335 "Please specify filename explicitly."));
342 size = writeConfigFile(filename, cfg);
354 params->set(
"size", Element::create(
static_cast<long long>(size)));
355 params->set(
"filename", Element::create(filename));
358 + filename +
" successful", params));
362 ControlledDhcpv4Srv::commandConfigSetHandler(
const string&,
371 message =
"Missing mandatory 'arguments' parameter.";
373 dhcp4 = args->get(
"Dhcp4");
375 message =
"Missing mandatory 'Dhcp4' parameter.";
376 }
else if (dhcp4->getType() != Element::map) {
377 message =
"'Dhcp4' parameter expected to be a map.";
382 if (message.empty()) {
383 for (
auto obj : args->mapValue()) {
384 const string& obj_name = obj.first;
385 if (obj_name !=
"Dhcp4") {
388 if (message.empty()) {
389 message =
"Unsupported '" + obj_name +
"' parameter";
391 message +=
" (and '" + obj_name +
"')";
395 if (!message.empty()) {
400 if (!message.empty()) {
413 CfgMgr::instance().rollback();
419 Daemon::configureLogger(dhcp4, CfgMgr::instance().getStagingCfg());
423 CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
434 CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
437 CfgMgr::instance().commit();
438 }
else if (CfgMgr::instance().getCurrentCfg()->getSequence() != 0) {
445 CfgMgr::instance().getCurrentCfg()->applyLoggingCfg();
457 ControlledDhcpv4Srv::commandConfigTestHandler(
const string&,
466 message =
"Missing mandatory 'arguments' parameter.";
468 dhcp4 = args->get(
"Dhcp4");
470 message =
"Missing mandatory 'Dhcp4' parameter.";
471 }
else if (dhcp4->getType() != Element::map) {
472 message =
"'Dhcp4' parameter expected to be a map.";
477 if (message.empty()) {
478 for (
auto obj : args->mapValue()) {
479 const string& obj_name = obj.first;
480 if (obj_name !=
"Dhcp4") {
483 if (message.empty()) {
484 message =
"Unsupported '" + obj_name +
"' parameter";
486 message +=
" (and '" + obj_name +
"')";
490 if (!message.empty()) {
495 if (!message.empty()) {
508 CfgMgr::instance().rollback();
511 return (checkConfig(dhcp4));
515 ControlledDhcpv4Srv::commandDhcpDisableHandler(
const std::string&,
517 std::ostringstream message;
518 int64_t max_period = 0;
529 if (args->getType() != Element::map) {
530 message <<
"arguments for the 'dhcp-disable' command must be a map";
535 if (max_period_element) {
537 if (max_period_element->getType() != Element::integer) {
538 message <<
"'max-period' argument must be a number";
542 max_period = max_period_element->intValue();
543 if (max_period <= 0) {
544 message <<
"'max-period' must be positive integer";
550 if (origin_element) {
552 if (origin_element->getType() != Element::string) {
553 message <<
"'origin' argument must be a string";
556 origin = origin_element->stringValue();
557 if (origin ==
"ha-partner") {
558 type = NetworkState::Origin::HA_COMMAND;
559 }
else if (origin !=
"user") {
560 if (origin.empty()) {
561 origin =
"(empty string)";
563 message <<
"invalid value used for 'origin' parameter: "
572 if (message.tellp() == 0) {
573 message <<
"DHCPv4 service disabled";
574 if (max_period > 0) {
575 message <<
" for " << max_period <<
" seconds";
580 network_state_->delayedEnableAll(
static_cast<unsigned>(max_period),
583 network_state_->disableService(type);
594 ControlledDhcpv4Srv::commandDhcpEnableHandler(
const std::string&,
596 std::ostringstream message;
606 if (args->getType() != Element::map) {
607 message <<
"arguments for the 'dhcp-enable' command must be a map";
612 if (origin_element) {
614 if (origin_element->getType() != Element::string) {
615 message <<
"'origin' argument must be a string";
618 origin = origin_element->stringValue();
619 if (origin ==
"ha-partner") {
620 type = NetworkState::Origin::HA_COMMAND;
621 }
else if (origin !=
"user") {
622 if (origin.empty()) {
623 origin =
"(empty string)";
625 message <<
"invalid value used for 'origin' parameter: "
634 if (message.tellp() == 0) {
635 network_state_->enableService(type);
639 "DHCP service successfully enabled"));
647 ControlledDhcpv4Srv::commandVersionGetHandler(
const string&,
ConstElementPtr) {
648 ElementPtr extended = Element::create(Dhcpv4Srv::getVersion(
true));
650 arguments->set(
"extended", extended);
652 Dhcpv4Srv::getVersion(
false),
658 ControlledDhcpv4Srv::commandBuildReportHandler(
const string&,
666 ControlledDhcpv4Srv::commandLeasesReclaimHandler(
const string&,
673 message =
"Missing mandatory 'remove' parameter.";
677 message =
"Missing mandatory 'remove' parameter.";
678 }
else if (remove_name->getType() != Element::boolean) {
679 message =
"'remove' parameter expected to be a boolean.";
681 bool remove_lease = remove_name->boolValue();
682 server_->alloc_engine_->reclaimExpiredLeases4(0, 0, remove_lease);
684 message =
"Reclamation of expired leases is complete.";
692 ControlledDhcpv4Srv::commandServerTagGetHandler(
const std::string&,
694 const std::string& tag =
695 CfgMgr::instance().getCurrentCfg()->getServerTag();
697 response->set(
"server-tag", Element::create(tag));
703 ControlledDhcpv4Srv::commandConfigBackendPullHandler(
const std::string&,
705 auto ctl_info = CfgMgr::instance().getCurrentCfg()->getConfigControlInfo();
714 if (TimerMgr::instance()->isTimerRegistered(
"Dhcp4CBFetchTimer")) {
715 TimerMgr::instance()->cancel(
"Dhcp4CBFetchTimer");
716 TimerMgr::instance()->setup(
"Dhcp4CBFetchTimer");
723 auto srv_cfg = CfgMgr::instance().getCurrentCfg();
724 auto mode = CBControlDHCPv4::FetchMode::FETCH_UPDATE;
725 server_->getCBControl()->databaseConfigFetch(srv_cfg, mode);
726 }
catch (
const std::exception& ex) {
730 "On demand configuration update failed: " +
734 "On demand configuration update successful."));
738 ControlledDhcpv4Srv::commandStatusGetHandler(
const string&,
741 status->set(
"pid", Element::create(
static_cast<int>(getpid())));
743 auto now = boost::posix_time::second_clock::universal_time();
745 if (!start_.is_not_a_date_time()) {
746 auto uptime = now - start_;
747 status->set(
"uptime", Element::create(uptime.total_seconds()));
750 auto last_commit = CfgMgr::instance().getCurrentCfg()->getLastCommitTime();
751 if (!last_commit.is_not_a_date_time()) {
752 auto reload = now - last_commit;
753 status->set(
"reload", Element::create(reload.total_seconds()));
756 auto& mt_mgr = MultiThreadingMgr::instance();
757 if (mt_mgr.getMode()) {
758 status->set(
"multi-threading-enabled", Element::create(
true));
759 status->set(
"thread-pool-size", Element::create(
static_cast<int32_t
>(
760 MultiThreadingMgr::instance().getThreadPoolSize())));
761 status->set(
"packet-queue-size", Element::create(
static_cast<int32_t
>(
762 MultiThreadingMgr::instance().getPacketQueueSize())));
763 ElementPtr queue_stats = Element::createList();
764 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(10)));
765 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(100)));
766 queue_stats->add(Element::create(mt_mgr.getThreadPool().getQueueStat(1000)));
767 status->set(
"packet-queue-statistics", queue_stats);
770 status->set(
"multi-threading-enabled", Element::create(
false));
774 ElementPtr socket_errors(Element::createList());
775 for (
IfacePtr const& interface : IfaceMgr::instance().getIfaces()) {
776 for (std::string
const&
error : interface->getErrors()) {
777 socket_errors->add(Element::create(
error));
783 if (socket_errors->empty()) {
784 sockets->set(
"status", Element::create(
"ready"));
787 CfgMgr::instance().getCurrentCfg()->getCfgIface()->getReconnectCtl());
788 if (reconnect_ctl && reconnect_ctl->retriesLeft()) {
789 sockets->set(
"status", Element::create(
"retrying"));
791 sockets->set(
"status", Element::create(
"failed"));
793 sockets->set(
"errors", socket_errors);
795 status->set(
"sockets", sockets);
801 ControlledDhcpv4Srv::commandStatisticSetMaxSampleCountAllHandler(
const string&,
803 StatsMgr& stats_mgr = StatsMgr::instance();
807 CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal(
808 "statistic-default-sample-count", Element::create(max_samples));
813 ControlledDhcpv4Srv::commandStatisticSetMaxSampleAgeAllHandler(
const string&,
815 StatsMgr& stats_mgr = StatsMgr::instance();
820 CfgMgr::instance().getCurrentCfg()->addConfiguredGlobal(
821 "statistic-default-sample-age", Element::create(max_age));
826 ControlledDhcpv4Srv::processCommand(
const string& command,
828 string txt = args ? args->str() :
"(none)";
831 .arg(command).arg(txt);
837 "Server object not initialized, so can't process command '" +
838 command +
"', arguments: '" + txt +
"'.");
843 if (command ==
"shutdown") {
844 return (srv->commandShutdownHandler(command, args));
846 }
else if (command ==
"libreload") {
847 return (srv->commandLibReloadHandler(command, args));
849 }
else if (command ==
"config-reload") {
850 return (srv->commandConfigReloadHandler(command, args));
852 }
else if (command ==
"config-set") {
853 return (srv->commandConfigSetHandler(command, args));
855 }
else if (command ==
"config-get") {
856 return (srv->commandConfigGetHandler(command, args));
858 }
else if (command ==
"config-hash-get") {
859 return (srv->commandConfigHashGetHandler(command, args));
861 }
else if (command ==
"config-test") {
862 return (srv->commandConfigTestHandler(command, args));
864 }
else if (command ==
"dhcp-disable") {
865 return (srv->commandDhcpDisableHandler(command, args));
867 }
else if (command ==
"dhcp-enable") {
868 return (srv->commandDhcpEnableHandler(command, args));
870 }
else if (command ==
"version-get") {
871 return (srv->commandVersionGetHandler(command, args));
873 }
else if (command ==
"build-report") {
874 return (srv->commandBuildReportHandler(command, args));
876 }
else if (command ==
"leases-reclaim") {
877 return (srv->commandLeasesReclaimHandler(command, args));
879 }
else if (command ==
"config-write") {
880 return (srv->commandConfigWriteHandler(command, args));
882 }
else if (command ==
"server-tag-get") {
883 return (srv->commandServerTagGetHandler(command, args));
885 }
else if (command ==
"config-backend-pull") {
886 return (srv->commandConfigBackendPullHandler(command, args));
888 }
else if (command ==
"status-get") {
889 return (srv->commandStatusGetHandler(command, args));
897 + command +
"': " + ex.
what() +
898 ", params: '" + txt +
"'"));
907 std::ostringstream err;
910 err <<
"Server object not initialized, can't process config.";
927 }
catch (
const std::exception& ex) {
928 err <<
"Failed to process configuration:" << ex.what();
934 DatabaseConnection::db_lost_callback_ =
935 std::bind(&ControlledDhcpv4Srv::dbLostCallback, srv, ph::_1);
937 DatabaseConnection::db_recovered_callback_ =
938 std::bind(&ControlledDhcpv4Srv::dbRecoveredCallback, srv, ph::_1);
940 DatabaseConnection::db_failed_callback_ =
941 std::bind(&ControlledDhcpv4Srv::dbFailedCallback, srv, ph::_1);
943 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
944 string params =
"universe=4";
945 if (cfg_db->getExtendedInfoTablesEnabled()) {
946 params +=
" extended-info-tables=true";
948 cfg_db->setAppendedParameters(params);
949 cfg_db->createManagers();
953 }
catch (
const std::exception& ex) {
954 err <<
"Unable to open database: " << ex.what();
961 }
catch (
const std::exception& ex) {
962 err <<
"Error starting DHCP_DDNS client after server reconfiguration: "
969 Dhcp4to6Ipc::instance().open();
970 }
catch (
const std::exception& ex) {
971 err <<
"error starting DHCPv4-over-DHCPv6 IPC "
972 " after server reconfiguration: " << ex.what();
979 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
980 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET, qc)) {
982 .arg(IfaceMgr::instance().getPacketQueue4()->getInfoStr());
985 }
catch (
const std::exception& ex) {
986 err <<
"Error setting packet queue controls after server reconfiguration: "
993 CfgIface::open_sockets_failed_callback_ =
994 std::bind(&ControlledDhcpv4Srv::openSocketsFailedCallback, srv, ph::_1);
1003 CfgMgr::instance().getStagingCfg()->getCfgIface()->
1005 getInstance()->useBroadcast());
1009 CfgMgr::instance().getStagingCfg()->getCfgExpiration()->
1010 setupTimers(&ControlledDhcpv4Srv::reclaimExpiredLeases,
1011 &ControlledDhcpv4Srv::deleteExpiredReclaimedLeases,
1014 }
catch (
const std::exception& ex) {
1015 err <<
"unable to setup timers for periodically running the"
1016 " reclamation of the expired leases: "
1017 << ex.what() <<
".";
1022 auto ctl_info = CfgMgr::instance().getStagingCfg()->getConfigControlInfo();
1024 long fetch_time =
static_cast<long>(ctl_info->getConfigFetchWaitTime());
1027 if (fetch_time > 0) {
1033 if (!server_->inTestMode()) {
1034 fetch_time = 1000 * fetch_time;
1037 boost::shared_ptr<unsigned> failure_count(
new unsigned(0));
1038 TimerMgr::instance()->
1039 registerTimer(
"Dhcp4CBFetchTimer",
1040 std::bind(&ControlledDhcpv4Srv::cbFetchUpdates,
1041 server_, CfgMgr::instance().getStagingCfg(),
1045 TimerMgr::instance()->setup(
"Dhcp4CBFetchTimer");
1051 LibDHCP::commitRuntimeOptionDefs();
1053 auto notify_libraries = ControlledDhcpv4Srv::finishConfigHookLibraries(config);
1054 if (notify_libraries) {
1055 return (notify_libraries);
1063 CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
1065 }
catch (
const std::exception& ex) {
1066 err <<
"Error initializing the lease allocators: "
1075 CfgMultiThreading::apply(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading());
1076 }
catch (
const std::exception& ex) {
1077 err <<
"Error applying multi threading settings: "
1093 if (HooksManager::calloutsPresent(
Hooks.hooks_index_dhcp4_srv_configured_)) {
1096 callout_handle->setArgument(
"io_context", srv->
getIOService());
1098 callout_handle->setArgument(
"json_config", config);
1099 callout_handle->setArgument(
"server_config", CfgMgr::instance().getStagingCfg());
1101 HooksManager::callCallouts(
Hooks.hooks_index_dhcp4_srv_configured_,
1105 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
1108 callout_handle->getArgument(
"error",
error);
1110 error =
"unknown error";
1125 "Server object not initialized, can't process config.");
1135 ControlledDhcpv4Srv::ControlledDhcpv4Srv(uint16_t server_port ,
1136 uint16_t client_port )
1140 "There is another Dhcpv4Srv instance already.");
1158 CommandMgr::instance().registerCommand(
"build-report",
1159 std::bind(&ControlledDhcpv4Srv::commandBuildReportHandler,
this, ph::_1, ph::_2));
1161 CommandMgr::instance().registerCommand(
"config-backend-pull",
1162 std::bind(&ControlledDhcpv4Srv::commandConfigBackendPullHandler,
this, ph::_1, ph::_2));
1164 CommandMgr::instance().registerCommand(
"config-get",
1165 std::bind(&ControlledDhcpv4Srv::commandConfigGetHandler,
this, ph::_1, ph::_2));
1167 CommandMgr::instance().registerCommand(
"config-hash-get",
1168 std::bind(&ControlledDhcpv4Srv::commandConfigHashGetHandler,
this, ph::_1, ph::_2));
1170 CommandMgr::instance().registerCommand(
"config-reload",
1171 std::bind(&ControlledDhcpv4Srv::commandConfigReloadHandler,
this, ph::_1, ph::_2));
1173 CommandMgr::instance().registerCommand(
"config-set",
1174 std::bind(&ControlledDhcpv4Srv::commandConfigSetHandler,
this, ph::_1, ph::_2));
1176 CommandMgr::instance().registerCommand(
"config-test",
1177 std::bind(&ControlledDhcpv4Srv::commandConfigTestHandler,
this, ph::_1, ph::_2));
1179 CommandMgr::instance().registerCommand(
"config-write",
1180 std::bind(&ControlledDhcpv4Srv::commandConfigWriteHandler,
this, ph::_1, ph::_2));
1182 CommandMgr::instance().registerCommand(
"dhcp-enable",
1183 std::bind(&ControlledDhcpv4Srv::commandDhcpEnableHandler,
this, ph::_1, ph::_2));
1185 CommandMgr::instance().registerCommand(
"dhcp-disable",
1186 std::bind(&ControlledDhcpv4Srv::commandDhcpDisableHandler,
this, ph::_1, ph::_2));
1188 CommandMgr::instance().registerCommand(
"libreload",
1189 std::bind(&ControlledDhcpv4Srv::commandLibReloadHandler,
this, ph::_1, ph::_2));
1191 CommandMgr::instance().registerCommand(
"leases-reclaim",
1192 std::bind(&ControlledDhcpv4Srv::commandLeasesReclaimHandler,
this, ph::_1, ph::_2));
1194 CommandMgr::instance().registerCommand(
"server-tag-get",
1195 std::bind(&ControlledDhcpv4Srv::commandServerTagGetHandler,
this, ph::_1, ph::_2));
1197 CommandMgr::instance().registerCommand(
"shutdown",
1198 std::bind(&ControlledDhcpv4Srv::commandShutdownHandler,
this, ph::_1, ph::_2));
1200 CommandMgr::instance().registerCommand(
"status-get",
1201 std::bind(&ControlledDhcpv4Srv::commandStatusGetHandler,
this, ph::_1, ph::_2));
1203 CommandMgr::instance().registerCommand(
"version-get",
1204 std::bind(&ControlledDhcpv4Srv::commandVersionGetHandler,
this, ph::_1, ph::_2));
1207 CommandMgr::instance().registerCommand(
"statistic-get",
1208 std::bind(&StatsMgr::statisticGetHandler, ph::_1, ph::_2));
1210 CommandMgr::instance().registerCommand(
"statistic-reset",
1211 std::bind(&StatsMgr::statisticResetHandler, ph::_1, ph::_2));
1213 CommandMgr::instance().registerCommand(
"statistic-remove",
1214 std::bind(&StatsMgr::statisticRemoveHandler, ph::_1, ph::_2));
1216 CommandMgr::instance().registerCommand(
"statistic-get-all",
1217 std::bind(&StatsMgr::statisticGetAllHandler, ph::_1, ph::_2));
1219 CommandMgr::instance().registerCommand(
"statistic-reset-all",
1220 std::bind(&StatsMgr::statisticResetAllHandler, ph::_1, ph::_2));
1222 CommandMgr::instance().registerCommand(
"statistic-remove-all",
1223 std::bind(&StatsMgr::statisticRemoveAllHandler, ph::_1, ph::_2));
1225 CommandMgr::instance().registerCommand(
"statistic-sample-age-set",
1226 std::bind(&StatsMgr::statisticSetMaxSampleAgeHandler, ph::_1, ph::_2));
1228 CommandMgr::instance().registerCommand(
"statistic-sample-age-set-all",
1229 std::bind(&ControlledDhcpv4Srv::commandStatisticSetMaxSampleAgeAllHandler,
this, ph::_1, ph::_2));
1231 CommandMgr::instance().registerCommand(
"statistic-sample-count-set",
1232 std::bind(&StatsMgr::statisticSetMaxSampleCountHandler, ph::_1, ph::_2));
1234 CommandMgr::instance().registerCommand(
"statistic-sample-count-set-all",
1235 std::bind(&ControlledDhcpv4Srv::commandStatisticSetMaxSampleCountAllHandler,
this, ph::_1, ph::_2));
1246 MultiThreadingMgr::instance().apply(
false, 0, 0);
1257 timer_mgr_->unregisterTimers();
1260 CommandMgr::instance().closeCommandSocket();
1263 CommandMgr::instance().deregisterCommand(
"build-report");
1264 CommandMgr::instance().deregisterCommand(
"config-backend-pull");
1265 CommandMgr::instance().deregisterCommand(
"config-get");
1266 CommandMgr::instance().deregisterCommand(
"config-hash-get");
1267 CommandMgr::instance().deregisterCommand(
"config-reload");
1268 CommandMgr::instance().deregisterCommand(
"config-set");
1269 CommandMgr::instance().deregisterCommand(
"config-test");
1270 CommandMgr::instance().deregisterCommand(
"config-write");
1271 CommandMgr::instance().deregisterCommand(
"dhcp-disable");
1272 CommandMgr::instance().deregisterCommand(
"dhcp-enable");
1273 CommandMgr::instance().deregisterCommand(
"leases-reclaim");
1274 CommandMgr::instance().deregisterCommand(
"libreload");
1275 CommandMgr::instance().deregisterCommand(
"server-tag-get");
1276 CommandMgr::instance().deregisterCommand(
"shutdown");
1277 CommandMgr::instance().deregisterCommand(
"statistic-get");
1278 CommandMgr::instance().deregisterCommand(
"statistic-get-all");
1279 CommandMgr::instance().deregisterCommand(
"statistic-remove");
1280 CommandMgr::instance().deregisterCommand(
"statistic-remove-all");
1281 CommandMgr::instance().deregisterCommand(
"statistic-reset");
1282 CommandMgr::instance().deregisterCommand(
"statistic-reset-all");
1283 CommandMgr::instance().deregisterCommand(
"statistic-sample-age-set");
1284 CommandMgr::instance().deregisterCommand(
"statistic-sample-age-set-all");
1285 CommandMgr::instance().deregisterCommand(
"statistic-sample-count-set");
1286 CommandMgr::instance().deregisterCommand(
"statistic-sample-count-set-all");
1287 CommandMgr::instance().deregisterCommand(
"status-get");
1288 CommandMgr::instance().deregisterCommand(
"version-get");
1306 ControlledDhcpv4Srv::reclaimExpiredLeases(
const size_t max_leases,
1307 const uint16_t timeout,
1308 const bool remove_lease,
1309 const uint16_t max_unwarned_cycles) {
1311 server_->
alloc_engine_->reclaimExpiredLeases4(max_leases, timeout,
1313 max_unwarned_cycles);
1314 }
catch (
const std::exception& ex) {
1323 ControlledDhcpv4Srv::deleteExpiredReclaimedLeases(
const uint32_t secs) {
1324 server_->
alloc_engine_->deleteExpiredReclaimedLeases4(secs);
1330 ControlledDhcpv4Srv::dbLostCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1331 if (!db_reconnect_ctl) {
1338 if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries() &&
1339 db_reconnect_ctl->alterServiceState()) {
1347 if (!db_reconnect_ctl->retriesLeft() ||
1348 !db_reconnect_ctl->retryInterval()) {
1350 .arg(db_reconnect_ctl->retriesLeft())
1351 .arg(db_reconnect_ctl->retryInterval());
1352 if (db_reconnect_ctl->exitOnFailure()) {
1362 ControlledDhcpv4Srv::dbRecoveredCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1363 if (!db_reconnect_ctl) {
1370 if (db_reconnect_ctl->alterServiceState()) {
1376 db_reconnect_ctl->resetRetries();
1382 ControlledDhcpv4Srv::dbFailedCallback(
ReconnectCtlPtr db_reconnect_ctl) {
1383 if (!db_reconnect_ctl) {
1390 .arg(db_reconnect_ctl->maxRetries());
1392 if (db_reconnect_ctl->exitOnFailure()) {
1400 ControlledDhcpv4Srv::openSocketsFailedCallback(
ReconnectCtlPtr reconnect_ctl) {
1401 if (!reconnect_ctl) {
1408 .arg(reconnect_ctl->maxRetries());
1410 if (reconnect_ctl->exitOnFailure()) {
1416 ControlledDhcpv4Srv::cbFetchUpdates(
const SrvConfigPtr& srv_cfg,
1417 boost::shared_ptr<unsigned> failure_count) {
1425 (*failure_count) = 0;
1427 }
catch (
const std::exception& ex) {
1434 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 DHCPv4 server.
virtual ~ControlledDhcpv4Srv()
Destructor.
static ControlledDhcpv4Srv * getInstance()
Returns pointer to the sole instance of Dhcpv4Srv.
void cleanup()
Performs cleanup, immediately before termination.
virtual void shutdownServer(int exit_value)
Initiates shutdown procedure for the whole DHCPv4 server.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
void shutdown() override
Instructs the server to shut down.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
NetworkStatePtr & getNetworkState()
Returns pointer to the network state used by the server.
NetworkStatePtr network_state_
Holds information about disabled DHCP service and/or disabled subnet/network scopes.
uint16_t getServerPort() const
Get UDP port on which server should listen.
CBControlDHCPv4Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
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 ...
Contains declarations for loggers used by the DHCPv4 server component.
Defines the Dhcp4o6Ipc 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 DHCP4_NOT_RUNNING
const isc::log::MessageID DHCP4_DYNAMIC_RECONFIGURATION_FAIL
const isc::log::MessageID DHCP4_CONFIG_RECEIVED
const isc::log::MessageID DHCP4_DYNAMIC_RECONFIGURATION_SUCCESS
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
const isc::log::MessageID DHCP4_DB_RECONNECT_NO_DB_CTL
const isc::log::MessageID DHCP4_CB_PERIODIC_FETCH_UPDATES_RETRIES_EXHAUSTED
const isc::log::MessageID DHCP4_CONFIG_PACKET_QUEUE
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
const isc::log::MessageID DHCP4_CB_ON_DEMAND_FETCH_UPDATES_FAIL
const isc::log::MessageID DHCP4_CONFIG_LOAD_FAIL
const int DBG_DHCP4_COMMAND
Debug level used to log receiving commands.
const isc::log::MessageID DHCP4_HOOKS_LIBS_RELOAD_FAIL
const isc::log::MessageID DHCP4_DB_RECONNECT_DISABLED
const isc::log::MessageID DHCP4_CONFIG_UNRECOVERABLE_ERROR
const isc::log::MessageID DHCP4_DEPRECATED
const isc::log::MessageID DHCP4_DB_RECONNECT_SUCCEEDED
isc::data::ConstElementPtr configureDhcp4Server(Dhcpv4Srv &server, isc::data::ConstElementPtr config_set, bool check_only, bool extra_checks)
Configure DHCPv4 server (Dhcpv4Srv) with a set of configuration values.
const isc::log::MessageID DHCP4_COMMAND_RECEIVED
const isc::log::MessageID DHCP4_MULTI_THREADING_INFO
const isc::log::MessageID DHCP4_OPEN_SOCKETS_NO_RECONNECT_CTL
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
const isc::log::MessageID DHCP4_DB_RECONNECT_FAILED
const isc::log::MessageID DHCP4_OPEN_SOCKETS_FAILED
const isc::log::MessageID DHCP4_DYNAMIC_RECONFIGURATION
const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_FAIL
const isc::log::MessageID DHCP4_CONFIG_UNSUPPORTED_OBJECT
const isc::log::MessageID DHCP4_CB_PERIODIC_FETCH_UPDATES_FAIL
const isc::log::MessageID DHCP4_DB_RECONNECT_LOST_CONNECTION
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.