49 #include <boost/algorithm/string.hpp>
50 #include <boost/foreach.hpp>
51 #include <boost/lexical_cast.hpp>
52 #include <boost/scoped_ptr.hpp>
53 #include <boost/shared_ptr.hpp>
58 #include <netinet/in.h>
77 void dirExists(
const string& dir_path) {
79 if (stat(dir_path.c_str(), &statbuf) < 0) {
81 <<
"': " << strerror(errno));
83 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
109 std::string option_str = source_elem->stringValue();
113 code = boost::lexical_cast<int64_t>(option_str);
117 << option_str <<
"', the option code must be a"
118 " non-negative value");
120 }
else if (code > std::numeric_limits<uint16_t>::max()) {
122 << option_str <<
"', the option code must not be"
123 " greater than '" << std::numeric_limits<uint16_t>::max()
127 }
catch (
const boost::bad_lexical_cast &) {
135 code = def->getCode();
138 " specified option name '" << option_str <<
"'"
139 " while parsing the list of enabled"
140 " relay-supplied-options");
143 cfg->getCfgRSOO()->enable(code);
145 }
catch (
const std::exception& ex) {
181 if (global->contains(
"data-directory")) {
182 CfgMgr::instance().setDataDir(getString(global,
"data-directory"),
187 uint32_t probation_period =
188 getUint32(global,
"decline-probation-period");
189 srv_config->setDeclinePeriod(probation_period);
192 uint16_t dhcp4o6_port = getUint16(global,
"dhcp4o6-port");
193 srv_config->setDhcp4o6Port(dhcp4o6_port);
198 srv_config->setContext(user_context);
202 std::string server_tag = getString(global,
"server-tag");
203 srv_config->setServerTag(server_tag);
219 bool ip_reservations_unique = getBoolean(global,
"ip-reservations-unique");
220 cfg->setIPReservationsUnique(ip_reservations_unique);
232 if (!dest || !from) {
244 for (
auto net = networks->begin(); net != networks->end(); ++net) {
255 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
273 cfg->sanityChecksLifetime(
"preferred-lifetime");
274 cfg->sanityChecksLifetime(
"valid-lifetime");
279 sharedNetworksSanityChecks(*networks, global->get(
"shared-networks"));
301 std::set<string> names;
304 for (
auto net = networks.begin(); net != networks.end(); ++net) {
309 string iface = (*net)->getIface();
314 bool rapid_commit =
false;
317 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
321 if (subnet == subnets->begin()) {
323 rapid_commit = (*subnet)->getRapidCommit();
327 if (rapid_commit != (*subnet)->getRapidCommit()) {
329 "must have the same rapid-commit value. Subnet "
330 << (*subnet)->toText()
331 <<
" has specified rapid-commit "
332 << ( (*subnet)->getRapidCommit() ?
"true" :
"false")
333 <<
", but earlier subnet in the same shared-network"
334 <<
" or the shared-network itself used rapid-commit "
335 << (rapid_commit ?
"true" :
"false"));
340 iface = (*subnet)->getIface();
344 if ((*subnet)->getIface().empty()) {
348 if ((*subnet)->getIface() != iface) {
350 <<
" has specified interface " << (*subnet)->getIface()
351 <<
", but earlier subnet in the same shared-network"
352 <<
" or the shared-network itself used " << iface);
357 txt += (*subnet)->toText() +
" ";
362 if ((*net)->getName().empty()) {
364 << txt <<
" is missing mandatory 'name' parameter");
368 if (names.find((*net)->getName()) != names.end()) {
370 "name " << (*net)->getName() <<
" defined twice.");
372 names.insert((*net)->getName());
393 CfgMgr::instance().getStagingCfg()->getControlSocketInfo();
397 CfgMgr::instance().getCurrentCfg()->getControlSocketInfo();
402 bool sock_changed = (sock_cfg && current_sock_cfg &&
403 !sock_cfg->equals(*current_sock_cfg));
410 if (!sock_cfg || !current_sock_cfg || sock_changed) {
429 string(
"Can't parse NULL config"));
438 Subnet::resetSubnetID();
442 IfaceMgr::instance().closeSockets();
443 TimerMgr::instance()->unregisterTimers();
449 LibDHCP::revertRuntimeOptionDefs();
455 HostDataSourceFactory::printRegistered();
461 bool rollback =
false;
463 string parameter_name;
468 srv_config = CfgMgr::instance().getStagingCfg();
473 mutable_cfg = boost::const_pointer_cast<
Element>(config_set);
479 srv_config->moveDdnsParams(mutable_cfg);
483 BaseNetworkParser::moveReservationMode(mutable_cfg);
486 SimpleParser6::setAllDefaults(mutable_cfg);
489 SimpleParser6::deriveParameters(mutable_cfg);
498 Dhcp6ConfigParser global_parser;
501 global_parser.parseEarly(srv_config, mutable_cfg);
505 if (data_directory) {
506 parameter_name =
"data-directory";
507 dirExists(data_directory->stringValue());
513 parameter_name =
"option-def";
516 parser.
parse(cfg_option_def, option_defs);
521 parameter_name =
"option-data";
524 parser.
parse(cfg_option, option_datas);
529 parameter_name =
"mac-sources";
532 parser.
parse(mac_source, mac_sources);
536 if (control_socket) {
537 parameter_name =
"control-socket";
539 parser.
parse(*srv_config, control_socket);
543 if (multi_threading) {
544 parameter_name =
"multi-threading";
546 parser.
parse(*srv_config, multi_threading);
549 ConstElementPtr queue_control = mutable_cfg->get(
"dhcp-queue-control");
551 parameter_name =
"dhcp-queue-control";
553 srv_config->setDHCPQueueControl(parser.
parse(queue_control));
557 mutable_cfg->get(
"host-reservation-identifiers");
558 if (hr_identifiers) {
559 parameter_name =
"host-reservation-identifiers";
561 parser.
parse(hr_identifiers);
566 parameter_name =
"server-id";
568 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
569 parser.
parse(cfg, server_id);
574 parameter_name =
"interfaces-config";
577 parser.
parse(cfg_iface, ifaces_config);
582 parameter_name =
"sanity-checks";
584 parser.
parse(*srv_config, sanity_checks);
588 mutable_cfg->get(
"expired-leases-processing");
589 if (expiration_cfg) {
590 parameter_name =
"expired-leases-processing";
592 parser.
parse(expiration_cfg);
599 if (hooks_libraries) {
600 parameter_name =
"hooks-libraries";
602 HooksConfig& libraries = srv_config->getHooksConfig();
603 hooks_parser.
parse(libraries, hooks_libraries);
613 parameter_name =
"dhcp-ddns";
615 D2ClientConfigParser::setAllDefaults(dhcp_ddns);
617 d2_client_cfg = parser.
parse(dhcp_ddns);
621 if (client_classes) {
622 parameter_name =
"client-classes";
625 parser.
parse(client_classes, AF_INET6);
626 srv_config->setClientClassDictionary(dictionary);
631 if (lease_database) {
632 parameter_name =
"lease-database";
634 std::string access_string;
635 parser.
parse(access_string, lease_database);
637 cfg_db_access->setLeaseDbAccessString(access_string);
641 if (hosts_database) {
642 parameter_name =
"hosts-database";
644 std::string access_string;
645 parser.
parse(access_string, hosts_database);
647 cfg_db_access->setHostDbAccessString(access_string);
651 if (hosts_databases) {
652 parameter_name =
"hosts-databases";
655 for (
auto it : hosts_databases->listValue()) {
656 std::string access_string;
657 parser.
parse(access_string, it);
658 cfg_db_access->setHostDbAccessString(access_string);
664 if (shared_networks) {
665 parameter_name =
"shared-networks";
673 parser.
parse(cfg, shared_networks);
677 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
682 parameter_name =
"subnet6";
685 subnets_parser.
parse(srv_config, subnet6);
690 parameter_name =
"reservations";
693 parser.
parse(SUBNET_ID_GLOBAL, reservations, hosts);
694 for (
auto h = hosts.begin(); h != hosts.end(); ++h) {
695 srv_config->getCfgHosts()->add(*h);
700 if (config_control) {
701 parameter_name =
"config-control";
704 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
707 ConstElementPtr rsoo_list = mutable_cfg->get(
"relay-supplied-options");
709 parameter_name =
"relay-supplied-options";
710 RSOOListConfigParser parser;
711 parser.parse(srv_config, rsoo_list);
716 for (
auto kv : compatibility->mapValue()) {
717 if (kv.first ==
"lenient-option-parsing") {
718 CfgMgr::instance().getStagingCfg()->setLenientOptionParsing(
719 kv.second->boolValue());
726 const std::map<std::string, ConstElementPtr>& values_map =
727 mutable_cfg->mapValue();
729 BOOST_FOREACH(config_pair, values_map) {
731 parameter_name = config_pair.first;
734 if ((config_pair.first ==
"data-directory") ||
735 (config_pair.first ==
"option-def") ||
736 (config_pair.first ==
"option-data") ||
737 (config_pair.first ==
"mac-sources") ||
738 (config_pair.first ==
"control-socket") ||
739 (config_pair.first ==
"multi-threading") ||
740 (config_pair.first ==
"dhcp-queue-control") ||
741 (config_pair.first ==
"host-reservation-identifiers") ||
742 (config_pair.first ==
"server-id") ||
743 (config_pair.first ==
"interfaces-config") ||
744 (config_pair.first ==
"sanity-checks") ||
745 (config_pair.first ==
"expired-leases-processing") ||
746 (config_pair.first ==
"hooks-libraries") ||
747 (config_pair.first ==
"dhcp-ddns") ||
748 (config_pair.first ==
"client-classes") ||
749 (config_pair.first ==
"lease-database") ||
750 (config_pair.first ==
"hosts-database") ||
751 (config_pair.first ==
"hosts-databases") ||
752 (config_pair.first ==
"subnet6") ||
753 (config_pair.first ==
"shared-networks") ||
754 (config_pair.first ==
"reservations") ||
755 (config_pair.first ==
"config-control") ||
756 (config_pair.first ==
"relay-supplied-options") ||
757 (config_pair.first ==
"compatibility")) {
771 if ( (config_pair.first ==
"renew-timer") ||
772 (config_pair.first ==
"rebind-timer") ||
773 (config_pair.first ==
"preferred-lifetime") ||
774 (config_pair.first ==
"min-preferred-lifetime") ||
775 (config_pair.first ==
"max-preferred-lifetime") ||
776 (config_pair.first ==
"valid-lifetime") ||
777 (config_pair.first ==
"min-valid-lifetime") ||
778 (config_pair.first ==
"max-valid-lifetime") ||
779 (config_pair.first ==
"decline-probation-period") ||
780 (config_pair.first ==
"dhcp4o6-port") ||
781 (config_pair.first ==
"server-tag") ||
782 (config_pair.first ==
"reservation-mode") ||
783 (config_pair.first ==
"reservations-global") ||
784 (config_pair.first ==
"reservations-in-subnet") ||
785 (config_pair.first ==
"reservations-out-of-pool") ||
786 (config_pair.first ==
"calculate-tee-times") ||
787 (config_pair.first ==
"t1-percent") ||
788 (config_pair.first ==
"t2-percent") ||
789 (config_pair.first ==
"cache-threshold") ||
790 (config_pair.first ==
"cache-max-age") ||
791 (config_pair.first ==
"loggers") ||
792 (config_pair.first ==
"hostname-char-set") ||
793 (config_pair.first ==
"hostname-char-replacement") ||
794 (config_pair.first ==
"ddns-send-updates") ||
795 (config_pair.first ==
"ddns-override-no-update") ||
796 (config_pair.first ==
"ddns-override-client-update") ||
797 (config_pair.first ==
"ddns-replace-client-name") ||
798 (config_pair.first ==
"ddns-generated-prefix") ||
799 (config_pair.first ==
"ddns-qualifying-suffix") ||
800 (config_pair.first ==
"ddns-update-on-renew") ||
801 (config_pair.first ==
"ddns-use-conflict-resolution") ||
802 (config_pair.first ==
"store-extended-info") ||
803 (config_pair.first ==
"statistic-default-sample-count") ||
804 (config_pair.first ==
"statistic-default-sample-age") ||
805 (config_pair.first ==
"ip-reservations-unique")) {
806 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
812 if (config_pair.first ==
"user-context") {
818 "unsupported global configuration parameter: " << config_pair.first
819 <<
" (" << config_pair.second->getPosition() <<
")");
823 parameter_name =
"<post parsing>";
826 global_parser.parse(srv_config, mutable_cfg);
831 global_parser.sanityChecks(srv_config, mutable_cfg);
834 if (!d2_client_cfg) {
837 d2_client_cfg->validateContents();
838 srv_config->setD2ClientConfig(d2_client_cfg);
841 .arg(parameter_name).arg(ex.
what());
850 " processing error");
860 "Configuration seems sane. Control-socket, hook-libraries, and D2 "
861 "configuration were sanity checked, but not applied.");
880 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
881 CfgMgr::instance().setD2ClientConfig(cfg);
886 HooksManager::prepareUnloadLibraries();
887 static_cast<void>(HooksManager::unloadLibraries());
889 CfgMgr::instance().getStagingCfg()->getHooksConfig();
915 CBControlDHCPv6::FetchMode::FETCH_ALL);
918 std::ostringstream err;
919 err <<
"during update from config backend database: " << ex.
what();
927 std::ostringstream err;
928 err <<
"during update from config backend database: "
929 <<
"undefined configuration parsing error";
942 LibDHCP::revertRuntimeOptionDefs();
947 .arg(CfgMgr::instance().getStagingCfg()->
948 getConfigSummary(SrvConfig::CFGSEL_ALL6));
void parse(isc::data::ConstElementPtr expiration_config)
Parses parameters in the JSON map, pertaining to the processing of the expired leases.
Parser for the configuration of DHCP packet queue controls.
std::pair< std::string, isc::data::ConstElementPtr > ConfigPair
Combination of parameter name and configuration contents.
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list)
Parses a list of options, instantiates them and stores in cfg.
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg)
Parses a given dhcp-ddns element into D2ClientConfig.
Parser for hooks library list.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
this class parses a list of DHCP6 subnets
void parse(const CfgDUIDPtr &cfg, isc::data::ConstElementPtr duid_configuration)
Parses DUID configuration.
Parse Database Parameters.
isc::data::ConstElementPtr configureDhcp6Server(Dhcpv6Srv &server, isc::data::ConstElementPtr config_set, bool check_only)
Configures DHCPv6 server.
ClientClassDictionaryPtr parse(isc::data::ConstElementPtr class_def_list, uint16_t family)
Parse configuration entries.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const isc::log::MessageID DHCP6_CONFIG_START
Parser for a list of host identifiers for DHCPv6.
Parser for the configuration parameters pertaining to the processing of expired leases.
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Wrapper class that holds hooks libraries configuration.
data::ElementPtr parse(const isc::data::ConstElementPtr &control_elem)
Parses content of the "dhcp-queue-control".
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
Parser for D2ClientConfig.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure.
Parser for the configuration of interfaces.
Class of option definition space container.
void parse(const SubnetID &subnet_id, isc::data::ConstElementPtr hr_list, HostCollection &hosts_list)
Parses a list of host reservation entries for a subnet.
void parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
parser for MAC/hardware acquisition sources
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Parser for server DUID configuration.
Parsers for client class definitions.
Implements parser for config control information, "config-control".
Wrapper class that holds MAC/hardware address sources.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const int DBG_DHCP6_COMMAND
Debug level used to log receiving commands.
To be removed. Please use ConfigError instead.
Acts as a storage vault for D2 client configuration.
void closeCommandSocket()
Shuts down any open control sockets.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
Parser for a list of shared networks.
const isc::log::MessageID DHCP6_PARSER_COMMIT_FAIL
boost::shared_ptr< const Element > ConstElementPtr
Parser for option data values within a subnet.
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
Parser for a list of option definitions.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
void parse(CfgMACSource &mac_sources, isc::data::ConstElementPtr value)
parses parameters value
void parse(const CfgIfacePtr &config, const isc::data::ConstElementPtr &values)
Parses content of the "interfaces-config".
Simple parser for sanity-checks structure.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
void configureCommandChannel()
Initialize the command channel based on the staging configuration.
boost::multi_index_container< SharedNetwork6Ptr, 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< SharedNetwork6, std::string,&SharedNetwork6::getName > >, 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 > > >> SharedNetwork6Collection
Multi index container holding shared networks.
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
boost::multi_index_container< Subnet6Ptr, 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 > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime,&data::BaseStampedElement::getModificationTime > > >> Subnet6Collection
A collection of Subnet6 objects.
ConfigControlInfoPtr parse(const data::ConstElementPtr &config_control)
Parses a configuration control Element.
void loadLibraries() const
Commits hooks libraries configuration.
const isc::log::MessageID DHCP6_CONFIG_COMPLETE
This is a base class for exceptions thrown from the DNS library module.
void openCommandSocket(const isc::data::ConstElementPtr &socket_info)
Opens control socket with parameters specified in socket_info.
Defines the logger used by the top-level component of kea-dhcp-ddns.
CBControlDHCPv6Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
void parse(SrvConfig &srv_cfg, isc::data::ConstElementPtr value)
"Parses" control-socket structure
Logging initialization functions.
This file contains several functions and constants that are used for handling commands and responses ...
#define DHCP6_OPTION_SPACE
void parse(CfgSharedNetworksTypePtr &cfg, const data::ConstElementPtr &shared_networks_list_data)
Parses a list of shared networks.
The Element class represents a piece of data, used by the command channel and configuration parts...
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
Parser for a list of host reservations for a subnet.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure
void parse(CfgOptionDefPtr cfg, isc::data::ConstElementPtr def_list)
Parses a list of option definitions, create them and store in cfg.
Parser for the control-socket structure.
boost::shared_ptr< CfgDUID > CfgDUIDPtr
Pointer to the Non-const object.
const isc::log::MessageID DHCP6_PARSER_COMMIT_EXCEPTION
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
boost::shared_ptr< ConfigControlInfo > ConfigControlInfoPtr
Defines a pointer to a ConfigControlInfo.
const isc::log::MessageID DHCP6_PARSER_FAIL
Simple parser for multi-threading structure.
void parse(std::string &access_string, isc::data::ConstElementPtr database_config)
Parse configuration value.
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
Parser for a list of client class definitions.
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
void verifyLibraries(const isc::data::Element::Position &position) const
Verifies that libraries stored in libraries_ are valid.
static CommandMgr & instance()
CommandMgr is a singleton class.
const isc::log::MessageID DHCP6_PARSER_EXCEPTION