49namespace ph = std::placeholders;
 
   54struct CtrlDhcp4Hooks {
 
   55    int hooks_index_dhcp4_srv_configured_;
 
   79void signalHandler(
int signo) {
 
   81    if (signo == SIGHUP) {
 
   83    } 
else if ((signo == SIGTERM) || (signo == SIGINT)) {
 
   98    start_ = boost::posix_time::second_clock::universal_time();
 
  106        string reason = comment ? comment->stringValue() :
 
  107            "no details available";
 
 
  136        if (file_name.empty()) {
 
  139                      " Please use -c command line option.");
 
  153                      "a map, i.e., start with { and end with } and contain " 
  154                      "at least an entry called 'Dhcp4' that itself is a map. " 
  156                      << 
" is a valid JSON, but its top element is not a map." 
  157                      " Did you forget to add { } around your configuration?");
 
  167                      "process command \"config-set\"");
 
  175            string reason = comment ? comment->stringValue() :
 
  176                "no details available";
 
  179    } 
catch (
const std::exception& ex) {
 
  185            .arg(file_name).arg(ex.what());
 
  187                  << file_name << 
"': " << ex.what());
 
 
  199ControlledDhcpv4Srv::commandShutdownHandler(
const string&, 
ConstElementPtr args) {
 
  216                                     "parameter 'exit-value' is not an integer"));
 
  219            exit_value = param->intValue();
 
  228ControlledDhcpv4Srv::commandConfigReloadHandler(
const string&,
 
  237    } 
