Kea 1.9.11
network.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2020 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
9#include <dhcp/dhcp4.h>
10#include <dhcp/option_custom.h>
11#include <dhcp/option_space.h>
12#include <dhcpsrv/network.h>
13#include <boost/pointer_cast.hpp>
14
15using namespace isc::asiolink;
16using namespace isc::data;
17using namespace isc::util;
18
19namespace isc {
20namespace dhcp {
21
22void
24 if (containsAddress(addr)) {
25 isc_throw (BadValue, "RelayInfo already contains address: "
26 << addr.toText());
27 }
28
29 addresses_.push_back(addr);
30}
31
32bool
34 return (!addresses_.empty());
35}
36
37bool
39 for (auto address = addresses_.begin(); address != addresses_.end();
40 ++address) {
41 if ((*address) == addr) {
42 return (true);
43 }
44 }
45
46 return (false);
47}
48
49const IOAddressList&
51 return (addresses_);
52}
53
54void
56 relay_.addAddress(addr);
57}
58
59bool
61 return (relay_.hasAddresses());
62}
63
64bool
66 return (relay_.containsAddress(addr));
67}
68
69const IOAddressList&
71 return (relay_.getAddresses());
72}
73
74bool
76 if (client_class_.empty()) {
77 // There is no class defined for this network, so we do
78 // support everyone.
79 return (true);
80 }
81
82 return (classes.contains(client_class_));
83}
84
85void
87 client_class_ = class_name;
88}
89
90void
92 if (!required_classes_.contains(class_name)) {
93 required_classes_.insert(class_name);
94 }
95}
96
97const ClientClasses&
99 return (required_classes_);
100}
101
104 const std::string& global_name,
105 const std::string& /*min_name*/,
106 const std::string& /*max_name*/) const {
107 if (!global_name.empty() && fetch_globals_fn_) {
109 if (globals && (globals->getType() == Element::map)) {
110 ConstElementPtr global_param = globals->get(global_name);
111 if (global_param) {
112 std::string global_str = global_param->stringValue();
113 if (!global_str.empty()) {
114 return (IOAddress(global_str));
115 }
116 }
117 }
118 }
119 return (property);
120}
121
124 ElementPtr map = Element::createMap();
125
126 // Set user-context
127 contextToElement(map);
128
129 // Set interface
130 if (!iface_name_.unspecified()) {
131 map->set("interface", Element::create(iface_name_.get()));
132 }
133
134 ElementPtr relay_map = Element::createMap();
135 ElementPtr address_list = Element::createList();
136 const IOAddressList addresses = getRelayAddresses();
137 for (auto address = addresses.begin(); address != addresses.end(); ++address) {
138 address_list->add(Element::create((*address).toText()));
139 }
140
141 relay_map->set("ip-addresses", address_list);
142 map->set("relay", relay_map);
143
144 // Set client-class
145 if (!client_class_.unspecified()) {
146 map->set("client-class", Element::create(client_class_.get()));
147 }
148
149 // Set require-client-classes
150 const ClientClasses& classes = getRequiredClasses();
151 if (!classes.empty()) {
152 ElementPtr class_list = Element::createList();
153 for (ClientClasses::const_iterator it = classes.cbegin();
154 it != classes.cend(); ++it) {
155 class_list->add(Element::create(*it));
156 }
157 map->set("require-client-classes", class_list);
158 }
159
160 // T1, T2, and Valid are optional for SharedNetworks, and
161 // T1 and T2 are optional for Subnet4 thus we will only
162 // output them if they are marked as specified.
163 if (!t1_.unspecified()) {
164 map->set("renew-timer",
165 Element::create(static_cast<long long>(t1_.get())));
166 }
167
168 // Set rebind-timer
169 if (!t2_.unspecified()) {
170 map->set("rebind-timer",
171 Element::create(static_cast<long long>(t2_.get())));
172 }
173
174 // Set valid-lifetime
175 if (!valid_.unspecified()) {
176 map->set("valid-lifetime",
177 Element::create(static_cast<long long>(valid_.get())));
178 if (valid_.getMin() < valid_.get()) {
179 map->set("min-valid-lifetime",
180 Element::create(static_cast<long long>(valid_.getMin())));
181 }
182 if (valid_.getMax() > valid_.get()) {
183 map->set("max-valid-lifetime",
184 Element::create(static_cast<long long>(valid_.getMax())));
185 }
186 }
187
188 // Set reservations-global
189 if (!reservations_global_.unspecified()) {
190 map->set("reservations-global",
191 Element::create(reservations_global_.get()));
192 }
193
194 // Set reservations-in-subnet
195 if (!reservations_in_subnet_.unspecified()) {
196 map->set("reservations-in-subnet",
197 Element::create(reservations_in_subnet_.get()));
198 }
199
200 // Set reservations-out-of-pool
201 if (!reservations_out_of_pool_.unspecified()) {
202 map->set("reservations-out-of-pool",
203 Element::create(reservations_out_of_pool_.get()));
204 }
205
206 // Set options
208 map->set("option-data", opts->toElement());
209
210 // Output calculate-tee-times and percentages if calculation is enabled.
211 if (!calculate_tee_times_.unspecified()) {
212 map->set("calculate-tee-times", Element::create(calculate_tee_times_));
213 }
214
215 if (!t1_percent_.unspecified()) {
216 map->set("t1-percent", Element::create(t1_percent_));
217 }
218
219 if (!t2_percent_.unspecified()) {
220 map->set("t2-percent", Element::create(t2_percent_));
221 }
222
223 if (!ddns_send_updates_.unspecified()) {
224 map->set("ddns-send-updates", Element::create(ddns_send_updates_));
225 }
226
227 if (!ddns_override_no_update_.unspecified()) {
228 map->set("ddns-override-no-update", Element::create(ddns_override_no_update_));
229 }
230
231 if (!ddns_override_client_update_.unspecified()) {
232 map->set("ddns-override-client-update", Element::create(ddns_override_client_update_));
233 }
234
235 if (!ddns_replace_client_name_mode_.unspecified()) {
236 map->set("ddns-replace-client-name",
237 Element::create(D2ClientConfig::
238 replaceClientNameModeToString(ddns_replace_client_name_mode_)));
239 }
240
241 if (!ddns_generated_prefix_.unspecified()) {
242 map->set("ddns-generated-prefix", Element::create(ddns_generated_prefix_));
243 }
244
245 if (!ddns_qualifying_suffix_.unspecified()) {
246 map->set("ddns-qualifying-suffix", Element::create(ddns_qualifying_suffix_));
247 }
248
249 if (!hostname_char_set_.unspecified()) {
250 map->set("hostname-char-set", Element::create(hostname_char_set_));
251 }
252
253 if (!hostname_char_replacement_.unspecified()) {
254 map->set("hostname-char-replacement", Element::create(hostname_char_replacement_));
255 }
256
257 if (!store_extended_info_.unspecified()) {
258 map->set("store-extended-info", Element::create(store_extended_info_));
259 }
260
261 if (!cache_threshold_.unspecified()) {
262 map->set("cache-threshold", Element::create(cache_threshold_));
263 }
264
265 if (!cache_max_age_.unspecified()) {
266 map->set("cache-max-age",
267 Element::create(static_cast<long long>(cache_max_age_)));
268 }
269
270 if (!ddns_update_on_renew_.unspecified()) {
271 map->set("ddns-update-on-renew", Element::create(ddns_update_on_renew_));
272 }
273
274 if (!ddns_use_conflict_resolution_.unspecified()) {
275 map->set("ddns-use-conflict-resolution", Element::create(ddns_use_conflict_resolution_));
276 }
277
278 return (map);
279}
280
281void
283 if (!siaddr.get().isV4()) {
284 isc_throw(BadValue, "Can't set siaddr to non-IPv4 address "
285 << siaddr);
286 }
287 siaddr_ = siaddr;
288}
289
290void
292 sname_ = sname;
293}
294
295void
297 filename_ = filename;
298}
299
303
304 // Set match-client-id
305 if (!match_client_id_.unspecified()) {
306 map->set("match-client-id", Element::create(match_client_id_.get()));
307 }
308
309 // Set authoritative
310 if (!authoritative_.unspecified()) {
311 map->set("authoritative", Element::create(authoritative_.get()));
312 }
313
314 // Set next-server
315 if (!siaddr_.unspecified()) {
316 map->set("next-server", Element::create(siaddr_.get().toText()));
317 }
318
319 // Set server-hostname
320 if (!sname_.unspecified()) {
321 map->set("server-hostname", Element::create(sname_.get()));
322 }
323
324 // Set boot-file-name
325 if (!filename_.unspecified()) {
326 map->set("boot-file-name",Element::create(filename_.get()));
327 }
328
329 return (map);
330}
331
334 try {
335 OptionCustomPtr opt_server_id = boost::dynamic_pointer_cast<OptionCustom>
337 if (opt_server_id) {
338 return (opt_server_id->readAddress());
339 }
340 } catch (const std::exception&) {
341 // Ignore any exceptions and simply return empty buffer.
342 }
343
345}
346
350
351 // Set preferred-lifetime
352 if (!preferred_.unspecified()) {
353 map->set("preferred-lifetime",
354 Element::create(static_cast<long long>(preferred_.get())));
355 if (preferred_.getMin() < preferred_.get()) {
356 map->set("min-preferred-lifetime",
357 Element::create(static_cast<long long>(preferred_.getMin())));
358 }
359 if (preferred_.getMax() > preferred_.get()) {
360 map->set("max-preferred-lifetime",
361 Element::create(static_cast<long long>(preferred_.getMax())));
362 }
363 }
364
365 // Set interface-id
366 if (interface_id_) {
367 std::vector<uint8_t> bin = interface_id_->getData();
368 std::string ifid;
369 ifid.resize(bin.size());
370 if (!bin.empty()) {
371 std::memcpy(&ifid[0], &bin[0], bin.size());
372 }
373 map->set("interface-id", Element::create(ifid));
374 }
375
376 // Set rapid-commit
377 if (!rapid_commit_.unspecified()) {
378 map->set("rapid-commit", Element::create(rapid_commit_.get()));
379 }
380
381 return (map);
382}
383
384} // end of namespace isc::dhcp
385} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Container for storing client class names.
Definition: classify.h:43
bool contains(const ClientClass &x) const
returns if class x belongs to the defined classes
Definition: classify.h:99
void insert(const ClientClass &class_name)
Insert an element.
Definition: classify.h:62
std::list< ClientClass >::const_iterator const_iterator
Type of iterators.
Definition: classify.h:47
bool empty() const
Check if classes is empty.
Definition: classify.h:73
const_iterator cbegin() const
Iterator to the first element.
Definition: classify.h:86
const_iterator cend() const
Iterator to the past the end element.
Definition: classify.h:91
Acts as a storage vault for D2 client configuration.
Definition: d2_client_cfg.h:56
void setSiaddr(const util::Optional< asiolink::IOAddress > &siaddr)
Sets siaddr for the network.
Definition: network.cc:282
void setFilename(const util::Optional< std::string > &filename)
Sets boot file name for the network.
Definition: network.cc:296
virtual asiolink::IOAddress getServerId() const
Returns binary representation of the dhcp-server-identifier option (54).
Definition: network.cc:333
virtual data::ElementPtr toElement() const
Unparses network object.
Definition: network.cc:301
void setSname(const util::Optional< std::string > &sname)
Sets server hostname for the network.
Definition: network.cc:291
virtual data::ElementPtr toElement() const
Unparses network object.
Definition: network.cc:348
const IOAddressList & getAddresses() const
Returns const reference to the list of addresses.
Definition: network.cc:50
void addAddress(const asiolink::IOAddress &addr)
Adds an address to the list of addresses.
Definition: network.cc:23
bool containsAddress(const asiolink::IOAddress &addr) const
Checks the address list for the given address.
Definition: network.cc:38
bool hasAddresses() const
Indicates whether or not the address list has entries.
Definition: network.cc:33
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports client that belongs to specified classes.
Definition: network.cc:75
void addRelayAddress(const asiolink::IOAddress &addr)
Adds an address to the list addresses in the network's relay info.
Definition: network.cc:55
util::Optional< std::string > hostname_char_replacement_
A string to replace invalid characters when scrubbing hostnames.
Definition: network.h:1106
RelayInfo relay_
Relay information.
Definition: network.h:1031
util::Optional< bool > reservations_out_of_pool_
Enables out-of-pool reservations optimization.
Definition: network.h:1066
util::Optional< bool > ddns_update_on_renew_
Should Kea perform updates when leases are extended.
Definition: network.h:1119
CfgOptionPtr cfg_option_
Pointer to the option data configuration for this subnet.
Definition: network.h:1069
void requireClientClass(const isc::dhcp::ClientClass &class_name)
Adds class class_name to classes required to be evaluated.
Definition: network.cc:91
const IOAddressList & getRelayAddresses() const
Returns the list of relay addresses from the network's relay info.
Definition: network.cc:70
void allowClientClass(const isc::dhcp::ClientClass &class_name)
Sets the supported class to class class_name.
Definition: network.cc:86
util::Optional< bool > reservations_global_
Enables global reservations.
Definition: network.h:1056
util::Optional< bool > ddns_override_client_update_
Should Kea perform updates, even if client requested delegation.
Definition: network.h:1089
util::Optional< bool > reservations_in_subnet_
Enables subnet reservations.
Definition: network.h:1059
FetchNetworkGlobalsFn fetch_globals_fn_
Pointer to the optional callback used to fetch globally configured parameters inherited to the Networ...
Definition: network.h:1134
util::Optional< double > t2_percent_
Percentage of the lease lifetime to use when calculating T2 timer.
Definition: network.h:1078
util::Optional< std::string > ddns_generated_prefix_
Prefix Kea should use when generating domain-names.
Definition: network.h:1095
util::Optional< double > t1_percent_
Percentage of the lease lifetime to use when calculating T1 timer.
Definition: network.h:1075
bool hasRelays() const
Indicates if network's relay info has relay addresses.
Definition: network.cc:60
util::Optional< ClientClass > client_class_
Optional definition of a client class.
Definition: network.h:1038
virtual data::ElementPtr toElement() const
Unparses network object.
Definition: network.cc:123
util::Optional< std::string > hostname_char_set_
Regular expression describing invalid characters for client hostnames.
Definition: network.h:1102
bool hasRelayAddress(const asiolink::IOAddress &address) const
Tests if the network's relay info contains the given address.
Definition: network.cc:65
util::Optional< std::string > iface_name_
Holds interface name for which this network is selected.
Definition: network.h:1026
Triplet< uint32_t > valid_
a Triplet (min/default/max) holding allowed valid lifetime values
Definition: network.h:1053
const ClientClasses & getRequiredClasses() const
Returns classes which are required to be evaluated.
Definition: network.cc:98
util::Optional< bool > ddns_send_updates_
Should Kea perform DNS updates.
Definition: network.h:1082
Triplet< uint32_t > t1_
a Triplet (min/default/max) holding allowed renew timer values
Definition: network.h:1047
util::Optional< bool > store_extended_info_
Should Kea store additional client query data (e.g.
Definition: network.h:1110
util::Optional< bool > calculate_tee_times_
Enables calculation of T1 and T2 timers.
Definition: network.h:1072
util::Optional< bool > ddns_use_conflict_resolution_
Used to to tell kea-dhcp-ddns whether or not to use conflict resolution.
Definition: network.h:1122
util::Optional< uint32_t > cache_max_age_
Value in seconds to use as cache maximal age.
Definition: network.h:1116
util::Optional< bool > ddns_override_no_update_
Should Kea perform updates, even if client requested no updates.
Definition: network.h:1086
util::Optional< std::string > ddns_qualifying_suffix_
Suffix Kea should use when to qualify partial domain-names.
Definition: network.h:1098
ClientClasses required_classes_
Required classes.
Definition: network.h:1044
Triplet< uint32_t > t2_
a Triplet (min/default/max) holding allowed rebind timer values
Definition: network.h:1050
ReturnType getGlobalProperty(ReturnType property, const std::string &global_name, const std::string &min_name="", const std::string &max_name="") const
Returns a value of global configuration parameter with a given name.
Definition: network.h:782
util::Optional< D2ClientConfig::ReplaceClientNameMode > ddns_replace_client_name_mode_
How Kea should handle the domain-name supplied by the client.
Definition: network.h:1092
CfgOptionPtr getCfgOption()
Returns pointer to the option data configuration for this network.
Definition: network.h:436
util::Optional< double > cache_threshold_
Percentage of the lease lifetime to use as cache threshold.
Definition: network.h:1113
A template representing an optional value.
Definition: optional.h:36
T get() const
Retrieves the encapsulated value.
Definition: optional.h:112
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
std::string ClientClass
Defines a single class name.
Definition: classify.h:37
@ DHO_DHCP_SERVER_IDENTIFIER
Definition: dhcp4.h:123
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
std::vector< isc::asiolink::IOAddress > IOAddressList
List of IOAddresses.
Definition: network.h:38
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
Definition: cfg_option.h:709
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15