Kea  2.3.5-git
srv_config.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
9 #include <dhcpsrv/cfgmgr.h>
12 #include <dhcpsrv/srv_config.h>
14 #include <dhcpsrv/dhcpsrv_log.h>
15 #include <dhcpsrv/cfg_hosts_util.h>
16 #include <process/logging_info.h>
17 #include <log/logger_manager.h>
19 #include <dhcp/pkt.h> // Needed for HWADDR_SOURCE_*
20 #include <stats/stats_mgr.h>
21 #include <util/strutil.h>
22 
23 #include <boost/make_shared.hpp>
24 
25 #include <list>
26 #include <sstream>
27 
28 using namespace isc::log;
29 using namespace isc::data;
30 using namespace isc::process;
31 
32 namespace isc {
33 namespace dhcp {
34 
35 SrvConfig::SrvConfig()
36  : sequence_(0), cfg_iface_(new CfgIface()),
37  cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
38  cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
39  cfg_shared_networks4_(new CfgSharedNetworks4()),
40  cfg_shared_networks6_(new CfgSharedNetworks6()),
41  cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
42  cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
43  cfg_db_access_(new CfgDbAccess()),
44  cfg_host_operations4_(CfgHostOperations::createConfig4()),
45  cfg_host_operations6_(CfgHostOperations::createConfig6()),
46  class_dictionary_(new ClientClassDictionary()),
47  decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
48  d2_client_config_(new D2ClientConfig()),
49  configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()),
50  lenient_option_parsing_(false), ignore_rai_link_selection_(false),
51  reservations_lookup_first_(false) {
52 }
53 
54 SrvConfig::SrvConfig(const uint32_t sequence)
55  : sequence_(sequence), cfg_iface_(new CfgIface()),
56  cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
57  cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
58  cfg_shared_networks4_(new CfgSharedNetworks4()),
59  cfg_shared_networks6_(new CfgSharedNetworks6()),
60  cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
61  cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
62  cfg_db_access_(new CfgDbAccess()),
63  cfg_host_operations4_(CfgHostOperations::createConfig4()),
64  cfg_host_operations6_(CfgHostOperations::createConfig6()),
65  class_dictionary_(new ClientClassDictionary()),
66  decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
67  d2_client_config_(new D2ClientConfig()),
68  configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()),
69  lenient_option_parsing_(false), ignore_rai_link_selection_(false),
70  reservations_lookup_first_(false) {
71 }
72 
73 std::string
74 SrvConfig::getConfigSummary(const uint32_t selection) const {
75  std::ostringstream s;
76  size_t subnets_num;
77  if ((selection & CFGSEL_SUBNET4) == CFGSEL_SUBNET4) {
78  subnets_num = getCfgSubnets4()->getAll()->size();
79  if (subnets_num > 0) {
80  s << "added IPv4 subnets: " << subnets_num;
81  } else {
82  s << "no IPv4 subnets!";
83  }
84  s << "; ";
85  }
86 
87  if ((selection & CFGSEL_SUBNET6) == CFGSEL_SUBNET6) {
88  subnets_num = getCfgSubnets6()->getAll()->size();
89  if (subnets_num > 0) {
90  s << "added IPv6 subnets: " << subnets_num;
91  } else {
92  s << "no IPv6 subnets!";
93  }
94  s << "; ";
95  }
96 
97  if ((selection & CFGSEL_DDNS) == CFGSEL_DDNS) {
98  bool ddns_enabled = getD2ClientConfig()->getEnableUpdates();
99  s << "DDNS: " << (ddns_enabled ? "enabled" : "disabled") << "; ";
100  }
101 
102  if (s.tellp() == static_cast<std::streampos>(0)) {
103  s << "no config details available";
104  }
105 
106  std::string summary = s.str();
107  size_t last_separator_pos = summary.find_last_of(";");
108  if (last_separator_pos == summary.length() - 2) {
109  summary.erase(last_separator_pos);
110  }
111  return (summary);
112 }
113 
114 bool
116  return (getSequence() == other.getSequence());
117 }
118 
119 void
120 SrvConfig::copy(SrvConfig& new_config) const {
121  ConfigBase::copy(new_config);
122 
123  // Replace interface configuration.
124  new_config.cfg_iface_.reset(new CfgIface(*cfg_iface_));
125  // Replace option definitions.
126  cfg_option_def_->copyTo(*new_config.cfg_option_def_);
127  cfg_option_->copyTo(*new_config.cfg_option_);
128  // Replace the client class dictionary
129  new_config.class_dictionary_.reset(new ClientClassDictionary(*class_dictionary_));
130  // Replace the D2 client configuration
131  new_config.setD2ClientConfig(getD2ClientConfig());
132  // Replace configured hooks libraries.
133  new_config.hooks_config_.clear();
134  using namespace isc::hooks;
135  for (HookLibsCollection::const_iterator it = hooks_config_.get().begin();
136  it != hooks_config_.get().end(); ++it) {
137  new_config.hooks_config_.add(it->first, it->second);
138  }
139 }
140 
141 bool
142 SrvConfig::equals(const SrvConfig& other) const {
143 
144  // Checks common elements: logging & config control
145  if (!ConfigBase::equals(other)) {
146  return (false);
147  }
148 
149  // Common information is equal between objects, so check other values.
150  if ((*cfg_iface_ != *other.cfg_iface_) ||
151  (*cfg_option_def_ != *other.cfg_option_def_) ||
152  (*cfg_option_ != *other.cfg_option_) ||
153  (*class_dictionary_ != *other.class_dictionary_) ||
154  (*d2_client_config_ != *other.d2_client_config_)) {
155  return (false);
156  }
157  // Now only configured hooks libraries can differ.
158  // If number of configured hooks libraries are different, then
159  // configurations aren't equal.
160  if (hooks_config_.get().size() != other.hooks_config_.get().size()) {
161  return (false);
162  }
163  // Pass through all configured hooks libraries.
164  return (hooks_config_.equal(other.hooks_config_));
165 }
166 
167 void
169  ConfigBase::merge(other);
170  try {
171  SrvConfig& other_srv_config = dynamic_cast<SrvConfig&>(other);
172  // We merge objects in order of dependency (real or theoretical).
173  // First we merge the common stuff.
174 
175  // Merge globals.
176  mergeGlobals(other_srv_config);
177 
178  // Merge option defs. We need to do this next so we
179  // pass these into subsequent merges so option instances
180  // at each level can be created based on the merged
181  // definitions.
182  cfg_option_def_->merge((*other_srv_config.getCfgOptionDef()));
183 
184  // Merge options.
185  cfg_option_->merge(cfg_option_def_, (*other_srv_config.getCfgOption()));
186 
187  if (!other_srv_config.getClientClassDictionary()->empty()) {
188  // Client classes are complicated because they are ordered and may
189  // depend on each other. Merging two lists of classes with preserving
190  // the order would be very involved and could result in errors. Thus,
191  // we simply replace the current list of classes with a new list.
192  setClientClassDictionary(boost::make_shared
193  <ClientClassDictionary>(*other_srv_config.getClientClassDictionary()));
194  }
195 
196  if (CfgMgr::instance().getFamily() == AF_INET) {
197  merge4(other_srv_config);
198  } else {
199  merge6(other_srv_config);
200  }
201  } catch (const std::bad_cast&) {
202  isc_throw(InvalidOperation, "internal server error: must use derivation"
203  " of the SrvConfig as an argument of the call to"
204  " SrvConfig::merge()");
205  }
206 }
207 
208 void
209 SrvConfig::merge4(SrvConfig& other) {
210  // Merge shared networks.
211  cfg_shared_networks4_->merge(cfg_option_def_, *(other.getCfgSharedNetworks4()));
212 
213  // Merge subnets.
214  cfg_subnets4_->merge(cfg_option_def_, getCfgSharedNetworks4(),
215  *(other.getCfgSubnets4()));
216 
218 }
219 
220 void
221 SrvConfig::merge6(SrvConfig& other) {
222  // Merge shared networks.
223  cfg_shared_networks6_->merge(cfg_option_def_, *(other.getCfgSharedNetworks6()));
224 
225  // Merge subnets.
226  cfg_subnets6_->merge(cfg_option_def_, getCfgSharedNetworks6(),
227  *(other.getCfgSubnets6()));
228 
230 }
231 
232 void
233 SrvConfig::mergeGlobals(SrvConfig& other) {
234  auto config_set = getConfiguredGlobals();
235  // If the deprecated reservation-mode is found in database, overwrite other
236  // reservation flags so there is no conflict when merging to new flags.
241  }
242  // Iterate over the "other" globals, adding/overwriting them into
243  // this config's list of globals.
244  for (auto other_global : other.getConfiguredGlobals()->valuesMap()) {
245  addConfiguredGlobal(other_global.first, other_global.second);
246  }
247 
248  // Merge the reservation-mode to new reservation flags.
250 
251  // A handful of values are stored as members in SrvConfig. So we'll
252  // iterate over the merged globals, setting appropriate members.
253  for (auto merged_global : getConfiguredGlobals()->valuesMap()) {
254  std::string name = merged_global.first;
255  ConstElementPtr element = merged_global.second;
256  try {
257  if (name == "decline-probation-period") {
258  setDeclinePeriod(element->intValue());
259  } else if (name == "echo-client-id") {
260  // echo-client-id is v4 only, but we'll let upstream
261  // worry about that.
262  setEchoClientId(element->boolValue());
263  } else if (name == "dhcp4o6-port") {
264  setDhcp4o6Port(element->intValue());
265  } else if (name == "server-tag") {
266  setServerTag(element->stringValue());
267  } else if (name == "ip-reservations-unique") {
268  setIPReservationsUnique(element->boolValue());
269  } else if (name == "reservations-lookup-first") {
270  setReservationsLookupFirst(element->boolValue());
271  }
272  } catch(const std::exception& ex) {
273  isc_throw (BadValue, "Invalid value:" << element->str()
274  << " explicit global:" << name);
275  }
276  }
277 }
278 
279 void
281  // Removes statistics for v4 and v6 subnets
282  getCfgSubnets4()->removeStatistics();
283 
284  getCfgSubnets6()->removeStatistics();
285 }
286 
287 void
289  // Update default sample limits.
291  ConstElementPtr samples =
292  getConfiguredGlobal("statistic-default-sample-count");
293  uint32_t max_samples = 0;
294  if (samples) {
295  max_samples = samples->intValue();
296  stats_mgr.setMaxSampleCountDefault(max_samples);
297  if (max_samples != 0) {
298  stats_mgr.setMaxSampleCountAll(max_samples);
299  }
300  }
301  ConstElementPtr duration =
302  getConfiguredGlobal("statistic-default-sample-age");
303  if (duration) {
304  int64_t time_duration = duration->intValue();
305  auto max_age = std::chrono::seconds(time_duration);
306  stats_mgr.setMaxSampleAgeDefault(max_age);
307  if (max_samples == 0) {
308  stats_mgr.setMaxSampleAgeAll(max_age);
309  }
310  }
311 
312  // Updating subnet statistics involves updating lease statistics, which
313  // is done by the LeaseMgr. Since servers with subnets, must have a
314  // LeaseMgr, we do not bother updating subnet stats for servers without
315  // a lease manager, such as D2. @todo We should probably examine why
316  // "SrvConfig" is being used by D2.
318  // Updates statistics for v4 and v6 subnets
319  getCfgSubnets4()->updateStatistics();
320 
321  getCfgSubnets6()->updateStatistics();
322  }
323 }
324 
325 void
327  // Code from SimpleParser::setDefaults
328  // This is the position representing a default value. As the values
329  // we're inserting here are not present in whatever the config file
330  // came from, we need to make sure it's clearly labeled as default.
331  const Element::Position pos("<default-value>", 0, 0);
332 
333  // Let's go over all parameters we have defaults for.
334  for (auto def_value : defaults) {
335 
336  // Try if such a parameter is there. If it is, let's
337  // skip it, because user knows best *cough*.
338  ConstElementPtr x = getConfiguredGlobal(def_value.name_);
339  if (x) {
340  // There is such a value already, skip it.
341  continue;
342  }
343 
344  // There isn't such a value defined, let's create the default
345  // value...
346  switch (def_value.type_) {
347  case Element::string: {
348  x.reset(new StringElement(def_value.value_, pos));
349  break;
350  }
351  case Element::integer: {
352  try {
353  int int_value = boost::lexical_cast<int>(def_value.value_);
354  x.reset(new IntElement(int_value, pos));
355  }
356  catch (const std::exception& ex) {
358  "Internal error. Integer value expected for: "
359  << def_value.name_ << ", value is: "
360  << def_value.value_ );
361  }
362 
363  break;
364  }
365  case Element::boolean: {
366  bool bool_value;
367  if (def_value.value_ == std::string("true")) {
368  bool_value = true;
369  } else if (def_value.value_ == std::string("false")) {
370  bool_value = false;
371  } else {
373  "Internal error. Boolean value for "
374  << def_value.name_ << " specified as "
375  << def_value.value_ << ", expected true or false");
376  }
377  x.reset(new BoolElement(bool_value, pos));
378  break;
379  }
380  case Element::real: {
381  double dbl_value = boost::lexical_cast<double>(def_value.value_);
382  x.reset(new DoubleElement(dbl_value, pos));
383  break;
384  }
385  default:
386  // No default values for null, list or map
388  "Internal error. Incorrect default value type for "
389  << def_value.name_);
390  }
391  addConfiguredGlobal(def_value.name_, x);
392  }
393 }
394 
395 void
397  if (config->getType() != Element::map) {
398  isc_throw(BadValue, "extractConfiguredGlobals must be given a map element");
399  }
400 
401  const std::map<std::string, ConstElementPtr>& values = config->mapValue();
402  for (auto value = values.begin(); value != values.end(); ++value) {
403  if (value->second->getType() != Element::list &&
404  value->second->getType() != Element::map) {
405  addConfiguredGlobal(value->first, value->second);
406  }
407  }
408 }
409 
410 void
411 SrvConfig::sanityChecksLifetime(const std::string& name) const {
412  // Initialize as some compilers complain otherwise.
413  uint32_t value = 0;
414  ConstElementPtr has_value = getConfiguredGlobal(name);
415  if (has_value) {
416  value = has_value->intValue();
417  }
418 
419  uint32_t min_value = 0;
420  ConstElementPtr has_min = getConfiguredGlobal("min-" + name);
421  if (has_min) {
422  min_value = has_min->intValue();
423  }
424 
425  uint32_t max_value = 0;
426  ConstElementPtr has_max = getConfiguredGlobal("max-" + name);
427  if (has_max) {
428  max_value = has_max->intValue();
429  }
430 
431  if (!has_value && !has_min && !has_max) {
432  return;
433  }
434  if (has_value) {
435  if (!has_min && !has_max) {
436  // default only.
437  return;
438  } else if (!has_min) {
439  // default and max.
440  min_value = value;
441  } else if (!has_max) {
442  // default and min.
443  max_value = value;
444  }
445  } else if (has_min) {
446  if (!has_max) {
447  // min only.
448  return;
449  } else {
450  // min and max.
451  isc_throw(BadValue, "have min-" << name << " and max-"
452  << name << " but no " << name << " (default)");
453  }
454  } else {
455  // max only.
456  return;
457  }
458 
459  // Check that min <= max.
460  if (min_value > max_value) {
461  if (has_min && has_max) {
462  isc_throw(BadValue, "the value of min-" << name << " ("
463  << min_value << ") is not less than max-" << name << " ("
464  << max_value << ")");
465  } else if (has_min) {
466  // Only min and default so min > default.
467  isc_throw(BadValue, "the value of min-" << name << " ("
468  << min_value << ") is not less than (default) " << name
469  << " (" << value << ")");
470  } else {
471  // Only default and max so default > max.
472  isc_throw(BadValue, "the value of (default) " << name
473  << " (" << value << ") is not less than max-" << name
474  << " (" << max_value << ")");
475  }
476  }
477 
478  // Check that value is between min and max.
479  if ((value < min_value) || (value > max_value)) {
480  isc_throw(BadValue, "the value of (default) " << name << " ("
481  << value << ") is not between min-" << name << " ("
482  << min_value << ") and max-" << name << " ("
483  << max_value << ")");
484  }
485 }
486 
487 void
489  const std::string& name) const {
490  // Three cases:
491  // - the external/source config has the parameter: use it.
492  // - only the target config has the parameter: use this one.
493  // - no config has the parameter.
494  uint32_t value = 0;
495  ConstElementPtr has_value = getConfiguredGlobal(name);
496  bool new_value = true;
497  if (!has_value) {
498  has_value = target_config.getConfiguredGlobal(name);
499  new_value = false;
500  }
501  if (has_value) {
502  value = has_value->intValue();
503  }
504 
505  uint32_t min_value = 0;
506  ConstElementPtr has_min = getConfiguredGlobal("min-" + name);
507  bool new_min = true;
508  if (!has_min) {
509  has_min = target_config.getConfiguredGlobal("min-" + name);
510  new_min = false;
511  }
512  if (has_min) {
513  min_value = has_min->intValue();
514  }
515 
516  uint32_t max_value = 0;
517  ConstElementPtr has_max = getConfiguredGlobal("max-" + name);
518  bool new_max = true;
519  if (!has_max) {
520  has_max = target_config.getConfiguredGlobal("max-" + name);
521  new_max = false;
522  }
523  if (has_max) {
524  max_value = has_max->intValue();
525  }
526 
527  if (!has_value && !has_min && !has_max) {
528  return;
529  }
530  if (has_value) {
531  if (!has_min && !has_max) {
532  // default only.
533  return;
534  } else if (!has_min) {
535  // default and max.
536  min_value = value;
537  } else if (!has_max) {
538  // default and min.
539  max_value = value;
540  }
541  } else if (has_min) {
542  if (!has_max) {
543  // min only.
544  return;
545  } else {
546  // min and max.
547  isc_throw(BadValue, "have min-" << name << " and max-"
548  << name << " but no " << name << " (default)");
549  }
550  } else {
551  // max only.
552  return;
553  }
554 
555  // Check that min <= max.
556  if (min_value > max_value) {
557  if (has_min && has_max) {
558  std::string from_min = (new_min ? "new" : "previous");
559  std::string from_max = (new_max ? "new" : "previous");
560  isc_throw(BadValue, "the value of " << from_min
561  << " min-" << name << " ("
562  << min_value << ") is not less than "
563  << from_max << " max-" << name
564  << " (" << max_value << ")");
565  } else if (has_min) {
566  // Only min and default so min > default.
567  std::string from_min = (new_min ? "new" : "previous");
568  std::string from_value = (new_value ? "new" : "previous");
569  isc_throw(BadValue, "the value of " << from_min
570  << " min-" << name << " ("
571  << min_value << ") is not less than " << from_value
572  << " (default) " << name
573  << " (" << value << ")");
574  } else {
575  // Only default and max so default > max.
576  std::string from_max = (new_max ? "new" : "previous");
577  std::string from_value = (new_value ? "new" : "previous");
578  isc_throw(BadValue, "the value of " << from_value
579  << " (default) " << name
580  << " (" << value << ") is not less than " << from_max
581  << " max-" << name << " (" << max_value << ")");
582  }
583  }
584 
585  // Check that value is between min and max.
586  if ((value < min_value) || (value > max_value)) {
587  std::string from_value = (new_value ? "new" : "previous");
588  std::string from_min = (new_min ? "new" : "previous");
589  std::string from_max = (new_max ? "new" : "previous");
590  isc_throw(BadValue, "the value of " << from_value
591  <<" (default) " << name << " ("
592  << value << ") is not between " << from_min
593  << " min-" << name << " (" << min_value
594  << ") and " << from_max << " max-"
595  << name << " (" << max_value << ")");
596  }
597 }
598 
601  // Top level map
602  ElementPtr result = Element::createMap();
603 
604  // Get family for the configuration manager
605  uint16_t family = CfgMgr::instance().getFamily();
606 
607  // DhcpX global map initialized from configured globals
608  ElementPtr dhcp = configured_globals_->toElement();
609 
610  auto loggers_info = getLoggingInfo();
611  // Was in the Logging global map.
612  if (!loggers_info.empty()) {
613  // Set loggers list
614  ElementPtr loggers = Element::createList();
615  for (LoggingInfoStorage::const_iterator logger =
616  loggers_info.cbegin();
617  logger != loggers_info.cend(); ++logger) {
618  loggers->add(logger->toElement());
619  }
620  dhcp->set("loggers", loggers);
621  }
622 
623  // Set user-context
624  contextToElement(dhcp);
625 
626  // Set data directory if DHCPv6 and specified.
627  if (family == AF_INET6) {
628  const util::Optional<std::string>& datadir =
630  if (!datadir.unspecified()) {
631  dhcp->set("data-directory", Element::create(datadir));
632  }
633  }
634 
635  // Set decline-probation-period
636  dhcp->set("decline-probation-period",
637  Element::create(static_cast<long long>(decline_timer_)));
638  // Set echo-client-id (DHCPv4)
639  if (family == AF_INET) {
640  dhcp->set("echo-client-id", Element::create(echo_v4_client_id_));
641  }
642  // Set dhcp4o6-port
643  dhcp->set("dhcp4o6-port",
644  Element::create(static_cast<int>(dhcp4o6_port_)));
645  // Set dhcp-ddns
646  dhcp->set("dhcp-ddns", d2_client_config_->toElement());
647  // Set interfaces-config
648  dhcp->set("interfaces-config", cfg_iface_->toElement());
649  // Set option-def
650  dhcp->set("option-def", cfg_option_def_->toElement());
651  // Set option-data
652  dhcp->set("option-data", cfg_option_->toElement());
653 
654  // Set subnets and shared networks.
655 
656  // We have two problems to solve:
657  // - a subnet is unparsed once:
658  // * if it is a plain subnet in the global subnet list
659  // * if it is a member of a shared network in the shared network
660  // subnet list
661  // - unparsed subnets must be kept to add host reservations in them.
662  // Of course this can be done only when subnets are unparsed.
663 
664  // The list of all unparsed subnets
665  std::vector<ElementPtr> sn_list;
666 
667  if (family == AF_INET) {
668  // Get plain subnets
669  ElementPtr plain_subnets = Element::createList();
670  const Subnet4Collection* subnets = cfg_subnets4_->getAll();
671  for (Subnet4Collection::const_iterator subnet = subnets->cbegin();
672  subnet != subnets->cend(); ++subnet) {
673  // Skip subnets which are in a shared-network
674  SharedNetwork4Ptr network;
675  (*subnet)->getSharedNetwork(network);
676  if (network) {
677  continue;
678  }
679  ElementPtr subnet_cfg = (*subnet)->toElement();
680  sn_list.push_back(subnet_cfg);
681  plain_subnets->add(subnet_cfg);
682  }
683  dhcp->set("subnet4", plain_subnets);
684 
685  // Get shared networks
686  ElementPtr shared_networks = cfg_shared_networks4_->toElement();
687  dhcp->set("shared-networks", shared_networks);
688 
689  // Get subnets in shared network subnet lists
690  const std::vector<ElementPtr> networks = shared_networks->listValue();
691  for (auto network = networks.cbegin();
692  network != networks.cend(); ++network) {
693  const std::vector<ElementPtr> sh_list =
694  (*network)->get("subnet4")->listValue();
695  for (auto subnet = sh_list.cbegin();
696  subnet != sh_list.cend(); ++subnet) {
697  sn_list.push_back(*subnet);
698  }
699  }
700 
701  } else {
702  // Get plain subnets
703  ElementPtr plain_subnets = Element::createList();
704  const Subnet6Collection* subnets = cfg_subnets6_->getAll();
705  for (Subnet6Collection::const_iterator subnet = subnets->cbegin();
706  subnet != subnets->cend(); ++subnet) {
707  // Skip subnets which are in a shared-network
708  SharedNetwork6Ptr network;
709  (*subnet)->getSharedNetwork(network);
710  if (network) {
711  continue;
712  }
713  ElementPtr subnet_cfg = (*subnet)->toElement();
714  sn_list.push_back(subnet_cfg);
715  plain_subnets->add(subnet_cfg);
716  }
717  dhcp->set("subnet6", plain_subnets);
718 
719  // Get shared networks
720  ElementPtr shared_networks = cfg_shared_networks6_->toElement();
721  dhcp->set("shared-networks", shared_networks);
722 
723  // Get subnets in shared network subnet lists
724  const std::vector<ElementPtr> networks = shared_networks->listValue();
725  for (auto network = networks.cbegin();
726  network != networks.cend(); ++network) {
727  const std::vector<ElementPtr> sh_list =
728  (*network)->get("subnet6")->listValue();
729  for (auto subnet = sh_list.cbegin();
730  subnet != sh_list.cend(); ++subnet) {
731  sn_list.push_back(*subnet);
732  }
733  }
734  }
735 
736  // Host reservations
737  CfgHostsList resv_list;
738  resv_list.internalize(cfg_hosts_->toElement());
739 
740  // Insert global reservations
741  ConstElementPtr global_resvs = resv_list.get(SUBNET_ID_GLOBAL);
742  if (global_resvs->size() > 0) {
743  dhcp->set("reservations", global_resvs);
744  }
745 
746  // Insert subnet reservations
747  for (std::vector<ElementPtr>::const_iterator subnet = sn_list.cbegin();
748  subnet != sn_list.cend(); ++subnet) {
749  ConstElementPtr id = (*subnet)->get("id");
750  if (isNull(id)) {
751  isc_throw(ToElementError, "subnet has no id");
752  }
753  SubnetID subnet_id = id->intValue();
754  ConstElementPtr resvs = resv_list.get(subnet_id);
755  (*subnet)->set("reservations", resvs);
756  }
757 
758  // Set expired-leases-processing
759  ConstElementPtr expired = cfg_expiration_->toElement();
760  dhcp->set("expired-leases-processing", expired);
761  if (family == AF_INET6) {
762  // Set server-id (DHCPv6)
763  dhcp->set("server-id", cfg_duid_->toElement());
764 
765  // Set relay-supplied-options (DHCPv6)
766  dhcp->set("relay-supplied-options", cfg_rsoo_->toElement());
767  }
768  // Set lease-database
769  CfgLeaseDbAccess lease_db(*cfg_db_access_);
770  dhcp->set("lease-database", lease_db.toElement());
771  // Set hosts-databases
772  CfgHostDbAccess host_db(*cfg_db_access_);
773  ConstElementPtr hosts_databases = host_db.toElement();
774  if (hosts_databases->size() > 0) {
775  dhcp->set("hosts-databases", hosts_databases);
776  }
777  // Set host-reservation-identifiers
778  ConstElementPtr host_ids;
779  if (family == AF_INET) {
780  host_ids = cfg_host_operations4_->toElement();
781  } else {
782  host_ids = cfg_host_operations6_->toElement();
783  }
784  dhcp->set("host-reservation-identifiers", host_ids);
785  // Set mac-sources (DHCPv6)
786  if (family == AF_INET6) {
787  dhcp->set("mac-sources", cfg_mac_source_.toElement());
788  }
789  // Set control-socket (skip if null as empty is not legal)
790  if (!isNull(control_socket_)) {
791  dhcp->set("control-socket", UserContext::toElement(control_socket_));
792  }
793  // Set client-classes
794  ConstElementPtr client_classes = class_dictionary_->toElement();
796  if (!client_classes->empty()) {
797  dhcp->set("client-classes", client_classes);
798  }
799  // Set hooks-libraries
800  ConstElementPtr hooks_libs = hooks_config_.toElement();
801  dhcp->set("hooks-libraries", hooks_libs);
802  // Set DhcpX
803  result->set(family == AF_INET ? "Dhcp4" : "Dhcp6", dhcp);
804 
805  ConstElementPtr cfg_consist = cfg_consist_->toElement();
806  dhcp->set("sanity-checks", cfg_consist);
807 
808  // Set config-control (if it exists)
810  if (info) {
811  ConstElementPtr info_elem = info->toElement();
812  dhcp->set("config-control", info_elem);
813  }
814 
815  // Set dhcp-packet-control (if it exists)
816  data::ConstElementPtr dhcp_queue_control = getDHCPQueueControl();
817  if (dhcp_queue_control) {
818  dhcp->set("dhcp-queue-control", dhcp_queue_control);
819  }
820 
821  // Set multi-threading (if it exists)
822  data::ConstElementPtr dhcp_multi_threading = getDHCPMultiThreading();
823  if (dhcp_multi_threading) {
824  dhcp->set("multi-threading", dhcp_multi_threading);
825  }
826 
827  return (result);
828 }
829 
831 SrvConfig::getDdnsParams(const Subnet4Ptr& subnet) const {
832  return (DdnsParamsPtr(new DdnsParams(subnet,
833  getD2ClientConfig()->getEnableUpdates())));
834 }
835 
837 SrvConfig::getDdnsParams(const Subnet6Ptr& subnet) const {
838  return(DdnsParamsPtr(new DdnsParams(subnet,
839  getD2ClientConfig()->getEnableUpdates())));
840 }
841 
842 void
844  if (!srv_elem || (srv_elem->getType() != Element::map)) {
845  isc_throw(BadValue, "moveDdnsParams server config must be given a map element");
846  }
847 
848  if (!srv_elem->contains("dhcp-ddns")) {
849  /* nothing to do */
850  return;
851  }
852 
853  ElementPtr d2_elem = boost::const_pointer_cast<Element>(srv_elem->get("dhcp-ddns"));
854  if (!d2_elem || (d2_elem->getType() != Element::map)) {
855  isc_throw(BadValue, "moveDdnsParams dhcp-ddns is not a map");
856  }
857 
858  struct Param {
859  std::string from_name;
860  std::string to_name;
861  };
862 
863  std::vector<Param> params {
864  { "override-no-update", "ddns-override-no-update" },
865  { "override-client-update", "ddns-override-client-update" },
866  { "replace-client-name", "ddns-replace-client-name" },
867  { "generated-prefix", "ddns-generated-prefix" },
868  { "qualifying-suffix", "ddns-qualifying-suffix" },
869  { "hostname-char-set", "hostname-char-set" },
870  { "hostname-char-replacement", "hostname-char-replacement" }
871  };
872 
873  for (auto param : params) {
874  if (d2_elem->contains(param.from_name)) {
875  if (!srv_elem->contains(param.to_name)) {
876  // No global value for it already, so let's add it.
877  srv_elem->set(param.to_name, d2_elem->get(param.from_name));
879  .arg(param.from_name).arg(param.to_name);
880  } else {
881  // Already a global value, we'll use it and ignore this one.
883  .arg(param.from_name).arg(param.to_name);
884  }
885 
886  // Now remove it from d2_data, so D2ClientCfg won't complain.
887  d2_elem->remove(param.from_name);
888  }
889  }
890 }
891 
892 void
894  if (!getCfgDbAccess()->getIPReservationsUnique() && unique) {
896  }
897  getCfgHosts()->setIPReservationsUnique(unique);
898  getCfgDbAccess()->setIPReservationsUnique(unique);
899 }
900 
901 void
903  Option::lenient_parsing_ = lenient_option_parsing_;
904 }
905 
906 bool
908  if (!subnet_) {
909  return (false);
910  }
911 
912  return (d2_client_enabled_ && subnet_->getDdnsSendUpdates().get());
913 }
914 
915 bool
917  if (!subnet_) {
918  return (false);
919  }
920 
921  return (subnet_->getDdnsOverrideNoUpdate().get());
922 }
923 
925  if (!subnet_) {
926  return (false);
927  }
928 
929  return (subnet_->getDdnsOverrideClientUpdate().get());
930 }
931 
934  if (!subnet_) {
935  return (D2ClientConfig::RCM_NEVER);
936  }
937 
938  return (subnet_->getDdnsReplaceClientNameMode().get());
939 }
940 
941 std::string
943  if (!subnet_) {
944  return ("");
945  }
946 
947  return (subnet_->getDdnsGeneratedPrefix().get());
948 }
949 
950 std::string
952  if (!subnet_) {
953  return ("");
954  }
955 
956  return (subnet_->getDdnsQualifyingSuffix().get());
957 }
958 
959 std::string
961  if (!subnet_) {
962  return ("");
963  }
964 
965  return (subnet_->getHostnameCharSet().get());
966 }
967 
968 std::string
970  if (!subnet_) {
971  return ("");
972  }
973 
974  return (subnet_->getHostnameCharReplacement().get());
975 }
976 
980  if (subnet_) {
981  std::string char_set = getHostnameCharSet();
982  if (!char_set.empty()) {
983  try {
984  sanitizer.reset(new util::str::StringSanitizer(char_set,
985  getHostnameCharReplacement()));
986  } catch (const std::exception& ex) {
987  isc_throw(BadValue, "hostname_char_set_: '" << char_set <<
988  "' is not a valid regular expression");
989  }
990  }
991  }
992 
993  return (sanitizer);
994 }
995 
996 bool
998  if (!subnet_) {
999  return (false);
1000  }
1001 
1002  return (subnet_->getDdnsUpdateOnRenew().get());
1003 }
1004 
1005 bool
1007  if (!subnet_) {
1008  return (true);
1009  }
1010 
1011  return (subnet_->getDdnsUseConflictResolution().get());
1012 }
1013 
1014 } // namespace dhcp
1015 } // namespace isc
const isc::log::MessageID DHCPSRV_CFGMGR_IP_RESERVATIONS_UNIQUE_DUPLICATES_POSSIBLE
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
Represents configuration of the RSOO options for the DHCP server.
Definition: cfg_rsoo.h:25
D2ClientConfigPtr getD2ClientConfig()
Returns pointer to the D2 client configuration.
Definition: srv_config.h:825
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:136
void internalize(isc::data::ConstElementPtr list)
Internalize a list Element.
uint32_t getSequence() const
Returns configuration sequence number.
Definition: srv_config.h:243
util::Optional< std::string > getDataDir() const
returns path do the data directory
Definition: cfgmgr.cc:31
SrvConfig()
Default constructor.
Definition: srv_config.cc:35
bool getOverrideClientUpdate() const
Returns whether or not Kea should perform updates, even if client requested delegation.
Definition: srv_config.cc:924
D2ClientConfig::ReplaceClientNameMode getReplaceClientNameMode() const
Returns how Kea should handle the domain-name supplied by the client.
Definition: srv_config.cc:933
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
Utility class to represent host reservation configurations internally as a map keyed by subnet IDs...
Holds subnets configured for the DHCPv6 server.
Definition: cfg_subnets6.h:34
std::string getQualifyingSuffix() const
Returns the suffix Kea should use when to qualify partial domain-names.
Definition: srv_config.cc:951
void setMaxSampleCountDefault(uint32_t max_samples)
Set default count limit.
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet).
static void moveDdnsParams(isc::data::ElementPtr srv_elem)
Moves deprecated parameters from dhcp-ddns element to global element.
Definition: srv_config.cc:843
Represents configuration of IPv4 shared networks.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
Base class for all configurations.
Definition: config_base.h:33
Cannot unparse error.
void removeStatistics()
Removes statistics.
Definition: srv_config.cc:280
const isc::data::ConstElementPtr getDHCPMultiThreading() const
Returns DHCP multi threading information.
Definition: srv_config.h:557
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
Definition: subnet.h:477
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
std::string getHostnameCharSet() const
Returns the regular expression describing invalid characters for client hostnames.
Definition: srv_config.cc:960
void setMaxSampleCountAll(uint32_t max_samples)
Set count limit for all collected statistics.
CfgSubnets6Ptr getCfgSubnets6()
Returns pointer to non-const object holding subnets configuration for DHCPv6.
Definition: srv_config.h:359
Holds configuration parameters pertaining to lease expiration and lease affinity. ...
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition: data.cc:1088
void updateStatistics()
Updates statistics.
Definition: srv_config.cc:288
const isc::data::ConstElementPtr getDHCPQueueControl() const
Returns DHCP queue control information.
Definition: srv_config.h:543
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:291
void setIPReservationsUnique(const bool unique)
Configures the server to allow or disallow specifying multiple hosts with the same IP address/subnet...
Definition: srv_config.cc:893
Maintains a list of ClientClassDef&#39;s.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:286
isc::data::ConstElementPtr getConfiguredGlobal(std::string name) const
Returns pointer to a given configured global parameter.
Definition: srv_config.h:868
static StatsMgr & instance()
Statistics Manager accessor method.
Statistics Manager class.
process::ConstConfigControlInfoPtr getConfigControlInfo() const
Fetches a read-only copy of the configuration control information.
Definition: config_base.h:106
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
Definition: srv_config.h:172
void clear()
Removes all configured hooks libraries.
Definition: hooks_config.h:59
void setMaxSampleAgeAll(const StatsDuration &duration)
Set duration limit for all collected statistics.
CfgOptionDefPtr getCfgOptionDef()
Return pointer to non-const object representing user-defined option definitions.
Definition: srv_config.h:286
void configureLowerLevelLibraries() const
Convenience method to propagate configuration parameters through inversion of control.
Definition: srv_config.cc:902
std::string getConfigSummary(const uint32_t selection) const
Returns summary of the configuration in the textual format.
Definition: srv_config.cc:74
void setEchoClientId(const bool echo)
Sets whether server should send back client-id in DHCPv4.
Definition: srv_config.h:792
#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...
bool getUseConflictResolution() const
Returns whether or not keah-dhcp-ddns should use conflict resolution.
Definition: srv_config.cc:1006
Parameters for various consistency checks.
CfgSharedNetworks6Ptr getCfgSharedNetworks6() const
Returns pointer to non-const object holding configuration of shared networks in DHCPv6.
Definition: srv_config.h:343
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:318
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 > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, 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 > > >> Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:866
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1360
virtual isc::data::ElementPtr toElement() const
Unparse.
bool getEnableUpdates() const
Returns whether or not DHCP DDNS updating is enabled.
Definition: srv_config.cc:907
void setDeclinePeriod(const uint32_t decline_timer)
Sets decline probation-period.
Definition: srv_config.h:773
void setReservationsLookupFirst(const bool first)
Sets whether the server does host reservations lookup before lease lookup.
Definition: srv_config.h:961
Acts as a storage vault for D2 client configuration.
Definition: d2_client_cfg.h:57
uint16_t getFamily() const
Returns address family.
Definition: cfgmgr.h:280
Notes: IntElement type is changed to int64_t.
Definition: data.h:590
void addConfiguredGlobal(const std::string &name, isc::data::ConstElementPtr value)
Adds a parameter to the collection configured globals.
Definition: srv_config.h:903
Class to store configured global parameters.
Definition: cfg_globals.h:25
static void moveReservationMode(isc::data::ElementPtr config)
Moves deprecated reservation-mode parameter to new reservations flags.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
Represents option definitions used by the DHCP server.
Holds access parameters and the configuration of the lease and hosts database connection.
Definition: cfg_db_access.h:25
CfgDbAccessPtr getCfgDbAccess()
Returns pointer to the object holding configuration of the lease and host database connection paramet...
Definition: srv_config.h:445
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy an Element map.
Definition: user_context.cc:24
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
Represents global configuration for host reservations.
Holds subnets configured for the DHCPv4 server.
Definition: cfg_subnets4.h:33
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
Definition: srv_config.h:47
bool getOverrideNoUpdate() const
Returns whether or not Kea should perform updates, even if client requested no updates.
Definition: srv_config.cc:916
Implements a regular expression based string scrubber.
Definition: strutil.h:311
isc::util::str::StringSanitizerPtr getHostnameSanitizer() const
Returns a regular expression string sanitizer.
Definition: srv_config.cc:978
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
Represents the position of the data element within a configuration string.
Definition: data.h:92
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.
Definition: subnet.h:937
utility class for unparsing
Represents configuration of IPv6 shared networks.
Specifies current DHCP configuration.
Definition: srv_config.h:177
Defines the logger used by the top-level component of kea-lfc.
void add(std::string libname, isc::data::ConstElementPtr parameters)
Adds additional hooks libraries.
Definition: hooks_config.h:46
isc::log::Logger logger("asiodns")
Use the ASIO logger.
bool equals(const SrvConfig &other) const
Compares two objects for equality.
Definition: srv_config.cc:142
virtual void merge(ConfigBase &other)
Merges the configuration specified as a parameter into this configuration.
Definition: srv_config.cc:168
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
Definition: data.cc:1139
const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED
const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED
ReplaceClientNameMode
Defines the client name replacement modes.
Definition: d2_client_cfg.h:76
static const uint32_t CFGSEL_SUBNET4
Number of IPv4 subnets.
Definition: srv_config.h:185
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:241
const isc::hooks::HookLibsCollection & get() const
Provides access to the configured hooks libraries.
Definition: hooks_config.h:54
void setClientClassDictionary(const ClientClassDictionaryPtr &dictionary)
Sets the client class dictionary.
Definition: srv_config.h:587
void setServerTag(const util::Optional< std::string > &server_tag)
Sets the server&#39;s logical name.
Definition: config_base.h:127
A generic exception that is thrown if a function is called in a prohibited way.
bool sequenceEquals(const SrvConfig &other)
Compares configuration sequence with other sequence.
Definition: srv_config.cc:115
void extractConfiguredGlobals(isc::data::ConstElementPtr config)
Saves scalar elements from the global scope of a configuration.
Definition: srv_config.cc:396
The Element class represents a piece of data, used by the command channel and configuration parts...
Definition: data.h:70
Represents the host reservations specified in the configuration file.
Definition: cfg_hosts.h:37
static const uint32_t CFGSEL_DDNS
DDNS enabled/disabled.
Definition: srv_config.h:193
std::string getHostnameCharReplacement() const
Returns the string to replace invalid characters when scrubbing hostnames.
Definition: srv_config.cc:969
DdnsParamsPtr getDdnsParams(const Subnet4Ptr &subnet) const
Fetches the DDNS parameters for a given DHCPv4 subnet.
Definition: srv_config.cc:831
ClientClassDictionaryPtr getClientClassDictionary()
Returns pointer to the dictionary of global client class definitions.
Definition: srv_config.h:572
void setMaxSampleAgeDefault(const StatsDuration &duration)
Set default duration limit.
bool getUpdateOnRenew() const
Returns whether or not DNS should be updated when leases renew.
Definition: srv_config.cc:997
static bool haveInstance()
Indicates if the lease manager has been instantiated.
CfgHostsPtr getCfgHosts()
Returns pointer to the non-const objects representing host reservations for different IPv4 and IPv6 s...
Definition: srv_config.h:375
void sanityChecksLifetime(const std::string &name) const
Conducts sanity checks on global lifetime parameters.
Definition: srv_config.cc:411
CfgSubnets4Ptr getCfgSubnets4()
Returns pointer to non-const object holding subnets configuration for DHCPv4.
Definition: srv_config.h:325
isc::data::ConstElementPtr get(SubnetID id) const
Return the host reservations for a subnet ID.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
Definition: subnet.h:635
boost::shared_ptr< StringSanitizer > StringSanitizerPtr
Type representing the pointer to the StringSanitizer.
Definition: strutil.h:359
void copy(SrvConfig &new_config) const
Copies the current configuration to a new configuration.
Definition: srv_config.cc:120
CfgOptionPtr getCfgOption()
Returns pointer to the non-const object holding options.
Definition: srv_config.h:307
static const uint32_t CFGSEL_SUBNET6
Number of IPv6 subnets.
Definition: srv_config.h:187
CfgSharedNetworks4Ptr getCfgSharedNetworks4() const
Returns pointer to non-const object holding configuration of shared networks in DHCPv4;.
Definition: srv_config.h:334
void applyDefaultsConfiguredGlobals(const isc::data::SimpleDefaults &defaults)
Applies defaults to global parameters.
Definition: srv_config.cc:326
const process::LoggingInfoStorage & getLoggingInfo() const
Returns logging specific configuration.
Definition: config_base.h:43
virtual isc::data::ElementPtr toElement() const
Unparse.
std::string getGeneratedPrefix() const
Returns the Prefix Kea should use when generating domain-names.
Definition: srv_config.cc:942
void setDhcp4o6Port(uint16_t port)
Sets DHCP4o6 IPC port.
Definition: srv_config.h:809
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition: option.h:483
Holds manual configuration of the server identifier (DUID).
Definition: cfg_duid.h:30
void setD2ClientConfig(const D2ClientConfigPtr &d2_client_config)
Sets the D2 client configuration.
Definition: srv_config.h:839
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
CfgGlobalsPtr getConfiguredGlobals()
Returns non-const pointer to configured global parameters.
Definition: srv_config.h:849
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: srv_config.cc:600
boost::shared_ptr< const ConfigControlInfo > ConstConfigControlInfoPtr
Defines a pointer to a const ConfigControlInfo.