catch (
const std::exception& ex) {
 
  244                             "Config reload failed: " + 
string(ex.what())));
 
  249ControlledDhcpv4Srv::commandConfigGetHandler(
const string&,
 
  259ControlledDhcpv4Srv::commandConfigHashGetHandler(
const string&,
 
  271ControlledDhcpv4Srv::commandConfigWriteHandler(
const string&,
 
  280        if (filename_param) {
 
  283                                     "passed parameter 'filename' is not a string"));
 
  285            filename = filename_param->stringValue();
 
  289    if (filename.empty()) {
 
  293        if (filename.empty()) {
 
  295                                 "Please specify filename explicitly."));
 
  300        } 
catch (
const isc::Exception& ex) {
 
  301            std::ostringstream msg;
 
  302            msg << 
"not allowed to write config into " << filename
 
  303                << 
": " << ex.
what();
 
  313    } 
catch (
const isc::Exception& ex) {
 
  328                         + filename + 
" successful", params));
 
  332ControlledDhcpv4Srv::commandConfigSetHandler(
const string&,
 
  341        message = 
"Missing mandatory 'arguments' parameter.";
 
  343        dhcp4 = args->get(
"Dhcp4");
 
  345            message = 
"Missing mandatory 'Dhcp4' parameter.";
 
  347            message = 
"'Dhcp4' parameter expected to be a map.";
 
  352    if (message.empty()) {
 
  353        for (
auto const& obj : args->mapValue()) {
 
  354            const string& obj_name = obj.first;
 
  355            if (obj_name != 
"Dhcp4") {
 
  358                if (message.empty()) {
 
  359                    message = 
"Unsupported '" + obj_name + 
"' parameter";
 
  361                    message += 
" (and '" + obj_name + 
"')";
 
  365        if (!message.empty()) {
 
  370    if (!message.empty()) {
 
  378    MultiThreadingCriticalSection cs;
 
  427    } 
catch (
const std::exception& ex) {
 
  428        std::ostringstream err;
 
  429        err << 
"Error initializing hooks: " 
  438ControlledDhcpv4Srv::commandConfigTestHandler(
const string&,
 
  447        message = 
"Missing mandatory 'arguments' parameter.";
 
  449        dhcp4 = args->get(
"Dhcp4");
 
  451            message = 
"Missing mandatory 'Dhcp4' parameter.";
 
  453            message = 
"'Dhcp4' parameter expected to be a map.";
 
  458    if (message.empty()) {
 
  459        for (
auto const& obj : args->mapValue()) {
 
  460            const string& obj_name = obj.first;
 
  461            if (obj_name != 
"Dhcp4") {
 
  464                if (message.empty()) {
 
  465                    message = 
"Unsupported '" + obj_name + 
"' parameter";
 
  467                    message += 
" (and '" + obj_name + 
"')";
 
  471        if (!message.empty()) {
 
  476    if (!message.empty()) {
 
  484    MultiThreadingCriticalSection cs;
 
  496ControlledDhcpv4Srv::commandDhcpDisableHandler(
const std::string&,
 
  498    std::ostringstream message;
 
  499    int64_t max_period = 0;
 
  511            message << 
"arguments for the 'dhcp-disable' command must be a map";
 
  516            if (max_period_element) {
 
  519                    message << 
"'max-period' argument must be a number";
 
  523                    max_period = max_period_element->intValue();
 
  524                    if (max_period <= 0) {
 
  525                        message << 
"'max-period' must be positive integer";
 
  538            if (origin_id_element) {
 
  540                    type = origin_id_element->intValue();
 
  542                    message << 
"'origin-id' argument must be a number";
 
  544            } 
else if (origin_element) {
 
  545                switch (origin_element->getType()) {
 
  547                    origin = origin_element->stringValue();
 
  548                    if (origin == 
"ha-partner") {
 
  550                    } 
else if (origin != 
"user") {
 
  551                        if (origin.empty()) {
 
  552                            origin = 
"(empty string)";
 
  554                        message << 
"invalid value used for 'origin' parameter: " 
  559                    type = origin_element->intValue();
 
  563                    message << 
"'origin' argument must be a string or a number";
 
  570    if (message.tellp() == 0) {
 
  571        message << 
"DHCPv4 service disabled";
 
  572        if (max_period > 0) {
 
  573            message << 
" for " << max_period << 
" seconds";
 
  578            network_state_->delayedEnableService(
static_cast<unsigned>(max_period),
 
  592ControlledDhcpv4Srv::commandDhcpEnableHandler(
const std::string&,
 
  594    std::ostringstream message;
 
  605            message << 
"arguments for the 'dhcp-enable' command must be a map";
 
  617            if (origin_id_element) {
 
  619                    type = origin_id_element->intValue();
 
  621                    message << 
"'origin-id' argument must be a number";
 
  623            } 
else if (origin_element) {
 
  624                switch (origin_element->getType()) {
 
  626                    origin = origin_element->stringValue();
 
  627                    if (origin == 
"ha-partner") {
 
  629                    } 
else if (origin != 
"user") {
 
  630                        if (origin.empty()) {
 
  631                            origin = 
"(empty string)";
 
  633                        message << 
"invalid value used for 'origin' parameter: " 
  638                    type = origin_element->intValue();
 
  642                    message << 
"'origin' argument must be a string or a number";
 
  649    if (message.tellp() == 0) {
 
  654                                     "DHCP service successfully enabled"));
 
  662ControlledDhcpv4Srv::commandVersionGetHandler(
const string&, 
ConstElementPtr) {
 
  665    arguments->set(
"extended", extended);
 
  673ControlledDhcpv4Srv::commandBuildReportHandler(
const string&,
 
  681ControlledDhcpv4Srv::commandLeasesReclaimHandler(
const string&,
 
  688        message = 
"Missing mandatory 'remove' parameter.";
 
  692            message = 
"Missing mandatory 'remove' parameter.";
 
  694            message = 
"'remove' parameter expected to be a boolean.";
 
  696            bool remove_lease = remove_name->boolValue();
 
  697            server_->alloc_engine_->reclaimExpiredLeases4(0, 0, remove_lease);
 
  699            message = 
"Reclamation of expired leases is complete.";
 
  707ControlledDhcpv4Srv::commandSubnet4SelectTestHandler(
const string&,
 
  715    bool ignore_link_sel =
 
  717    SubnetSelector selector;
 
  718    for (
auto const& entry : args->mapValue()) {
 
  719        ostringstream errmsg;
 
  720        if (entry.first == 
"interface") {
 
  722                errmsg << 
"'interface' entry must be a string";
 
  725            selector.
iface_name_ = entry.second->stringValue();
 
  727        } 
else if (entry.first == 
"address") {
 
  729                errmsg << 
"'address' entry must be a string";
 
  733                IOAddress addr(entry.second->stringValue());
 
  735                    errmsg << 
"bad 'address' entry: not IPv4";
 
  740            } 
catch (
const exception& ex) {
 
  741                errmsg << 
"bad 'address' entry: " << ex.what();
 
  744        } 
else if (entry.first == 
"relay") {
 
  746                errmsg << 
"'relay' entry must be a string";
 
  750                IOAddress addr(entry.second->stringValue());
 
  752                    errmsg << 
"bad 'relay' entry: not IPv4";
 
  757            } 
catch (
const exception& ex) {
 
  758                errmsg << 
"bad 'relay' entry: " << ex.what();
 
  761        } 
else if (entry.first == 
"local") {
 
  763                errmsg << 
"'local' entry must be a string";
 
  767                IOAddress addr(entry.second->stringValue());
 
  769                    errmsg << 
"bad 'local' entry: not IPv4";
 
  774            } 
catch (
const exception& ex) {
 
  775                errmsg << 
"bad 'local' entry: " << ex.what();
 
  778        } 
else if (entry.first == 
"remote") {
 
  780                errmsg << 
"'remote' entry must be a string";
 
  784                IOAddress addr(entry.second->stringValue());
 
  786                    errmsg << 
"bad 'remote' entry: not IPv4";
 
  791            } 
catch (
const exception& ex) {
 
  792                errmsg << 
"bad 'remote' entry: " << ex.what();
 
  795        } 
else if (entry.first == 
"link") {
 
  797                errmsg << 
"'link' entry must be a string";
 
  801                IOAddress addr(entry.second->stringValue());
 
  803                    errmsg << 
"bad 'link' entry: not IPv4";
 
  806                if (!ignore_link_sel) {
 
  810            } 
catch (
const exception& ex) {
 
  811                errmsg << 
"bad 'link' entry: " << ex.what();
 
  814        } 
else if (entry.first == 
"subnet") {
 
  816            if (args->contains(
"link") && !ignore_link_sel) {
 
  820                errmsg << 
"'subnet' entry must be a string";
 
  824                IOAddress addr(entry.second->stringValue());
 
  826                    errmsg << 
"bad 'subnet' entry: not IPv4";
 
  831            } 
catch (
const exception& ex) {
 
  832                errmsg << 
"bad 'subnet' entry: " << ex.what();
 
  835        } 
else if (entry.first == 
"classes") {
 
  838                                     "'classes' entry must be a list"));
 
  840            for (
auto const& item : entry.second->listValue()) {
 
  842                    errmsg << 
"'classes' entry must be a list of strings";
 
  846                if (!item->stringValue().empty()) {
 
  852            errmsg << 
"unknown entry '" << entry.first << 
"'";
 
  857        getCfgSubnets4()->selectSubnet(selector);
 
  862    subnet->getSharedNetwork(network);
 
  865        msg << 
"selected shared network '" << network->getName()
 
  866            << 
"' starting with subnet '" << subnet->toText()
 
  867            << 
"' id " << subnet->getID();
 
  869        msg << 
"selected subnet '" << subnet->toText()
 
  870            << 
"' id " << subnet->getID();
 
  876ControlledDhcpv4Srv::commandSubnet4o6SelectTestHandler(
const string&,
 
  884    SubnetSelector selector;
 
  888    for (
auto const& entry : args->mapValue()) {
 
  889        ostringstream errmsg;
 
  890        if (entry.first == 
"interface") {
 
  892                errmsg << 
"'interface' entry must be a string";
 
  895            selector.
iface_name_ = entry.second->stringValue();
 
  897        } 
if (entry.first == 
"interface-id") {
 
  899                errmsg << 
"'interface-id' entry must be a string";
 
  903                string str = entry.second->stringValue();
 
  909                    errmsg << 
"'interface-id' must be not empty";
 
  917                errmsg << 
"value of 'interface-id' was not recognized";
 
  920        } 
else if (entry.first == 
"address") {
 
  922                errmsg << 
"'address' entry must be a string";
 
  926                IOAddress addr(entry.second->stringValue());
 
  928                    errmsg << 
"bad 'address' entry: not IPv4";
 
  933            } 
catch (
const exception& ex) {
 
  934                errmsg << 
"bad 'address' entry: " << ex.what();
 
  937        } 
else if (entry.first == 
"relay") {
 
  939                errmsg << 
"'relay' entry must be a string";
 
  943                IOAddress addr(entry.second->stringValue());
 
  945                    errmsg << 
"bad 'relay' entry: not IPv4";
 
  950            } 
catch (
const exception& ex) {
 
  951                errmsg << 
"bad 'relay' entry: " << ex.what();
 
  954        } 
else if (entry.first == 
"local") {
 
  956                errmsg << 
"'local' entry must be a string";
 
  960                IOAddress addr(entry.second->stringValue());
 
  962                    errmsg << 
"bad 'local' entry: not IPv6";
 
  967            } 
catch (
const exception& ex) {
 
  968                errmsg << 
"bad 'local' entry: " << ex.what();
 
  971        } 
else if (entry.first == 
"remote") {
 
  973                errmsg << 
"'remote' entry must be a string";
 
  977                IOAddress addr(entry.second->stringValue());
 
  979                    errmsg << 
"bad 'remote' entry: not IPv6";
 
  984            } 
catch (
const exception& ex) {
 
  985                errmsg << 
"bad 'remote' entry: " << ex.what();
 
  988        } 
else if (entry.first == 
"link") {
 
  990                errmsg << 
"'link' entry must be a string";
 
  994                IOAddress addr(entry.second->stringValue());
 
  996                    errmsg << 
"bad 'link' entry: not IPv6";
 
 1001            } 
catch (
const exception& ex) {
 
 1002                errmsg << 
"bad 'link' entry: " << ex.what();
 
 1005        } 
else if (entry.first == 
"subnet") {
 
 1007                errmsg << 
"'subnet' entry must be a string";
 
 1011                IOAddress addr(entry.second->stringValue());
 
 1013                    errmsg << 
"bad 'subnet' entry: not IPv4";
 
 1018            } 
catch (
const exception& ex) {
 
 1019                errmsg << 
"bad 'subnet' entry: " << ex.what();
 
 1022        } 
else if (entry.first == 
"classes") {
 
 1025                                     "'classes' entry must be a list"));
 
 1027            for (
auto const& item : entry.second->listValue()) {
 
 1029                    errmsg << 
"'classes' entry must be a list of strings";
 
 1033                if (!item->stringValue().empty()) {
 
 1039            errmsg << 
"unknown entry '" << entry.first << 
"'";
 
 1044        getCfgSubnets4()->selectSubnet4o6(selector);
 
 1049    subnet->getSharedNetwork(network);
 
 1052        msg << 
"selected shared network '" << network->getName()
 
 1053            << 
"' starting with subnet '" << subnet->toText()
 
 1054            << 
"' id " << subnet->getID();
 
 1056        msg << 
"selected subnet '" << subnet->toText()
 
 1057            << 
"' id " << subnet->getID();
 
 1063ControlledDhcpv4Srv::commandServerTagGetHandler(
const std::string&,
 
 1065    const std::string& tag =
 
 1074ControlledDhcpv4Srv::commandConfigBackendPullHandler(
const std::string&,
 
 1082    MultiThreadingCriticalSection cs;
 
 1095        auto mode = CBControlDHCPv4::FetchMode::FETCH_UPDATE;
 
 1096        server_->getCBControl()->databaseConfigFetch(srv_cfg, mode);
 
 1097    } 
catch (
const std::exception& ex) {
 
 1101                             "On demand configuration update failed: " +
 
 1102                             string(ex.what())));
 
 1105                         "On demand configuration update successful."));
 
 1109ControlledDhcpv4Srv::commandStatusGetHandler(
const string&,
 
 1114    auto now = boost::posix_time::second_clock::universal_time();
 
 1116    if (!
start_.is_not_a_date_time()) {
 
 1117        auto uptime = now - 
start_;
 
 1122    if (!last_commit.is_not_a_date_time()) {
 
 1123        auto reload = now - last_commit;
 
 1128    if (mt_mgr.getMode()) {
 
 1132        status->set(
"packet-queue-size", 
Element::create(
static_cast<int32_t
>(
 
 1135        queue_stats->add(
Element::create(mt_mgr.getThreadPool().getQueueStat(10)));
 
 1136        queue_stats->add(
Element::create(mt_mgr.getThreadPool().getQueueStat(100)));
 
 1137        queue_stats->add(
Element::create(mt_mgr.getThreadPool().getQueueStat(1000)));
 
 1138        status->set(
"packet-queue-statistics", queue_stats);
 
 1147        for (std::string 
const& 
error : interface->getErrors()) {
 
 1154    if (socket_errors->empty()) {
 
 1159        if (reconnect_ctl && reconnect_ctl->retriesLeft()) {
 
 1164        sockets->set(
"errors", socket_errors);
 
 1166    status->set(
"sockets", sockets);
 
 1174ControlledDhcpv4Srv::commandStatisticSetMaxSampleCountAllHandler(
const string&,
 
 1186ControlledDhcpv4Srv::commandStatisticSetMaxSampleAgeAllHandler(
const string&,
 
 1207    std::ostringstream err;
 
 1210        err << 
"Server object not initialized, can't process config.";
 
 1233    } 
catch (
const std::exception& ex) {
 
 1234        err << 
"Failed to process configuration:" << ex.what();
 
 1241            std::bind(&ControlledDhcpv4Srv::dbLostCallback, srv, ph::_1);
 
 1244            std::bind(&ControlledDhcpv4Srv::dbRecoveredCallback, srv, ph::_1);
 
 1247            std::bind(&ControlledDhcpv4Srv::dbFailedCallback, srv, ph::_1);
 
 1250        string params = 
"universe=4";
 
 1251        cfg_db->setAppendedParameters(params);
 
 1252        cfg_db->createManagers();
 
 1257    } 
catch (
const std::exception& ex) {
 
 1258        err << 
"Unable to open database: " << ex.what();
 
 1265    } 
catch (
const std::exception& ex) {
 
 1266        err << 
"Error starting DHCP_DDNS client after server reconfiguration: " 
 1274    } 
catch (
const std::exception& ex) {
 
 1275        err << 
"error starting DHCPv4-over-DHCPv6 IPC " 
 1276               " after server reconfiguration: " << ex.what();
 
 1289    } 
catch (
const std::exception& ex) {
 
 1290        err << 
"Error setting packet queue controls after server reconfiguration: " 
 1298        std::bind(&ControlledDhcpv4Srv::openSocketsFailedCallback, srv, ph::_1);
 
 1314            setupTimers(&ControlledDhcpv4Srv::reclaimExpiredLeases,
 
 1315                        &ControlledDhcpv4Srv::deleteExpiredReclaimedLeases,
 
 1318    } 
catch (
const std::exception& ex) {
 
 1319        err << 
"unable to setup timers for periodically running the" 
 1320            " reclamation of the expired leases: " 
 1321            << ex.what() << 
".";
 
 1328        long fetch_time = 
static_cast<long>(ctl_info->getConfigFetchWaitTime());
 
 1331        if (fetch_time > 0) {
 
 1337            if (!server_->inTestMode()) {
 
 1338                fetch_time = 1000 * fetch_time;
 
 1341            boost::shared_ptr<unsigned> failure_count(
new unsigned(0));
 
 1343                registerTimer(
"Dhcp4CBFetchTimer",
 
 1344                              std::bind(&ControlledDhcpv4Srv::cbFetchUpdates,
 
 1358    if (notify_libraries) {
 
 1359        return (notify_libraries);
 
 1368    } 
catch (
const std::exception& ex) {
 
 1369        err << 
"Error initializing the lease allocators: " 
 1380    } 
catch (
const std::exception& ex) {
 
 1381        err << 
"Error applying multi threading settings: " 
 
 1400        callout_handle->setArgument(
"io_context", srv->
getIOService());
 
 1402        callout_handle->setArgument(
"json_config", 
config);
 
 1403        callout_handle->setArgument(
"server_config", 
CfgMgr::instance().getStagingCfg());
 
 1412                callout_handle->getArgument(
"error", 
error);
 
 1414                error = 
"unknown error";
 
 
 1429            "Server object not initialized, can't process config.");
 
 
 1440                                         uint16_t client_port )
 
 1444                  "There is another Dhcpv4Srv instance already.");
 
 1467        std::bind(&ControlledDhcpv4Srv::commandBuildReportHandler, 
this, ph::_1, ph::_2));
 
 1470        std::bind(&ControlledDhcpv4Srv::commandConfigBackendPullHandler, 
this, ph::_1, ph::_2));
 
 1473        std::bind(&ControlledDhcpv4Srv::commandConfigGetHandler, 
this, ph::_1, ph::_2));
 
 1476        std::bind(&ControlledDhcpv4Srv::commandConfigHashGetHandler, 
this, ph::_1, ph::_2));
 
 1479        std::bind(&ControlledDhcpv4Srv::commandConfigReloadHandler, 
this, ph::_1, ph::_2));
 
 1482        std::bind(&ControlledDhcpv4Srv::commandConfigSetHandler, 
this, ph::_1, ph::_2));
 
 1485        std::bind(&ControlledDhcpv4Srv::commandConfigTestHandler, 
this, ph::_1, ph::_2));
 
 1488        std::bind(&ControlledDhcpv4Srv::commandConfigWriteHandler, 
this, ph::_1, ph::_2));
 
 1491        std::bind(&ControlledDhcpv4Srv::commandDhcpEnableHandler, 
this, ph::_1, ph::_2));
 
 1494        std::bind(&ControlledDhcpv4Srv::commandDhcpDisableHandler, 
this, ph::_1, ph::_2));
 
 1497        std::bind(&ControlledDhcpv4Srv::commandLeasesReclaimHandler, 
this, ph::_1, ph::_2));
 
 1500        std::bind(&ControlledDhcpv4Srv::commandSubnet4SelectTestHandler, 
this, ph::_1, ph::_2));
 
 1503        std::bind(&ControlledDhcpv4Srv::commandSubnet4o6SelectTestHandler, 
this, ph::_1, ph::_2));
 
 1506        std::bind(&ControlledDhcpv4Srv::commandServerTagGetHandler, 
this, ph::_1, ph::_2));
 
 1509        std::bind(&ControlledDhcpv4Srv::commandShutdownHandler, 
this, ph::_1, ph::_2));
 
 1512        std::bind(&ControlledDhcpv4Srv::commandStatusGetHandler, 
this, ph::_1, ph::_2));
 
 1515        std::bind(&ControlledDhcpv4Srv::commandVersionGetHandler, 
this, ph::_1, ph::_2));
 
 1540        std::bind(&ControlledDhcpv4Srv::commandStatisticSetMaxSampleAgeAllHandler, 
this, ph::_1, ph::_2));
 
 1546        std::bind(&ControlledDhcpv4Srv::commandStatisticSetMaxSampleCountAllHandler, 
this, ph::_1, ph::_2));
 
 
 1567        timer_mgr_->unregisterTimers();
 
 
 1616ControlledDhcpv4Srv::reclaimExpiredLeases(
const size_t max_leases,
 
 1617                                          const uint16_t timeout,
 
 1618                                          const bool remove_lease,
 
 1619                                          const uint16_t max_unwarned_cycles) {
 
 1622            server_->
alloc_engine_->reclaimExpiredLeases4(max_leases, timeout,
 
 1624                                                          max_unwarned_cycles);
 
 1628                 getCfgExpiration()->getReclaimTimerWaitTime());
 
 1630    } 
catch (
const std::exception& ex) {
 
 1639ControlledDhcpv4Srv::deleteExpiredReclaimedLeases(
const uint32_t secs) {
 
 1641        server_->alloc_engine_->deleteExpiredReclaimedLeases4(secs);
 
 1649ControlledDhcpv4Srv::dbLostCallback(
ReconnectCtlPtr db_reconnect_ctl) {
 
 1650    if (!db_reconnect_ctl) {
 
 1657    if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries() &&
 
 1658        db_reconnect_ctl->alterServiceState()) {
 
 1663        .arg(db_reconnect_ctl->id())
 
 1664        .arg(db_reconnect_ctl->timerName());;
 
 1668    if (!db_reconnect_ctl->retriesLeft() ||
 
 1669        !db_reconnect_ctl->retryInterval()) {
 
 1671            .arg(db_reconnect_ctl->retriesLeft())
 
 1672            .arg(db_reconnect_ctl->retryInterval())
 
 1673            .arg(db_reconnect_ctl->id())
 
 1674            .arg(db_reconnect_ctl->timerName());
 
 1675        if (db_reconnect_ctl->exitOnFailure()) {
 
 1685ControlledDhcpv4Srv::dbRecoveredCallback(
ReconnectCtlPtr db_reconnect_ctl) {
 
 1686    if (!db_reconnect_ctl) {
 
 1693    if (db_reconnect_ctl->retriesLeft() != db_reconnect_ctl->maxRetries() &&
 
 1694        db_reconnect_ctl->alterServiceState()) {
 
 1699        .arg(db_reconnect_ctl->id())
 
 1700        .arg(db_reconnect_ctl->timerName());
 
 1702    db_reconnect_ctl->resetRetries();
 
 1708ControlledDhcpv4Srv::dbFailedCallback(
ReconnectCtlPtr db_reconnect_ctl) {
 
 1709    if (!db_reconnect_ctl) {
 
 1716        .arg(db_reconnect_ctl->maxRetries())
 
 1717        .arg(db_reconnect_ctl->id())
 
 1718        .arg(db_reconnect_ctl->timerName());
 
 1720    if (db_reconnect_ctl->exitOnFailure()) {
 
 1728ControlledDhcpv4Srv::openSocketsFailedCallback(
ReconnectCtlPtr reconnect_ctl) {
 
 1729    if (!reconnect_ctl) {
 
 1736            .arg(reconnect_ctl->maxRetries());
 
 1738    if (reconnect_ctl->exitOnFailure()) {
 
 1744ControlledDhcpv4Srv::cbFetchUpdates(
const SrvConfigPtr& srv_cfg,
 
 1745                                    boost::shared_ptr<unsigned> failure_count) {
 
 1747    MultiThreadingCriticalSection cs;
 
 1751        server_->getCBControl()->databaseConfigFetch(srv_cfg,
 
 1752                                                     CBControlDHCPv4::FetchMode::FETCH_UPDATE);
 
 1753        (*failure_count) = 0;
 
 1755    } 
catch (
const std::exception& ex) {
 
 1762        if (++(*failure_count) > 10) {
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
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.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
static IOServiceMgr & instance()
Access the IOServiceMgr singleton instance.
void pollIOServices()
Poll IOService objects.
Implements an asynchronous "signal" for IOService driven processing.
static void setIOService(isc::asiolink::IOServicePtr io_service)
Set the I/O service.
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
void registerCommand(const std::string &cmd, CommandHandler handler)
Registers specified command handler for a given command.
static std::string getHash(const isc::data::ConstElementPtr &config)
returns a hash of a given Element structure
void deregisterCommand(const std::string &cmd)
Deregisters specified command handler.
static CommandMgr & instance()
CommandMgr is a singleton class.
static std::string DEFAULT_AUTHENTICATION_REALM
Default HTTP authentication realm.
void closeCommandSockets()
Close http control sockets.
static HttpCommandMgr & instance()
HttpCommandMgr is a singleton class.
void setIOService(const asiolink::IOServicePtr &io_service)
Sets IO service to be used by the http command manager.
static UnixCommandMgr & instance()
UnixCommandMgr is a singleton class.
void setIOService(const asiolink::IOServicePtr &io_service)
Sets IO service to be used by the unix command manager.
void closeCommandSockets()
Shuts down any open unix control sockets.
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
static void setIOService(const isc::asiolink::IOServicePtr &io_service)
Sets IO service to be used by the database backends.
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.
RAII class to enable DB reconnect retries on server startup.
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.
static OpenSocketsFailedCallback open_sockets_failed_callback_
Optional callback function to invoke if all retries of the opening sockets fail.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
void commit()
Commits the staging configuration.
void clearStagingConfiguration()
Remove staging configuration.
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
static void apply(data::ConstElementPtr value)
apply multi threading configuration
void insert(const ClientClass &class_name)
Insert an element.
Controlled version of the DHCPv4 server.
virtual ~ControlledDhcpv4Srv()
Destructor.
static isc::data::ConstElementPtr finishConfigHookLibraries(isc::data::ConstElementPtr config)
Configuration checker for hook libraries.
isc::data::ConstElementPtr loadConfigFile(const std::string &file_name)
Configure DHCPv4 server using the configuration file specified.
void cleanup()
Performs cleanup, immediately before termination.
ControlledDhcpv4Srv(uint16_t server_port=DHCP4_SERVER_PORT, uint16_t client_port=0)
Constructor.
static isc::data::ConstElementPtr checkConfig(isc::data::ConstElementPtr config)
Configuration checker.
void init(const std::string &config_file)
Initializes the server.
static isc::data::ConstElementPtr processConfig(isc::data::ConstElementPtr config)
Configuration processor.
static ControlledDhcpv4Srv * getInstance()
Returns pointer to the sole instance of Dhcpv4Srv.
virtual void shutdownServer(int exit_value)
Initiates shutdown procedure for the whole DHCPv4 server.
static Dhcp4to6Ipc & instance()
Returns pointer to the sole instance of Dhcp4to6Ipc.
virtual void open()
Open communication socket.
void startD2()
Starts DHCP_DDNS client IO if DDNS updates are enabled.
Dhcpv4Srv(uint16_t server_port=DHCP4_SERVER_PORT, uint16_t client_port=0, const bool use_bcast=true, const bool direct_response_desired=true)
Default constructor.
void shutdown() override
Instructs the server to shut down.
asiolink::IOServicePtr & getIOService()
Returns pointer to the IO service used by the server.
boost::shared_ptr< AllocEngine > alloc_engine_
Allocation Engine.
NetworkStatePtr & getNetworkState()
Returns pointer to the network state used by the server.
static std::string getVersion(bool extended)
returns Kea version on stdout and exit.
bool useBroadcast() const
Return bool value indicating that broadcast flags should be set on sockets.
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.
static void create()
Creates new instance of the HostMgr.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
static void destroy()
Destroy lease manager.
static void commitRuntimeOptionDefs()
Commits runtime option definitions.
static const unsigned int DB_CONNECTION
The network state is being altered by the DB connection recovery mechanics.
static const unsigned int USER_COMMAND
Origin of the network state transition.
static const unsigned int HA_REMOTE_COMMAND
The network state is being altered by a "dhcp-disable" or "dhcp-enable" command sent by a HA partner.
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.
@ PARSER_DHCP4
This parser will parse the content as Dhcp4 config wrapped in a map (that's the regular config file)
Manages a pool of asynchronous interval timers.
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
@ NEXT_STEP_DROP
drop the packet
static int registerHook(const std::string &name)
Register Hook.
static bool calloutsPresent(int index)
Are callouts present?
static boost::shared_ptr< CalloutHandle > createCalloutHandle()
Return callout handle.
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
std::string getConfigFile() const
Returns config file name.
virtual size_t writeConfigFile(const std::string &config_file, isc::data::ConstElementPtr cfg=isc::data::ConstElementPtr()) const
Writes current configuration to specified file.
isc::asiolink::IOSignalSetPtr signal_set_
A pointer to the object installing custom signal handlers.
boost::posix_time::ptime start_
Timestamp of the start of the daemon.
void checkWriteConfigFile(std::string &file)
Checks the to-be-written configuration file name.
void setExitValue(int value)
Sets the exit value.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
static StatsMgr & instance()
Statistics Manager accessor method.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
void apply(bool enabled, uint32_t thread_count, uint32_t queue_size)
Apply the multi-threading related settings.
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.
static isc::data::ConstElementPtr statisticResetHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-reset command.
static isc::data::ConstElementPtr statisticGetAllHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-get-all command.
static isc::data::ConstElementPtr statisticRemoveHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-remove command.
static isc::data::ConstElementPtr statisticGetHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-get command.
isc::data::ConstElementPtr statisticSetMaxSampleAgeAllHandler(const isc::data::ConstElementPtr ¶ms)
Handles statistic-sample-age-set-all command.
static isc::data::ConstElementPtr statisticResetAllHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-reset-all command.
static isc::data::ConstElementPtr statisticSetMaxSampleAgeHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-sample-age-set command.
static isc::data::ConstElementPtr statisticRemoveAllHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-remove-all command.
static isc::data::ConstElementPtr statisticSetMaxSampleCountHandler(const std::string &name, const isc::data::ConstElementPtr ¶ms)
Handles statistic-sample-count-set 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 ...
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
Parses a standard config/command level answer and returns arguments or text status code.
ConstElementPtr createCommand(const std::string &command)
Creates a standard command message with no argument (of the form { "command": "my_command" }...
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
Creates a standard config/command level answer message.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
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< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
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_DB_RECONNECT_DISABLED
const isc::log::MessageID DHCP4_CONFIG_UNRECOVERABLE_ERROR
const int DBG_DHCP4_BASIC
Debug level used to trace basic operations within the code.
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_MULTI_THREADING_INFO
const isc::log::MessageID DHCP4_OPEN_SOCKETS_NO_RECONNECT_CTL
const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_SKIPPED
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
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
boost::shared_ptr< Option > OptionPtr
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
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.
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
vector< uint8_t > quotedStringToBinary(const string "ed_string)
Converts a string in quotes into vector.
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Defines the logger used by the top-level component of kea-lfc.
asiolink::IOAddress local_address_
Address on which the message was received.
bool dhcp4o6_
Specifies if the packet is DHCP4o6.
asiolink::IOAddress option_select_
RAI link select or subnet select option.
std::string iface_name_
Name of the interface on which the message was received.
asiolink::IOAddress ciaddr_
ciaddr from the client's message.
ClientClasses client_classes_
Classes that the client belongs to.
asiolink::IOAddress remote_address_
Source address of the message.
OptionPtr interface_id_
Interface id option.
asiolink::IOAddress first_relay_linkaddr_
First relay link address.
asiolink::IOAddress giaddr_
giaddr from the client's message.