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>
79void dirExists(
const string& dir_path) {
81 if (stat(dir_path.c_str(), &statbuf) < 0) {
83 <<
"': " << strerror(errno));
85 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
111 std::string option_str = source_elem->stringValue();
115 code = boost::lexical_cast<int64_t>(option_str);
119 << option_str <<
"', the option code must be a"
120 " non-negative value");
122 }
else if (code > std::numeric_limits<uint16_t>::max()) {
124 << option_str <<
"', the option code must not be"
125 " greater than '" << std::numeric_limits<uint16_t>::max()
129 }
catch (
const boost::bad_lexical_cast &) {
137 code = def->getCode();
140 " specified option name '" << option_str <<
"'"
141 " while parsing the list of enabled"
142 " relay-supplied-options");
145 cfg->getCfgRSOO()->enable(code);
147 }
catch (
const std::exception& ex) {
183 if (global->contains(
"data-directory")) {
184 CfgMgr::instance().setDataDir(
getString(global,
"data-directory"),
189 uint32_t probation_period =
190 getUint32(global,
"decline-probation-period");
191 cfg->setDeclinePeriod(probation_period);
194 uint16_t dhcp4o6_port =
getUint16(global,
"dhcp4o6-port");
195 cfg->setDhcp4o6Port(dhcp4o6_port);
200 cfg->setContext(user_context);
204 std::string server_tag =
getString(global,
"server-tag");
205 cfg->setServerTag(server_tag);
221 bool ip_reservations_unique =
getBoolean(global,
"ip-reservations-unique");
222 cfg->setIPReservationsUnique(ip_reservations_unique);
234 if (!dest || !from) {
246 for (
auto net = networks->begin(); net != networks->end(); ++net) {
257 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
275 cfg->sanityChecksLifetime(
"preferred-lifetime");
276 cfg->sanityChecksLifetime(
"valid-lifetime");
281 sharedNetworksSanityChecks(*networks, global->get(
"shared-networks"));
303 std::set<string> names;
306 for (
auto net = networks.begin(); net != networks.end(); ++net) {
311 string iface = (*net)->getIface();
316 bool rapid_commit =
false;
319 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
323 if (subnet == subnets->begin()) {
325 rapid_commit = (*subnet)->getRapidCommit();
329 if (rapid_commit != (*subnet)->getRapidCommit()) {
331 "must have the same rapid-commit value. Subnet "
332 << (*subnet)->toText()
333 <<
" has specified rapid-commit "
334 << ( (*subnet)->getRapidCommit() ?
"true" :
"false")
335 <<
", but earlier subnet in the same shared-network"
336 <<
" or the shared-network itself used rapid-commit "
337 << (rapid_commit ?
"true" :
"false"));
342 iface = (*subnet)->getIface();
346 if ((*subnet)->getIface().empty()) {
350 if ((*subnet)->getIface() != iface) {
352 <<
" has specified interface " << (*subnet)->getIface()
353 <<
", but earlier subnet in the same shared-network"
354 <<
" or the shared-network itself used " << iface);
359 txt += (*subnet)->toText() +
" ";
364 if ((*net)->getName().empty()) {
366 << txt <<
" is missing mandatory 'name' parameter");
370 if (names.find((*net)->getName()) != names.end()) {
372 "name " << (*net)->getName() <<
" defined twice.");
374 names.insert((*net)->getName());
404 bool sock_changed = (sock_cfg && current_sock_cfg &&
405 !sock_cfg->equals(*current_sock_cfg));
412 if (!sock_cfg || !current_sock_cfg || sock_changed) {
431 string(
"Can't parse NULL config"));
463 bool rollback =
false;
465 string parameter_name;
475 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
481 srv_config->moveDdnsParams(mutable_cfg);
500 Dhcp6ConfigParser global_parser;
503 global_parser.parseEarly(srv_config, mutable_cfg);
507 if (data_directory) {
508 parameter_name =
"data-directory";
509 dirExists(data_directory->stringValue());
515 parameter_name =
"option-def";
518 parser.
parse(cfg_option_def, option_defs);
523 parameter_name =
"option-data";
526 parser.
parse(cfg_option, option_datas);
531 parameter_name =
"mac-sources";
534 parser.
parse(mac_source, mac_sources);
538 if (control_socket) {
539 parameter_name =
"control-socket";
541 parser.
parse(*srv_config, control_socket);
545 if (multi_threading) {
546 parameter_name =
"multi-threading";
548 parser.
parse(*srv_config, multi_threading);
552 ConstElementPtr queue_control = mutable_cfg->get(
"dhcp-queue-control");
554 parameter_name =
"dhcp-queue-control";
556 srv_config->setDHCPQueueControl(parser.
parse(queue_control));
560 ConstElementPtr reservations_lookup_first = mutable_cfg->get(
"reservations-lookup-first");
561 if (reservations_lookup_first) {
562 parameter_name =
"reservations-lookup-first";
563 if (MultiThreadingMgr::instance().getMode()) {
566 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
570 mutable_cfg->get(
"host-reservation-identifiers");
571 if (hr_identifiers) {
572 parameter_name =
"host-reservation-identifiers";
574 parser.
parse(hr_identifiers);
579 parameter_name =
"server-id";
581 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
582 parser.
parse(cfg, server_id);
587 parameter_name =
"interfaces-config";
590 parser.
parse(cfg_iface, ifaces_config);
595 parameter_name =
"sanity-checks";
597 parser.
parse(*srv_config, sanity_checks);
601 mutable_cfg->get(
"expired-leases-processing");
602 if (expiration_cfg) {
603 parameter_name =
"expired-leases-processing";
605 parser.
parse(expiration_cfg);
612 if (hooks_libraries) {
613 parameter_name =
"hooks-libraries";
615 HooksConfig& libraries = srv_config->getHooksConfig();
616 hooks_parser.
parse(libraries, hooks_libraries);
626 parameter_name =
"dhcp-ddns";
630 d2_client_cfg = parser.
parse(dhcp_ddns);
634 if (client_classes) {
635 parameter_name =
"client-classes";
638 parser.
parse(client_classes, AF_INET6);
639 srv_config->setClientClassDictionary(dictionary);
644 if (lease_database) {
645 parameter_name =
"lease-database";
647 std::string access_string;
648 parser.
parse(access_string, lease_database);
650 cfg_db_access->setLeaseDbAccessString(access_string);
654 if (hosts_database) {
655 parameter_name =
"hosts-database";
657 std::string access_string;
658 parser.
parse(access_string, hosts_database);
660 cfg_db_access->setHostDbAccessString(access_string);
664 if (hosts_databases) {
665 parameter_name =
"hosts-databases";
667 for (
auto it : hosts_databases->listValue()) {
669 std::string access_string;
670 parser.
parse(access_string, it);
671 cfg_db_access->setHostDbAccessString(access_string);
677 if (shared_networks) {
678 parameter_name =
"shared-networks";
686 parser.
parse(cfg, shared_networks);
690 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
695 parameter_name =
"subnet6";
698 subnets_parser.
parse(srv_config, subnet6);
703 parameter_name =
"reservations";
706 parser.
parse(SUBNET_ID_GLOBAL, reservations, hosts);
707 for (
auto h = hosts.begin(); h != hosts.end(); ++h) {
708 srv_config->getCfgHosts()->add(*h);
713 if (config_control) {
714 parameter_name =
"config-control";
720 ConstElementPtr rsoo_list = mutable_cfg->get(
"relay-supplied-options");
722 parameter_name =
"relay-supplied-options";
723 RSOOListConfigParser parser;
724 parser.parse(srv_config, rsoo_list);
729 for (
auto kv : compatibility->mapValue()) {
730 if (kv.first ==
"lenient-option-parsing") {
732 kv.second->boolValue());
739 const std::map<std::string, ConstElementPtr>& values_map =
740 mutable_cfg->mapValue();
742 BOOST_FOREACH(config_pair, values_map) {
744 parameter_name = config_pair.first;
747 if ((config_pair.first ==
"data-directory") ||
748 (config_pair.first ==
"option-def") ||
749 (config_pair.first ==
"option-data") ||
750 (config_pair.first ==
"mac-sources") ||
751 (config_pair.first ==
"control-socket") ||
752 (config_pair.first ==
"multi-threading") ||
753 (config_pair.first ==
"dhcp-queue-control") ||
754 (config_pair.first ==
"host-reservation-identifiers") ||
755 (config_pair.first ==
"server-id") ||
756 (config_pair.first ==
"interfaces-config") ||
757 (config_pair.first ==
"sanity-checks") ||
758 (config_pair.first ==
"expired-leases-processing") ||
759 (config_pair.first ==
"hooks-libraries") ||
760 (config_pair.first ==
"dhcp-ddns") ||
761 (config_pair.first ==
"client-classes") ||
762 (config_pair.first ==
"lease-database") ||
763 (config_pair.first ==
"hosts-database") ||
764 (config_pair.first ==
"hosts-databases") ||
765 (config_pair.first ==
"subnet6") ||
766 (config_pair.first ==
"shared-networks") ||
767 (config_pair.first ==
"reservations") ||
768 (config_pair.first ==
"config-control") ||
769 (config_pair.first ==
"relay-supplied-options") ||
770 (config_pair.first ==
"loggers") ||
771 (config_pair.first ==
"compatibility")) {
785 if ( (config_pair.first ==
"renew-timer") ||
786 (config_pair.first ==
"rebind-timer") ||
787 (config_pair.first ==
"preferred-lifetime") ||
788 (config_pair.first ==
"min-preferred-lifetime") ||
789 (config_pair.first ==
"max-preferred-lifetime") ||
790 (config_pair.first ==
"valid-lifetime") ||
791 (config_pair.first ==
"min-valid-lifetime") ||
792 (config_pair.first ==
"max-valid-lifetime") ||
793 (config_pair.first ==
"decline-probation-period") ||
794 (config_pair.first ==
"dhcp4o6-port") ||
795 (config_pair.first ==
"server-tag") ||
796 (config_pair.first ==
"reservation-mode") ||
797 (config_pair.first ==
"reservations-global") ||
798 (config_pair.first ==
"reservations-in-subnet") ||
799 (config_pair.first ==
"reservations-out-of-pool") ||
800 (config_pair.first ==
"calculate-tee-times") ||
801 (config_pair.first ==
"t1-percent") ||
802 (config_pair.first ==
"t2-percent") ||
803 (config_pair.first ==
"cache-threshold") ||
804 (config_pair.first ==
"cache-max-age") ||
805 (config_pair.first ==
"hostname-char-set") ||
806 (config_pair.first ==
"hostname-char-replacement") ||
807 (config_pair.first ==
"ddns-send-updates") ||
808 (config_pair.first ==
"ddns-override-no-update") ||
809 (config_pair.first ==
"ddns-override-client-update") ||
810 (config_pair.first ==
"ddns-replace-client-name") ||
811 (config_pair.first ==
"ddns-generated-prefix") ||
812 (config_pair.first ==
"ddns-qualifying-suffix") ||
813 (config_pair.first ==
"ddns-update-on-renew") ||
814 (config_pair.first ==
"ddns-use-conflict-resolution") ||
815 (config_pair.first ==
"store-extended-info") ||
816 (config_pair.first ==
"statistic-default-sample-count") ||
817 (config_pair.first ==
"statistic-default-sample-age") ||
818 (config_pair.first ==
"early-global-reservations-lookup") ||
819 (config_pair.first ==
"ip-reservations-unique") ||
820 (config_pair.first ==
"reservations-lookup-first") ||
821 (config_pair.first ==
"parked-packet-limit")) {
828 if (config_pair.first ==
"user-context") {
834 "unsupported global configuration parameter: " << config_pair.first
835 <<
" (" << config_pair.second->getPosition() <<
")");
839 parameter_name =
"<post parsing>";
842 global_parser.parse(srv_config, mutable_cfg);
847 global_parser.sanityChecks(srv_config, mutable_cfg);
850 if (!d2_client_cfg) {
853 d2_client_cfg->validateContents();
854 srv_config->setD2ClientConfig(d2_client_cfg);
857 .arg(parameter_name).arg(ex.
what());
866 " processing error");
876 "Configuration seems sane. Control-socket, hook-libraries, and D2 "
877 "configuration were sanity checked, but not applied.");
902 HooksManager::prepareUnloadLibraries();
903 static_cast<void>(HooksManager::unloadLibraries());
930 CBControlDHCPv6::FetchMode::FETCH_ALL);
932 std::ostringstream err;
933 err <<
"during update from config backend database: " << ex.
what();
941 std::ostringstream err;
942 err <<
"during update from config backend database: "
943 <<
"undefined configuration parsing error";
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.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
uint32_t getUint32(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint32_t.
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
uint16_t getUint16(isc::data::ConstElementPtr scope, const std::string &name)
Returns a value converted to uint16_t.
Parse Database Parameters.
void parse(std::string &access_string, isc::data::ConstElementPtr database_config)
Parse configuration value.
static void moveReservationMode(isc::data::ElementPtr config)
Moves deprecated reservation-mode parameter to new reservations flags.
Wrapper class that holds MAC/hardware address sources.
void setD2ClientConfig(D2ClientConfigPtr &new_config)
Updates the DHCP-DDNS client configuration to the given value.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
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.
static size_t setAllDefaults(isc::data::ConstElementPtr d2_config)
Sets all defaults for D2 client configuration.
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)
Parses content of the "dhcp-queue-control".
Parser for server DUID configuration.
void parse(const CfgDUIDPtr &cfg, isc::data::ConstElementPtr duid_configuration)
Parses DUID configuration.
To be removed. Please use ConfigError instead.
CBControlDHCPv6Ptr 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.
static void printRegistered()
Prints out all registered backends.
Parser for a list of host identifiers for DHCPv6.
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.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
void closeSockets()
Closes all open sockets.
Parser for the configuration of interfaces.
void parse(const CfgIfacePtr &config, const isc::data::ConstElementPtr &values)
Parses content of the "interfaces-config".
static void setRuntimeOptionDefs(const OptionDefSpaceContainer &defs)
Copies option definitions created at runtime.
static void revertRuntimeOptionDefs()
Reverts uncommitted changes to runtime option definitions.
parser for MAC/hardware acquisition sources
void parse(CfgMACSource &mac_sources, isc::data::ConstElementPtr value)
parses parameters value
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.
static size_t deriveParameters(isc::data::ElementPtr global)
Derives (inherits) all parameters from global to more specific scopes.
static size_t setAllDefaults(isc::data::ElementPtr global)
Sets all defaults for DHCPv6 configuration.
static const uint32_t CFGSEL_ALL6
IPv6 related config.
static void resetSubnetID()
Resets subnet-id counter to its initial value (1).
this class parses a list of DHCP6 subnets
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Wrapper class that holds hooks libraries configuration.
void verifyLibraries(const isc::data::Element::Position &position) const
Verifies that libraries stored in libraries_ are valid.
void loadLibraries() 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 ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Logging initialization functions.
#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)
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.
boost::shared_ptr< CfgDUID > CfgDUIDPtr
Pointer to the Non-const object.
std::pair< std::string, isc::data::ConstElementPtr > ConfigPair
Combination of parameter name and configuration contents.
const isc::log::MessageID DHCP6_PARSER_FAIL
const isc::log::MessageID DHCP6_PARSER_EXCEPTION
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
isc::data::ConstElementPtr configureDhcp6Server(Dhcpv6Srv &server, isc::data::ConstElementPtr config_set, bool check_only)
Configures DHCPv6 server.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
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.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const int DBG_DHCP6_COMMAND
Debug level used to log receiving commands.
const isc::log::MessageID DHCP6_CONFIG_COMPLETE
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
std::vector< HostPtr > HostCollection
Collection of the Host objects.
const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
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 > > > > Subnet6SimpleCollection
A simple collection of Subnet6 objects.
const isc::log::MessageID DHCP6_PARSER_COMMIT_EXCEPTION
const isc::log::MessageID DHCP6_CONFIG_START
const isc::log::MessageID DHCP6_PARSER_COMMIT_FAIL
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
boost::shared_ptr< ConfigControlInfo > ConfigControlInfoPtr
Defines a pointer to a ConfigControlInfo.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP6_OPTION_SPACE