Kea  1.9.9-git
base_network_parser.cc
Go to the documentation of this file.
1 // Copyright (C) 2019-2021 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>
8 #include <dhcpsrv/triplet.h>
10 #include <util/optional.h>
11 #include <util/strutil.h>
12 
13 using namespace isc::data;
14 using namespace isc::util;
15 
16 namespace isc {
17 namespace dhcp {
18 
19 void
20 BaseNetworkParser::moveReservationMode(ElementPtr config) {
21  if (!config->contains("reservation-mode")) {
22  return;
23  }
24  if (config->contains("reservations-global") ||
25  config->contains("reservations-in-subnet") ||
26  config->contains("reservations-out-of-pool")) {
27  isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
28  " and one of 'reservations-global', 'reservations-in-subnet'"
29  " or 'reservations-out-of-pool' parameters");
30  }
31  std::string hr_mode = getString(config, "reservation-mode");
32  if ((hr_mode == "disabled") || (hr_mode == "off")) {
33  config->set("reservations-global", Element::create(false));
34  config->set("reservations-in-subnet", Element::create(false));
35  } else if (hr_mode == "out-of-pool") {
36  config->set("reservations-global", Element::create(false));
37  config->set("reservations-in-subnet", Element::create(true));
38  config->set("reservations-out-of-pool", Element::create(true));
39  } else if (hr_mode == "global") {
40  config->set("reservations-global", Element::create(true));
41  config->set("reservations-in-subnet", Element::create(false));
42  } else if (hr_mode == "all") {
43  config->set("reservations-global", Element::create(false));
44  config->set("reservations-in-subnet", Element::create(true));
45  config->set("reservations-out-of-pool", Element::create(false));
46  } else {
47  isc_throw(DhcpConfigError, "invalid reservation-mode parameter: '"
48  << hr_mode << "' ("
49  << getPosition("reservation-mode", config) << ")");
50  }
51  config->remove("reservation-mode");
52 }
53 
54 void
55 BaseNetworkParser::parseCommon(const ConstElementPtr& network_data,
56  NetworkPtr& network) {
57  bool has_renew = network_data->contains("renew-timer");
58  bool has_rebind = network_data->contains("rebind-timer");
59  int64_t renew = -1;
60  int64_t rebind = -1;
61 
62  if (has_renew) {
63  renew = getInteger(network_data, "renew-timer");
64  if (renew < 0) {
65  isc_throw(DhcpConfigError, "the value of renew-timer" << " ("
66  << renew << ") must be a positive number");
67  }
68  network->setT1(renew);
69  }
70 
71  if (has_rebind) {
72  rebind = getInteger(network_data, "rebind-timer");
73  if (rebind < 0) {
74  isc_throw(DhcpConfigError, "the value of rebind-timer" << " ("
75  << rebind << ") must be a positive number");
76  }
77  network->setT2(rebind);
78  }
79 
80  if (has_renew && has_rebind && (renew > rebind)) {
81  isc_throw(DhcpConfigError, "the value of renew-timer" << " (" << renew
82  << ") is greater than the value of rebind-timer" << " ("
83  << rebind << ")");
84  }
85 
86  network->setValid(parseIntTriplet(network_data, "valid-lifetime"));
87 
88  if (network_data->contains("store-extended-info")) {
89  network->setStoreExtendedInfo(getBoolean(network_data,
90  "store-extended-info"));
91  }
92 
93  if (network_data->contains("reservations-global")) {
94  network->setReservationsGlobal(getBoolean(network_data,
95  "reservations-global"));
96  }
97 
98  if (network_data->contains("reservations-in-subnet")) {
99  network->setReservationsInSubnet(getBoolean(network_data,
100  "reservations-in-subnet"));
101  }
102 
103  if (network_data->contains("reservations-out-of-pool")) {
104  network->setReservationsOutOfPool(getBoolean(network_data,
105  "reservations-out-of-pool"));
106  }
107 }
108 
109 void
110 BaseNetworkParser::parseTeePercents(const ConstElementPtr& network_data,
111  NetworkPtr& network) {
112  bool calculate_tee_times = network->getCalculateTeeTimes();
113  if (network_data->contains("calculate-tee-times")) {
114  calculate_tee_times = getBoolean(network_data, "calculate-tee-times");
115  network->setCalculateTeeTimes(calculate_tee_times);
116  }
117 
118  Optional<double> t2_percent;
119  if (network_data->contains("t2-percent")) {
120  t2_percent = getDouble(network_data, "t2-percent");
121  }
122 
123  Optional<double> t1_percent;
124  if (network_data->contains("t1-percent")) {
125  t1_percent = getDouble(network_data, "t1-percent");
126  }
127  if (calculate_tee_times) {
128  if (!t2_percent.unspecified() && ((t2_percent.get() <= 0.0) ||
129  (t2_percent.get() >= 1.0))) {
130  isc_throw(DhcpConfigError, "t2-percent: " << t2_percent.get()
131  << " is invalid, it must be greater than 0.0 and less than 1.0");
132  }
133 
134  if (!t1_percent.unspecified() && ((t1_percent.get() <= 0.0) ||
135  (t1_percent.get() >= 1.0))) {
136  isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
137  << " is invalid it must be greater than 0.0 and less than 1.0");
138  }
139 
140  if (!t1_percent.unspecified() && !t2_percent.unspecified() &&
141  (t1_percent.get() >= t2_percent.get())) {
142  isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
143  << " is invalid, it must be less than t2-percent: "
144  << t2_percent.get());
145  }
146  }
147 
148  network->setT2Percent(t2_percent);
149  network->setT1Percent(t1_percent);
150 }
151 
152 void
153 BaseNetworkParser::parseCacheParams(const ConstElementPtr& network_data,
154  NetworkPtr& network) {
155  if (network_data->contains("cache-threshold")) {
156  double cache_threshold = getDouble(network_data, "cache-threshold");
157  if ((cache_threshold <= 0.0) || (cache_threshold >= 1.0)) {
158  isc_throw(DhcpConfigError, "cache-threshold: " << cache_threshold
159  << " is invalid, it must be greater than 0.0 and less than 1.0");
160  }
161  network->setCacheThreshold(cache_threshold);
162  }
163 
164  if (network_data->contains("cache-max-age")) {
165  network->setCacheMaxAge(getInteger(network_data, "cache-max-age"));
166  }
167 }
168 
169 void
170 BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
171  NetworkPtr& network) {
172 
173  if (network_data->contains("ddns-send-updates")) {
174  network->setDdnsSendUpdates(getBoolean(network_data, "ddns-send-updates"));
175  }
176 
177  if (network_data->contains("ddns-override-no-update")) {
178  network->setDdnsOverrideNoUpdate(getBoolean(network_data, "ddns-override-no-update"));
179  }
180 
181  if (network_data->contains("ddns-override-client-update")) {
182  network->setDdnsOverrideClientUpdate(getBoolean(network_data, "ddns-override-client-update"));
183  }
184 
185  if (network_data->contains("ddns-replace-client-name")) {
186  network->setDdnsReplaceClientNameMode(getAndConvert<D2ClientConfig::ReplaceClientNameMode,
187  D2ClientConfig::stringToReplaceClientNameMode>
188  (network_data, "ddns-replace-client-name",
189  "ReplaceClientName mode"));
190  }
191 
192  if (network_data->contains("ddns-generated-prefix")) {
193  network->setDdnsGeneratedPrefix(getString(network_data, "ddns-generated-prefix"));
194  }
195 
196  if (network_data->contains("ddns-qualifying-suffix")) {
197  network->setDdnsQualifyingSuffix(getString(network_data, "ddns-qualifying-suffix"));
198  }
199 
200  std::string hostname_char_set;
201  if (network_data->contains("hostname-char-set")) {
202  hostname_char_set = getString(network_data, "hostname-char-set");
203  network->setHostnameCharSet(hostname_char_set);
204  }
205 
206  std::string hostname_char_replacement;
207  if (network_data->contains("hostname-char-replacement")) {
208  hostname_char_replacement = getString(network_data, "hostname-char-replacement");
209  network->setHostnameCharReplacement(hostname_char_replacement);
210  }
211 
212  // We need to validate sanitizer values here so we can detect problems and
213  // cause a configuration. We don't retain the compilation because it's not
214  // something we can inherit.
215  if (!hostname_char_set.empty()) {
216  try {
217  str::StringSanitizerPtr sanitizer(new str::StringSanitizer(hostname_char_set,
218  hostname_char_replacement));
219  } catch (const std::exception& ex) {
220  isc_throw(BadValue, "hostname-char-set '" << hostname_char_set
221  << "' is not a valid regular expression");
222  }
223  }
224 
225  if (network_data->contains("ddns-update-on-renew")) {
226  network->setDdnsUpdateOnRenew(getBoolean(network_data, "ddns-update-on-renew"));
227  }
228 
229  if (network_data->contains("ddns-use-conflict-resolution")) {
230  network->setDdnsUseConflictResolution(getBoolean(network_data, "ddns-use-conflict-resolution"));
231  }
232 }
233 
234 } // end of namespace isc::dhcp
235 } // end of namespace isc
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:121
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
Definition: network.h:40
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
#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...
Definition: edns.h:19
To be removed. Please use ConfigError instead.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
Implements a regular expression based string scrubber.
Definition: strutil.h:303
Defines the logger used by the top-level component of kea-dhcp-ddns.
T get() const
Retrieves the encapsulated value.
Definition: optional.h:112
ReplaceClientNameMode
Defines the client name replacement modes.
Definition: d2_client_cfg.h:75
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:222
boost::shared_ptr< StringSanitizer > StringSanitizerPtr
Definition: strutil.h:348