47 #include <boost/algorithm/string.hpp>
48 #include <boost/foreach.hpp>
49 #include <boost/lexical_cast.hpp>
55 #include <netinet/in.h>
99 bool echo_client_id = getBoolean(global,
"echo-client-id");
100 cfg->setEchoClientId(echo_client_id);
103 uint32_t probation_period =
104 getUint32(global,
"decline-probation-period");
105 cfg->setDeclinePeriod(probation_period);
108 uint16_t dhcp4o6_port = getUint16(global,
"dhcp4o6-port");
109 cfg->setDhcp4o6Port(dhcp4o6_port);
114 cfg->setContext(user_context);
118 std::string server_tag = getString(global,
"server-tag");
119 cfg->setServerTag(server_tag);
135 bool ip_reservations_unique = getBoolean(global,
"ip-reservations-unique");
136 cfg->setIPReservationsUnique(ip_reservations_unique);
148 if (!dest || !from) {
160 for (
auto net = networks->begin(); net != networks->end(); ++net) {
171 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
189 cfg->sanityChecksLifetime(
"valid-lifetime");
194 sharedNetworksSanityChecks(*networks, global->get(
"shared-networks"));
216 std::set<string> names;
219 for (
auto net = networks.begin(); net != networks.end(); ++net) {
224 bool authoritative = (*net)->getAuthoritative();
225 string iface = (*net)->getIface();
230 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
231 if ((*subnet)->getAuthoritative() != authoritative) {
233 << (*subnet)->toText()
234 <<
" has different authoritative setting "
235 << (*subnet)->getAuthoritative()
236 <<
" than the shared-network itself: "
241 iface = (*subnet)->getIface();
245 if ((*subnet)->getIface().empty()) {
249 if ((*subnet)->getIface() != iface) {
251 <<
" has specified interface " << (*subnet)->getIface()
252 <<
", but earlier subnet in the same shared-network"
253 <<
" or the shared-network itself used " << iface);
258 txt += (*subnet)->toText() +
" ";
263 if ((*net)->getName().empty()) {
265 << txt <<
" is missing mandatory 'name' parameter");
269 if (names.find((*net)->getName()) != names.end()) {
271 "name " << (*net)->getName() <<
" defined twice.");
273 names.insert((*net)->getName());
294 CfgMgr::instance().getStagingCfg()->getControlSocketInfo();
298 CfgMgr::instance().getCurrentCfg()->getControlSocketInfo();
303 bool sock_changed = (sock_cfg && current_sock_cfg &&
304 !sock_cfg->equals(*current_sock_cfg));
311 if (!sock_cfg || !current_sock_cfg || sock_changed) {
329 Subnet::resetSubnetID();
332 LibDHCP::revertRuntimeOptionDefs();
338 HostDataSourceFactory::printRegistered();
344 string parameter_name;
349 srv_config = CfgMgr::instance().getStagingCfg();
354 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
360 srv_config->moveDdnsParams(mutable_cfg);
364 BaseNetworkParser::moveReservationMode(mutable_cfg);
367 SimpleParser4::setAllDefaults(mutable_cfg);
370 SimpleParser4::deriveParameters(mutable_cfg);
379 Dhcp4ConfigParser global_parser;
382 global_parser.parseEarly(srv_config, mutable_cfg);
387 parameter_name =
"option-def";
390 parser.
parse(cfg_option_def, option_defs);
395 parameter_name =
"option-data";
398 parser.
parse(cfg_option, option_datas);
402 if (control_socket) {
403 parameter_name =
"control-socket";
405 parser.
parse(*srv_config, control_socket);
409 if (multi_threading) {
410 parameter_name =
"multi-threading";
412 parser.
parse(*srv_config, multi_threading);
415 bool multi_threading_enabled =
true;
416 uint32_t thread_count = 0;
417 uint32_t queue_size = 0;
418 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
419 multi_threading_enabled, thread_count, queue_size);
422 ConstElementPtr queue_control = mutable_cfg->get(
"dhcp-queue-control");
424 parameter_name =
"dhcp-queue-control";
426 srv_config->setDHCPQueueControl(parser.
parse(queue_control, multi_threading_enabled));
430 ConstElementPtr reservations_lookup_first = mutable_cfg->get(
"reservations-lookup-first");
431 if (reservations_lookup_first) {
432 parameter_name =
"reservations-lookup-first";
433 if (multi_threading_enabled) {
436 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
440 mutable_cfg->get(
"host-reservation-identifiers");
441 if (hr_identifiers) {
442 parameter_name =
"host-reservation-identifiers";
444 parser.
parse(hr_identifiers);
449 parameter_name =
"interfaces-config";
452 parser.
parse(cfg_iface, ifaces_config);
457 parameter_name =
"sanity-checks";
459 parser.
parse(*srv_config, sanity_checks);
463 mutable_cfg->get(
"expired-leases-processing");
464 if (expiration_cfg) {
465 parameter_name =
"expired-leases-processing";
467 parser.
parse(expiration_cfg);
474 if (hooks_libraries) {
475 parameter_name =
"hooks-libraries";
477 HooksConfig& libraries = srv_config->getHooksConfig();
478 hooks_parser.
parse(libraries, hooks_libraries);
480 multi_threading_enabled);
489 parameter_name =
"dhcp-ddns";
491 D2ClientConfigParser::setAllDefaults(dhcp_ddns);
493 d2_client_cfg = parser.
parse(dhcp_ddns);
497 if (client_classes) {
498 parameter_name =
"client-classes";
501 parser.
parse(client_classes, AF_INET);
502 srv_config->setClientClassDictionary(dictionary);
507 if (lease_database) {
508 parameter_name =
"lease-database";
510 std::string access_string;
511 parser.
parse(access_string, lease_database);
513 cfg_db_access->setLeaseDbAccessString(access_string);
517 if (hosts_database) {
518 parameter_name =
"hosts-database";
520 std::string access_string;
521 parser.
parse(access_string, hosts_database);
523 cfg_db_access->setHostDbAccessString(access_string);
527 if (hosts_databases) {
528 parameter_name =
"hosts-databases";
530 for (
auto it : hosts_databases->listValue()) {
532 std::string access_string;
533 parser.
parse(access_string, it);
534 cfg_db_access->setHostDbAccessString(access_string);
540 if (shared_networks) {
541 parameter_name =
"shared-networks";
549 parser.
parse(cfg, shared_networks);
553 global_parser.copySubnets4(srv_config->getCfgSubnets4(), cfg);
558 parameter_name =
"subnet4";
561 subnets_parser.
parse(srv_config, subnet4);
566 parameter_name =
"reservations";
569 parser.
parse(SUBNET_ID_GLOBAL, reservations, hosts);
570 for (
auto h = hosts.begin(); h != hosts.end(); ++h) {
571 srv_config->getCfgHosts()->add(*h);
576 if (config_control) {
577 parameter_name =
"config-control";
580 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
585 for (
auto kv : compatibility->mapValue()) {
586 if (!kv.second || (kv.second->getType() != Element::boolean)) {
588 "compatibility parameter values must be "
589 <<
"boolean (" << kv.first <<
" at "
590 << kv.second->getPosition() <<
")");
592 if (kv.first ==
"lenient-option-parsing") {
593 CfgMgr::instance().getStagingCfg()->setLenientOptionParsing(
594 kv.second->boolValue());
595 }
else if (kv.first ==
"ignore-dhcp-server-identifier") {
596 CfgMgr::instance().getStagingCfg()->setIgnoreServerIdentifier(
597 kv.second->boolValue());
598 }
else if (kv.first ==
"ignore-rai-link-selection") {
599 CfgMgr::instance().getStagingCfg()->setIgnoreRAILinkSelection(
600 kv.second->boolValue());
601 }
else if (kv.first ==
"exclude-first-last-24") {
602 CfgMgr::instance().getStagingCfg()->setExcludeFirstLast24(
603 kv.second->boolValue());
606 "unsupported compatibility parameter: "
607 << kv.first <<
" (" << kv.second->getPosition()
615 const std::map<std::string, ConstElementPtr>& values_map =
616 mutable_cfg->mapValue();
618 BOOST_FOREACH(config_pair, values_map) {
620 parameter_name = config_pair.first;
623 if ((config_pair.first ==
"option-def") ||
624 (config_pair.first ==
"option-data") ||
625 (config_pair.first ==
"control-socket") ||
626 (config_pair.first ==
"multi-threading") ||
627 (config_pair.first ==
"dhcp-queue-control") ||
628 (config_pair.first ==
"host-reservation-identifiers") ||
629 (config_pair.first ==
"interfaces-config") ||
630 (config_pair.first ==
"sanity-checks") ||
631 (config_pair.first ==
"expired-leases-processing") ||
632 (config_pair.first ==
"hooks-libraries") ||
633 (config_pair.first ==
"dhcp-ddns") ||
634 (config_pair.first ==
"client-classes") ||
635 (config_pair.first ==
"lease-database") ||
636 (config_pair.first ==
"hosts-database") ||
637 (config_pair.first ==
"hosts-databases") ||
638 (config_pair.first ==
"subnet4") ||
639 (config_pair.first ==
"shared-networks") ||
640 (config_pair.first ==
"reservations") ||
641 (config_pair.first ==
"config-control") ||
642 (config_pair.first ==
"loggers") ||
643 (config_pair.first ==
"compatibility")) {
657 if ( (config_pair.first ==
"renew-timer") ||
658 (config_pair.first ==
"rebind-timer") ||
659 (config_pair.first ==
"valid-lifetime") ||
660 (config_pair.first ==
"min-valid-lifetime") ||
661 (config_pair.first ==
"max-valid-lifetime") ||
662 (config_pair.first ==
"decline-probation-period") ||
663 (config_pair.first ==
"dhcp4o6-port") ||
664 (config_pair.first ==
"echo-client-id") ||
665 (config_pair.first ==
"match-client-id") ||
666 (config_pair.first ==
"authoritative") ||
667 (config_pair.first ==
"next-server") ||
668 (config_pair.first ==
"server-hostname") ||
669 (config_pair.first ==
"boot-file-name") ||
670 (config_pair.first ==
"server-tag") ||
671 (config_pair.first ==
"reservation-mode") ||
672 (config_pair.first ==
"reservations-global") ||
673 (config_pair.first ==
"reservations-in-subnet") ||
674 (config_pair.first ==
"reservations-out-of-pool") ||
675 (config_pair.first ==
"calculate-tee-times") ||
676 (config_pair.first ==
"t1-percent") ||
677 (config_pair.first ==
"t2-percent") ||
678 (config_pair.first ==
"cache-threshold") ||
679 (config_pair.first ==
"cache-max-age") ||
680 (config_pair.first ==
"hostname-char-set") ||
681 (config_pair.first ==
"hostname-char-replacement") ||
682 (config_pair.first ==
"ddns-send-updates") ||
683 (config_pair.first ==
"ddns-override-no-update") ||
684 (config_pair.first ==
"ddns-override-client-update") ||
685 (config_pair.first ==
"ddns-replace-client-name") ||
686 (config_pair.first ==
"ddns-generated-prefix") ||
687 (config_pair.first ==
"ddns-qualifying-suffix") ||
688 (config_pair.first ==
"ddns-update-on-renew") ||
689 (config_pair.first ==
"ddns-use-conflict-resolution") ||
690 (config_pair.first ==
"ddns-ttl-percent") ||
691 (config_pair.first ==
"store-extended-info") ||
692 (config_pair.first ==
"statistic-default-sample-count") ||
693 (config_pair.first ==
"statistic-default-sample-age") ||
694 (config_pair.first ==
"early-global-reservations-lookup") ||
695 (config_pair.first ==
"ip-reservations-unique") ||
696 (config_pair.first ==
"reservations-lookup-first") ||
697 (config_pair.first ==
"parked-packet-limit") ||
698 (config_pair.first ==
"allocator") ||
699 (config_pair.first ==
"offer-lifetime") ) {
700 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
706 if (config_pair.first ==
"user-context") {
712 "unsupported global configuration parameter: " << config_pair.first
713 <<
" (" << config_pair.second->getPosition() <<
")");
717 parameter_name =
"<post parsing>";
720 global_parser.parse(srv_config, mutable_cfg);
725 global_parser.sanityChecks(srv_config, mutable_cfg);
728 if (!d2_client_cfg) {
731 d2_client_cfg->validateContents();
732 srv_config->setD2ClientConfig(d2_client_cfg);
735 .arg(parameter_name).arg(ex.
what());
746 "Control-socket, hook-libraries, and D2 configuration "
747 "were sanity checked, but not applied.");
755 bool check_only,
bool extra_checks) {
758 "Can't parse NULL config");
778 srv_config = CfgMgr::instance().getStagingCfg();
780 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
781 string params =
"universe=4 persist=false";
782 if (cfg_db->getExtendedInfoTablesEnabled()) {
783 params +=
" extended-info-tables=true";
785 cfg_db->setAppendedParameters(params);
786 cfg_db->createManagers();
787 }
catch (
const std::exception& ex) {
793 std::ostringstream err;
797 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
798 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET, qc)) {
800 .arg(IfaceMgr::instance().getPacketQueue4()->getInfoStr());
803 }
catch (
const std::exception& ex) {
804 err <<
"Error setting packet queue controls after server reconfiguration: "
812 string parameter_name;
821 MultiThreadingMgr::instance().apply(
false, 0, 0);
824 IfaceMgr::instance().closeSockets();
825 TimerMgr::instance()->unregisterTimers();
832 srv_config = CfgMgr::instance().getStagingCfg();
837 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
841 parameter_name =
"interfaces-config";
845 parser.
parse(cfg_iface, ifaces_config);
849 .arg(parameter_name).arg(ex.
what());
856 " processing error");
891 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
892 CfgMgr::instance().setD2ClientConfig(cfg);
911 HooksManager::prepareUnloadLibraries();
912 static_cast<void>(HooksManager::unloadLibraries());
914 CfgMgr::instance().getStagingCfg()->getHooksConfig();
915 bool multi_threading_enabled =
true;
916 uint32_t thread_count = 0;
917 uint32_t queue_size = 0;
918 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
919 multi_threading_enabled, thread_count, queue_size);
939 CBControlDHCPv4::FetchMode::FETCH_ALL);
941 std::ostringstream err;
942 err <<
"during update from config backend database: " << ex.
what();
948 std::ostringstream err;
949 err <<
"during update from config backend database: "
950 <<
"undefined configuration parsing error";
961 LibDHCP::revertRuntimeOptionDefs();
964 auto notify_libraries = ControlledDhcpv4Srv::finishConfigHookLibraries(config_set);
965 if (notify_libraries) {
966 return (notify_libraries);
974 .arg(CfgMgr::instance().getStagingCfg()->
975 getConfigSummary(SrvConfig::CFGSEL_ALL4));
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.
void closeCommandSocket()
Shuts down any open control sockets.
static CommandMgr & instance()
CommandMgr is a singleton class.
void openCommandSocket(const isc::data::ConstElementPtr &socket_info)
Opens control socket with parameters specified in socket_info.
Parse Database Parameters.
void parse(std::string &access_string, isc::data::ConstElementPtr database_config)
Parse configuration value.
Parser for a list of client class definitions.
ClientClassDictionaryPtr parse(isc::data::ConstElementPtr class_def_list, uint16_t family, bool check_dependencies=true)
Parse configuration entries.
Parser for the control-socket structure.
void parse(SrvConfig &srv_cfg, isc::data::ConstElementPtr value)
"Parses" control-socket structure
Parser for D2ClientConfig.
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg)
Parses a given dhcp-ddns element into D2ClientConfig.
Acts as a storage vault for D2 client configuration.
Parser for the configuration of DHCP packet queue controls.
data::ElementPtr parse(const isc::data::ConstElementPtr &control_elem, bool multi_threading_enabled)
Parses content of the "dhcp-queue-control".
To be removed. Please use ConfigError instead.
CBControlDHCPv4Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
Parser for the configuration parameters pertaining to the processing of expired leases.
void parse(isc::data::ConstElementPtr expiration_config)
Parses parameters in the JSON map, pertaining to the processing of the expired leases.
Parser for a list of host identifiers for DHCPv4.
void parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
Parser for a list of host reservations for a subnet.
void parse(const SubnetID &subnet_id, isc::data::ConstElementPtr hr_list, HostCollection &hosts_list)
Parses a list of host reservation entries for a subnet.
Parser for the configuration of interfaces.
void parse(const CfgIfacePtr &config, const isc::data::ConstElementPtr &values)
Parses content of the "interfaces-config".
Simple parser for multi-threading structure.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure.
Parser for option data values within a subnet.
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list)
Parses a list of options, instantiates them and stores in cfg.
Parser for a list of option definitions.
void parse(CfgOptionDefPtr cfg, isc::data::ConstElementPtr def_list)
Parses a list of option definitions, create them and store in cfg.
Class of option definition space container.
Simple parser for sanity-checks structure.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure
Parser for a list of shared networks.
void parse(CfgSharedNetworksTypePtr &cfg, const data::ConstElementPtr &shared_networks_list_data)
Parses a list of shared networks.
this class parses list of DHCP4 subnets
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
Wrapper class that holds hooks libraries configuration.
void verifyLibraries(const isc::data::Element::Position &position, bool multi_threading_enabled) const
Verifies that libraries stored in libraries_ are valid.
void loadLibraries(bool multi_threading_enabled) const
Commits hooks libraries configuration.
Parser for hooks library list.
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
Implements parser for config control information, "config-control".
ConfigControlInfoPtr parse(const data::ConstElementPtr &config_control)
Parses a configuration control Element.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
Parsers for client class definitions.
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.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#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_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
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
void configureCommandChannel()
Initialize the command channel based on the staging configuration.
std::pair< std::string, isc::data::ConstElementPtr > ConfigPair
Combination of parameter name and configuration contents.
const isc::log::MessageID DHCP4_CONFIG_START
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
const isc::log::MessageID DHCP4_PARSER_EXCEPTION
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const isc::log::MessageID DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED
isc::data::ConstElementPtr processDhcp4Config(isc::data::ConstElementPtr config_set)
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
const isc::log::MessageID DHCP4_CONFIG_PACKET_QUEUE
const isc::log::MessageID DHCP4_PARSER_COMMIT_EXCEPTION
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
const isc::log::MessageID DHCP4_PARSER_FAIL
std::vector< HostPtr > HostCollection
Collection of the Host objects.
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > > >> Subnet4SimpleCollection
A simple collection of Subnet4 objects.
const int DBG_DHCP4_COMMAND
Debug level used to log receiving commands.
const isc::log::MessageID DHCP4_PARSER_COMMIT_FAIL
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
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.
boost::shared_ptr< CfgSubnets4 > CfgSubnets4Ptr
Non-const pointer.
const isc::log::MessageID DHCP4_CONFIG_COMPLETE
boost::multi_index_container< SharedNetwork4Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SharedNetworkRandomAccessIndexTag > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< SharedNetworkIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t, &data::BaseStampedElement::getId > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SharedNetworkNameIndexTag >, boost::multi_index::const_mem_fun< SharedNetwork4, std::string, &SharedNetwork4::getName > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SharedNetworkServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SharedNetworkModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > >> SharedNetwork4Collection
Multi index container holding shared networks.
boost::shared_ptr< CfgSharedNetworks4 > CfgSharedNetworks4Ptr
Pointer to the configuration of IPv4 shared networks.
isc::log::Logger dhcp4_logger(DHCP4_APP_LOGGER_NAME)
Base logger for DHCPv4 server.
boost::shared_ptr< ConfigControlInfo > ConfigControlInfoPtr
Defines a pointer to a ConfigControlInfo.
Defines the logger used by the top-level component of kea-lfc.