Kea: cfg_iface.cc Source File

| Kea 3.2.0-git

cfg_iface.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2026 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 <dhcp/iface_mgr.h>
9#include <dhcpsrv/dhcpsrv_log.h>
10#include <dhcpsrv/cfg_iface.h>
11#include <dhcpsrv/timer_mgr.h>
12#include <util/reconnect_ctl.h>
13#include <util/multi_threading_mgr.h>
14#include <util/str.h>
15#include <algorithm>
16#include <functional>
17
18using namespace isc::asiolink;
19using namespace isc::data;
20using namespace isc::util;
21namespace ph = std::placeholders;
22
23namespace isc {
24namespace dhcp {
25
26const char* CfgIface::ALL_IFACES_KEYWORD = "*";
27
28 CfgIface::OpenSocketsFailedCallback CfgIface::open_sockets_failed_callback_ = 0;
29
30CfgIface::CfgIface()
31 : wildcard_used_(false), socket_type_(SOCKET_RAW), re_detect_(false),
32 service_socket_require_all_(false), service_sockets_retry_wait_time_(5000),
33 service_sockets_max_retries_(0),
34 outbound_iface_(SAME_AS_INBOUND) {
35}
36
37void
38CfgIface::closeSockets() const {
39 IfaceMgr::instance().closeSockets();
40}
41
42bool
43CfgIface::equals(const CfgIface& other) const {
44 return (iface_set_ == other.iface_set_ &&
45 address_map_ == other.address_map_ &&
46 wildcard_used_ == other.wildcard_used_ &&
47 socket_type_ == other.socket_type_);
48}
49
50bool
51CfgIface::multipleAddressesPerInterfaceActive() {
52 for (auto const& iface : IfaceMgr::instance().getIfaces()) {
53 if (iface->countActive4() > 1) {
54 return (true);
55 }
56 }
57 return (false);
58}
59
60void
61CfgIface::openSockets(const uint16_t family, const uint16_t port,
62 const bool use_bcast) {
63 // Close any open sockets because we're going to modify some properties
64 // of the IfaceMgr. Those modifications require that sockets are closed.
65 closeSockets();
66
67 // Initialize IfaceMgr FDEventHandler.
68 IfaceMgr::instance().initializeFDEventHandler();
69
70 // For the DHCPv4 server, if the user has selected that raw sockets
71 // should be used, we will try to configure the Interface Manager to
72 // support the direct responses to the clients that don't have the
73 // IP address. This should effectively turn on the use of raw
74 // sockets. However, this may be unsupported on some operating
75 // systems, so there is no guarantee.
76 if ((family == AF_INET) && (!IfaceMgr::instance().isTestMode())) {
77 IfaceMgr::instance().setMatchingPacketFilter(socket_type_ == SOCKET_RAW);
78 if ((socket_type_ == SOCKET_RAW) &&
79 !IfaceMgr::instance().isDirectResponseSupported()) {
80 LOG_WARN(dhcpsrv_logger, DHCPSRV_CFGMGR_SOCKET_RAW_UNSUPPORTED);
81 }
82 }
83
84 // Use broadcast only if we're using raw sockets. For the UDP sockets,
85 // we only handle the relayed (unicast) traffic.
86 const bool can_use_bcast = use_bcast && (socket_type_ == SOCKET_RAW);
87
88 reconnect_ctl_ = makeReconnectCtl();
89 auto sopen = openSocketsWithRetry(reconnect_ctl_, family, port, can_use_bcast, false);
90
91 if (!sopen) {
92 // If no socket were opened, log a warning because the server will
93 // not respond to any queries.
94 LOG_WARN(dhcpsrv_logger, DHCPSRV_NO_SOCKETS_OPEN);
95 }
96}
97
98void
99CfgIface::triggerOpenSocketsWithRetry(const uint16_t family, const uint16_t port,
100 const bool use_bcast) {
101 // Use broadcast only if we're using raw sockets. For the UDP sockets,
102 // we only handle the relayed (unicast) traffic.
103 const bool can_use_bcast = use_bcast && (socket_type_ == SOCKET_RAW);
104
105 reconnect_ctl_->resetRetries();
106
107 openSocketsWithRetry(reconnect_ctl_, family, port, can_use_bcast, true);
108}
109
110std::pair<bool, bool>
111CfgIface::openSocketsForFamily(const uint16_t family, const uint16_t port,
112 const bool can_use_bcast, const bool skip_opened) {
113 bool no_errors = true;
114
115 // Set the callbacks which are called when the socket fails to open
116 // for some specific interface.
117 auto error_callback = [&no_errors](const std::string& errmsg) {
118 socketOpenErrorHandler(errmsg);
119 no_errors = false;
120 };
121
122 bool sopen = false;
123 if (family == AF_INET) {
124 sopen = IfaceMgr::instance().openSockets4(port, can_use_bcast,
125 error_callback, skip_opened);
126 } else {
127 // use_bcast is ignored for V6.
128 sopen = IfaceMgr::instance().openSockets6(port, error_callback,
129 skip_opened);
130 }
131
132 return (std::make_pair(sopen, no_errors));
133}
134
135 ReconnectCtlPtr CfgIface::makeReconnectCtl() const {
136 // Create unique timer name per instance.
137 std::string timer_name = "SocketReopenTimer";
138
139 auto on_fail_action = OnFailAction::SERVE_RETRY_CONTINUE;
140 if (CfgIface::getServiceSocketsRequireAll()) {
141 on_fail_action = OnFailAction::SERVE_RETRY_EXIT;
142 }
143
144 // Add one attempt for an initial call.
145 auto reconnect_ctl = boost::make_shared<ReconnectCtl>("Socket", timer_name,
146 CfgIface::getServiceSocketsMaxRetries(),
147 CfgIface::getServiceSocketsRetryWaitTime(),
148 on_fail_action, 0);
149
150 return (reconnect_ctl);
151}
152
153bool
154CfgIface::openSocketsWithRetry(ReconnectCtlPtr reconnect_ctl,
155 const uint16_t family, const uint16_t port,
156 const bool can_use_bcast, bool skip_opened) const {
157 MultiThreadingCriticalSection cs;
158
159 ReceiverCriticalSection rcs;
160
161 // The detection must be done before resetting and setting the
162 // inactive4_ and inactive6_ flags.
163 IfaceMgr::instance().detectIfaces(true);
164
165 // Remove selection of unicast addresses from all interfaces.
166 IfaceMgr::instance().clearUnicasts();
167
168 // The loopback interface can be used only when:
169 // - UDP socket will be used, i.e. not IPv4 and RAW socket
170 // - the loopback interface is in the interface set or the address map.
171 bool loopback_used = false;
172 if ((family == AF_INET6) || (socket_type_ == SOCKET_UDP)) {
173 // Check interface set
174 for (auto const& iface_name : iface_set_) {
175 IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
176 if (iface && iface->flag_loopback_) {
177 loopback_used = true;
178 }
179 }
180 // Check address map
181 for (auto const& unicast : address_map_) {
182 IfacePtr iface = IfaceMgr::instance().getIface(unicast.first);
183 if (iface && iface->flag_loopback_) {
184 loopback_used = true;
185 }
186 }
187 }
188 // Allow the loopback interface when required.
189 IfaceMgr::instance().setAllowLoopBack(loopback_used);
190
191 // If wildcard interface '*' was not specified, set all interfaces to
192 // inactive state. We will later enable them selectively using the
193 // interface names specified by the user. If wildcard interface was
194 // specified, mark all interfaces active. Mark loopback inactive when
195 // not explicitly allowed.
196 setState(family, !wildcard_used_, !loopback_used);
197
198 // If there is no wildcard interface specified, we will have to iterate
199 // over the names specified by the caller and enable them.
200 if (!wildcard_used_) {
201 for (auto const& iface_name : iface_set_) {
202 IfacePtr iface = IfaceMgr::instance().getIface(iface_name);
203
204 // This shouldn't really happen because we are checking the
205 // names of interfaces when they are being added (use()
206 // function). But, if someone has triggered detection of
207 // interfaces since then, some interfaces may have disappeared.
208 if (iface == NULL) {
209 isc_throw(Unexpected,
210 "fail to open socket on interface '"
211 << iface_name << "' as this interface doesn't"
212 " exist");
213 }
214 if (family == AF_INET) {
215 iface->inactive4_ = false;
216 setIfaceAddrsState(family, true, *iface);
217
218 } else {
219 iface->inactive6_ = false;
220 }
221 }
222 }
223
224 // Select unicast sockets for DHCPv6 or activate specific IPv4 addresses
225 // for DHCPv4.
226 for (auto const& unicast : address_map_) {
227 IfacePtr iface = IfaceMgr::instance().getIface(unicast.first);
228 if (iface == NULL) {
229 isc_throw(Unexpected,
230 "fail to open unicast socket on interface '"
231 << unicast.first << "' as this interface doesn't"
232 " exist");
233 }
234 if (family == AF_INET6) {
235 iface->addUnicast(unicast.second);
236 iface->inactive6_ = false;
237
238 } else {
239 iface->setActive(unicast.second, true);
240 iface->inactive4_ = false;
241 }
242 }
243
244 // Opening multiple raw sockets handling brodcast traffic on the single
245 // interface may lead to processing the same message multiple times.
246 // We don't prohibit such configuration because raw sockets can as well
247 // handle the relayed traffic. We have to issue a warning, however, to
248 // draw administrator's attention.
249 if (family == AF_INET && can_use_bcast &&
250 CfgIface::multipleAddressesPerInterfaceActive()) {
251 LOG_WARN(dhcpsrv_logger, DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE);
252 }
253
254 // Skip opened sockets in the retry calls.
255 bool is_initial_call = false;
256 if (!skip_opened) {
257 is_initial_call = (reconnect_ctl->retriesLeft() == reconnect_ctl->maxRetries());
258 }
259 auto result_pair = CfgIface::openSocketsForFamily(family, port, can_use_bcast, !is_initial_call);
260 bool sopen = result_pair.first;
261 bool has_errors = !result_pair.second;
262
263 auto timer_name = reconnect_ctl->timerName();
264
265 // On the initial call, unregister the previous, pending timer.
266 if (is_initial_call && TimerMgr::instance()->isTimerRegistered(timer_name)) {
267 TimerMgr::instance()->unregisterTimer(timer_name);
268 }
269
270 // Has errors and can retry
271 if (has_errors && reconnect_ctl->retriesLeft() > 0) {
272 // Initial call is excluded from retries counter.
273 reconnect_ctl->checkRetries();
274 // Start the timer.
275 if (!TimerMgr::instance()->isTimerRegistered(timer_name)) {
276 TimerMgr::instance()->registerTimer(timer_name,
277 std::bind(&CfgIface::openSocketsWithRetry,
278 this,
279 reconnect_ctl, family,
280 port, can_use_bcast, false),
281 reconnect_ctl->retryInterval(),
282 asiolink::IntervalTimer::ONE_SHOT);
283 }
284 TimerMgr::instance()->setup(timer_name);
285 } else {
286 // Cancel the timer.
287 if (TimerMgr::instance()->isTimerRegistered(timer_name)) {
288 TimerMgr::instance()->unregisterTimer(timer_name);
289 }
290 // Has errors but retries exceed
291 if (has_errors) {
292 if (open_sockets_failed_callback_) {
293 open_sockets_failed_callback_(reconnect_ctl);
294 }
295 }
296 }
297
298 return (sopen);
299}
300
301void
302CfgIface::reset() {
303 wildcard_used_ = false;
304 iface_set_.clear();
305 address_map_.clear();
306 socket_type_ = SOCKET_RAW;
307}
308
309void
310CfgIface::setState(const uint16_t family, const bool inactive,
311 const bool loopback_inactive) const {
312 for (auto const& iface : IfaceMgr::instance().getIfaces()) {
313 bool iface_inactive = iface->flag_loopback_ ? loopback_inactive : inactive;
314 if (family == AF_INET) {
315 iface->inactive4_ = iface_inactive;
316 } else {
317 iface->inactive6_ = iface_inactive;
318 }
319
320 // Activate/deactivate all addresses.
321 setIfaceAddrsState(family, !inactive, *iface);
322 }
323}
324
325void
326CfgIface::setIfaceAddrsState(const uint16_t family, const bool active,
327 Iface& iface) const {
328 // Activate/deactivate all addresses.
329 for (auto const& addr : iface.getAddresses()) {
330 if (addr.get().getFamily() == family) {
331 iface.setActive(addr.get(), active);
332 }
333 }
334}
335
336void
337CfgIface::socketOpenErrorHandler(const std::string& errmsg) {
338 LOG_WARN(dhcpsrv_logger, DHCPSRV_OPEN_SOCKET_FAIL).arg(errmsg);
339}
340
341std::string
342CfgIface::socketTypeToText() const {
343 switch (socket_type_) {
344 case SOCKET_RAW:
345 return ("raw");
346
347 case SOCKET_UDP:
348 return ("udp");
349
350 default:
351 ;
352 }
353
354 isc_throw(Unexpected, "unsupported socket type " << socket_type_);
355}
356
357 CfgIface::SocketType
358CfgIface::textToSocketType(const std::string& socket_type_name) const {
359 if (socket_type_name == "udp") {
360 return (SOCKET_UDP);
361
362 } else if (socket_type_name == "raw") {
363 return (SOCKET_RAW);
364
365 } else {
366 isc_throw(InvalidSocketType, "unsupported socket type '"
367 << socket_type_name << "'");
368 }
369}
370
371 CfgIface::OutboundIface
372CfgIface::getOutboundIface() const {
373 return (outbound_iface_);
374}
375
376std::string
377CfgIface::outboundTypeToText() const {
378 switch (outbound_iface_) {
379 case SAME_AS_INBOUND:
380 return ("same-as-inbound");
381 case USE_ROUTING:
382 return ("use-routing");
383 default:
384 isc_throw(Unexpected, "unsupported outbound-type " << socket_type_);
385 }
386
387}
388
389 CfgIface::OutboundIface
390CfgIface::textToOutboundIface(const std::string& txt) {
391 if (txt == "same-as-inbound") {
392 return (SAME_AS_INBOUND);
393
394 } else if (txt == "use-routing") {
395 return (USE_ROUTING);
396
397 } else {
398 isc_throw(BadValue, "unsupported outbound interface type '"
399 << txt << "'");
400 }
401}
402
403void
404CfgIface::setOutboundIface(const OutboundIface& outbound_iface) {
405 outbound_iface_ = outbound_iface;
406}
407
408void
409CfgIface::use(const uint16_t family, const std::string& iface_name) {
410 // The interface name specified may have two formats:
411 // - "interface-name", e.g. eth0
412 // - "interface-name/address", e.g. eth0/10.0.0.1 or eth/2001:db8:1::1
413 // The latter format is used to open unicast socket on the specified
414 // interface. Here we are detecting which format was used and we strip
415 // all extraneous spaces.
416 size_t pos = iface_name.find("/");
417 std::string name;
418 std::string addr_str;
419 // There is no unicast address so the whole string is an interface name.
420 if (pos == std::string::npos) {
421 name = util::str::trim(iface_name);
422 if (name.empty()) {
423 isc_throw(InvalidIfaceName,
424 "empty interface name used in configuration");
425
426 } else if (name != ALL_IFACES_KEYWORD) {
427 if (IfaceMgr::instance().getIface(name) == NULL) {
428 isc_throw(NoSuchIface, "interface '" << name
429 << "' doesn't exist in the system");
430 }
431
432 } else if (wildcard_used_) {
433 isc_throw(DuplicateIfaceName, "the wildcard interface '"
434 << ALL_IFACES_KEYWORD << "' can only be specified once");
435
436 } else {
437 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
438 DHCPSRV_CFGMGR_ALL_IFACES_ACTIVE);
439 wildcard_used_ = true;
440
441 }
442
443 } else {
444 // The interface name includes the address on which the socket should
445 // be opened, and we need to split interface name and the address to
446 // two variables.
447 name = util::str::trim(iface_name.substr(0, pos));
448 addr_str = util::str::trim(iface_name.substr(pos + 1));
449
450 // Interface name must not be empty.
451 if (name.empty()) {
452 isc_throw(InvalidIfaceName,
453 "empty interface name specified in the"
454 " interface configuration");
455
456 }
457 // An address following the interface name must not be empty.
458 if (addr_str.empty()) {
459 isc_throw(InvalidIfaceName,
460 "empty address specified in the interface"
461 << " configuration");
462
463 }
464
465 // Interface name must not be the wildcard name.
466 if (name == ALL_IFACES_KEYWORD) {
467 isc_throw(InvalidIfaceName,
468 "wildcard interface name '" << ALL_IFACES_KEYWORD
469 << "' must not be used in conjunction with an"
470 " address");
471
472 }
473
474 // Interface must exist.
475 IfacePtr iface = IfaceMgr::instance().getIface(name);
476 if (!iface) {
477 isc_throw(NoSuchIface, "interface '" << name
478 << "' doesn't exist in the system");
479
480 }
481
482 // Convert address string. This may throw an exception if the address
483 // is invalid.
484 IOAddress addr(addr_str);
485
486 // Validate V6 address.
487 if (family == AF_INET6) {
488 // Check that the address is a valid unicast address.
489 if (!addr.isV6() || addr.isV6Multicast()) {
490 isc_throw(InvalidIfaceName, "address '" << addr << "' is not"
491 " a valid IPv6 unicast address");
492 }
493
494 // There are valid cases where link local address can be specified to
495 // receive unicast traffic, e.g. sent by relay agent.
496 if (addr.isV6LinkLocal()) {
497 LOG_WARN(dhcpsrv_logger, DHCPSRV_CFGMGR_UNICAST_LINK_LOCAL)
498 .arg(addr.toText()).arg(name);
499 }
500
501 } else {
502 if (!addr.isV4()) {
503 isc_throw(InvalidIfaceName, "address '" << addr << "' is not"
504 " a valid IPv4 address");
505 }
506 }
507
508 // Interface must have this address assigned.
509 if (!iface->hasAddress(addr)) {
510 isc_throw(NoSuchAddress,
511 "interface '" << name << "' doesn't have address '"
512 << addr << "' assigned");
513 }
514
515 // For the IPv4, if the interface name was specified (instead of the interface-
516 // address tuple) all addresses are already activated. Adding an explicit address
517 // for the interface should result in error.
518 if ((family == AF_INET) && (iface_set_.find(iface->getName()) != iface_set_.end())) {
519 isc_throw(DuplicateIfaceName, "interface '" << iface->getName()
520 << "' has already been selected");
521 }
522
523 // Check if the address hasn't been selected already.
524 std::pair<const std::string, IOAddress> iface_address_tuple(name, addr);
525 if (std::find(address_map_.begin(), address_map_.end(),
526 iface_address_tuple) != address_map_.end()) {
527 isc_throw(DuplicateAddress, "must not select address '"
528 << addr << "' for interface '" << name << "' "
529 "because this address is already selected");
530 }
531
532 if (family == AF_INET6) {
533 LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_USE_UNICAST)
534 .arg(addr.toText()).arg(name);
535
536 } else {
537 LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_USE_ADDRESS)
538 .arg(addr.toText()).arg(name);
539 }
540 address_map_.insert(std::pair<std::string, IOAddress>(name, addr));
541 }
542
543 // If interface name was explicitly specified without an address, we will
544 // insert the interface name to the set of enabled interfaces.
545 if ((name != ALL_IFACES_KEYWORD) && addr_str.empty()) {
546 // An interface has been selected or an IPv4 address on this interface
547 // has been selected it is not allowed to select the whole interface.
548 if ((iface_set_.find(name) != iface_set_.end()) ||
549 ((family == AF_INET) && address_map_.count(name) > 0)) {
550 isc_throw(DuplicateIfaceName, "interface '" << name
551 << "' has already been specified");
552 }
553
554 LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_ADD_IFACE).arg(name);
555 iface_set_.insert(name);
556 }
557}
558
559void
560CfgIface::useSocketType(const uint16_t family,
561 const SocketType& socket_type) {
562 if (family != AF_INET) {
563 isc_throw(InvalidSocketType, "socket type must not be specified for"
564 " the DHCPv6 server");
565 }
566 socket_type_ = socket_type;
567 LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT)
568 .arg(socketTypeToText());
569}
570
571void
572 CfgIface::useSocketType(const uint16_t family,
573 const std::string& socket_type_name) {
574 useSocketType(family, textToSocketType(socket_type_name));
575}
576
577 ElementPtr
578CfgIface::toElement() const {
579 ElementPtr result = Element::createMap();
580
581 // Set user context
582 contextToElement(result);
583
584 // Set interfaces
585 ElementPtr ifaces = Element::createList();
586 if (wildcard_used_) {
587 ifaces->add(Element::create(std::string(ALL_IFACES_KEYWORD)));
588 }
589 for (auto const& iface : iface_set_) {
590 ifaces->add(Element::create(iface));
591 }
592 for (auto const& address : address_map_) {
593 std::string spec = address.first + "/" + address.second.toText();
594 ifaces->add(Element::create(spec));
595 }
596 result->set("interfaces", ifaces);
597
598 // Set dhcp-socket-type (no default because it is DHCPv4 specific)
599 // @todo emit raw if and only if DHCPv4
600 if (socket_type_ != SOCKET_RAW) {
601 result->set("dhcp-socket-type", Element::create(std::string("udp")));
602 }
603
604 if (outbound_iface_ != SAME_AS_INBOUND) {
605 result->set("outbound-interface", Element::create(outboundTypeToText()));
606 }
607
608 // Set re-detect
609 result->set("re-detect", Element::create(re_detect_));
610
611 // Set server socket binding
612 if (service_socket_require_all_) {
613 result->set("service-sockets-require-all", Element::create(service_socket_require_all_));
614 }
615
616 if (service_sockets_max_retries_ != 0) {
617 result->set("service-sockets-max-retries", Element::create(static_cast<int>(service_sockets_max_retries_)));
618 // If the max retries parameter is zero, the wait time is not used.
619 result->set("service-sockets-retry-wait-time", Element::create(static_cast<int>(service_sockets_retry_wait_time_)));
620 }
621
622 return (result);
623}
624
625void
626CfgIface::update(CfgIface& other) {
627 iface_set_ = other.iface_set_;
628 address_map_ = other.address_map_;
629 wildcard_used_ = other.wildcard_used_;
630}
631
632} // end of isc::dhcp namespace
633} // end of isc namespace
cfg_iface.h
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic).
Definition io_address.h:53
isc::asiolink::IOAddress::toText
std::string toText() const
Convert the address to a string.
Definition io_address.cc:60
isc::asiolink::IOAddress::isV6
bool isV6() const
Convenience function to check for an IPv6 address.
Definition io_address.h:144
isc::asiolink::IOAddress::isV4
bool isV4() const
Convenience function to check for an IPv4 address.
Definition io_address.h:122
isc::asiolink::IOAddress::isV6Multicast
bool isV6Multicast() const
checks whether and address is IPv6 and is multicast
Definition io_address.cc:113
isc::asiolink::IOAddress::isV6LinkLocal
bool isV6LinkLocal() const
checks whether and address is IPv6 and is link-local
Definition io_address.cc:105
isc::asiolink::IntervalTimer::ONE_SHOT
@ ONE_SHOT
Definition interval_timer.h:72
isc::data::Element::create
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:299
isc::data::Element::createMap
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:354
isc::data::Element::createList
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:349
isc::dhcp::CfgIface::ALL_IFACES_KEYWORD
static const char * ALL_IFACES_KEYWORD
Keyword used to enable all interfaces.
Definition cfg_iface.h:155
isc::dhcp::CfgIface::closeSockets
void closeSockets() const
Convenience function which closes all open sockets.
Definition cfg_iface.cc:38
isc::dhcp::CfgIface::socketTypeToText
std::string socketTypeToText() const
Returns the socket type in the textual format.
Definition cfg_iface.cc:342
isc::dhcp::CfgIface::update
void update(CfgIface &other)
Update runtime mutable members.
Definition cfg_iface.cc:626
isc::dhcp::CfgIface::reset
void reset()
Puts the interface configuration into default state.
Definition cfg_iface.cc:302
isc::dhcp::CfgIface::getServiceSocketsRetryWaitTime
uint32_t getServiceSocketsRetryWaitTime() const
Indicates the socket service binding retry interval between attempts.
Definition cfg_iface.h:338
isc::dhcp::CfgIface::OutboundIface
OutboundIface
Indicates how outbound interface is selected for relayed traffic.
Definition cfg_iface.h:143
isc::dhcp::CfgIface::USE_ROUTING
@ USE_ROUTING
Server uses routing to determine the right interface to send response.
Definition cfg_iface.h:148
isc::dhcp::CfgIface::SAME_AS_INBOUND
@ SAME_AS_INBOUND
Server sends responses over the same interface on which queries are received.
Definition cfg_iface.h:146
isc::dhcp::CfgIface::getOutboundIface
OutboundIface getOutboundIface() const
Returns outbound interface selection mode.
Definition cfg_iface.cc:372
isc::dhcp::CfgIface::CfgIface
CfgIface()
Constructor.
Definition cfg_iface.cc:30
isc::dhcp::CfgIface::getServiceSocketsRequireAll
bool getServiceSocketsRequireAll() const
Indicates that Kea must successfully bind all socket services on init.
Definition cfg_iface.h:324
isc::dhcp::CfgIface::openSockets
void openSockets(const uint16_t family, const uint16_t port, const bool use_bcast=true)
Tries to open sockets on selected interfaces.
Definition cfg_iface.cc:61
isc::dhcp::CfgIface::textToOutboundIface
static OutboundIface textToOutboundIface(const std::string &txt)
Converts text to outbound interface selection mode.
Definition cfg_iface.cc:390
isc::dhcp::CfgIface::use
void use(const uint16_t family, const std::string &iface_name)
Select interface to be used to receive DHCP traffic.
Definition cfg_iface.cc:409
isc::dhcp::CfgIface::equals
bool equals(const CfgIface &other) const
Compares two CfgIface objects for equality.
Definition cfg_iface.cc:43
isc::dhcp::CfgIface::SocketType
SocketType
Socket type used by the DHCPv4 server.
Definition cfg_iface.h:135
isc::dhcp::CfgIface::SOCKET_UDP
@ SOCKET_UDP
Datagram socket, i.e. IP/UDP socket.
Definition cfg_iface.h:139
isc::dhcp::CfgIface::SOCKET_RAW
@ SOCKET_RAW
Raw socket, used for direct DHCPv4 traffic.
Definition cfg_iface.h:137
isc::dhcp::CfgIface::toElement
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition cfg_iface.cc:578
isc::dhcp::CfgIface::outboundTypeToText
std::string outboundTypeToText() const
Returns outbound interface selection mode as string.
Definition cfg_iface.cc:377
isc::dhcp::CfgIface::setOutboundIface
void setOutboundIface(const OutboundIface &outbound_iface)
Sets outbound interface selection mode.
Definition cfg_iface.cc:404
isc::dhcp::CfgIface::textToSocketType
SocketType textToSocketType(const std::string &socket_type_name) const
Converts the socket type in the textual format to the type represented by the SocketType.
Definition cfg_iface.cc:358
isc::dhcp::CfgIface::open_sockets_failed_callback_
static OpenSocketsFailedCallback open_sockets_failed_callback_
Optional callback function to invoke if all retries of the opening sockets fail.
Definition cfg_iface.h:369
isc::dhcp::CfgIface::useSocketType
void useSocketType(const uint16_t family, const SocketType &socket_type)
Sets the specified socket type to be used by the server.
Definition cfg_iface.cc:560
isc::dhcp::CfgIface::OpenSocketsFailedCallback
std::function< void(util::ReconnectCtlPtr)> OpenSocketsFailedCallback
Represents a callback invoked if all retries of the opening sockets fail.
Definition cfg_iface.h:365
isc::dhcp::CfgIface::getServiceSocketsMaxRetries
uint32_t getServiceSocketsMaxRetries() const
Indicates the maximum number of service sockets bind attempts.
Definition cfg_iface.h:352
isc::dhcp::CfgIface::triggerOpenSocketsWithRetry
void triggerOpenSocketsWithRetry(const uint16_t family, const uint16_t port, const bool use_bcast=true)
Trigger the reopen sockets with retry mechanism.
Definition cfg_iface.cc:99
isc::dhcp::DuplicateAddress
Exception thrown when duplicated address specified.
Definition cfg_iface.h:45
isc::dhcp::DuplicateIfaceName
Exception thrown when duplicated interface names specified.
Definition cfg_iface.h:24
isc::dhcp::IfaceMgr::openSockets4
bool openSockets4(const uint16_t port=DHCP4_SERVER_PORT, const bool use_bcast=true, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv4 sockets on detected interfaces.
Definition iface_mgr.cc:555
isc::dhcp::IfaceMgr::getIface
IfacePtr getIface(const unsigned int ifindex)
Returns interface specified interface index.
Definition iface_mgr.cc:937
isc::dhcp::IfaceMgr::openSockets6
bool openSockets6(const uint16_t port=DHCP6_SERVER_PORT, IfaceMgrErrorMsgCallback error_handler=0, const bool skip_opened=false)
Opens IPv6 sockets on detected interfaces.
Definition iface_mgr.cc:685
isc::dhcp::IfaceMgr::detectIfaces
void detectIfaces(bool update_only=false)
Detects network interfaces.
isc::dhcp::IfaceMgr::clearUnicasts
void clearUnicasts()
Clears unicast addresses on all interfaces.
Definition iface_mgr.cc:1028
isc::dhcp::IfaceMgr::instance
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition iface_mgr.cc:52
isc::dhcp::IfaceMgr::initializeFDEventHandler
void initializeFDEventHandler()
Initialize the FD event handler;.
Definition iface_mgr.cc:213
isc::dhcp::IfaceMgr::closeSockets
void closeSockets()
Closes all open sockets.
Definition iface_mgr.cc:313
isc::dhcp::IfaceMgr::setMatchingPacketFilter
void setMatchingPacketFilter(const bool direct_response_desired=false)
Set Packet Filter object to handle send/receive packets.
isc::dhcp::IfaceMgr::setAllowLoopBack
void setAllowLoopBack(const bool allow_loopback)
Allows or disallows the loopback interface.
Definition iface_mgr.h:884
isc::dhcp::Iface
Represents a single network interface.
Definition iface_mgr.h:136
isc::dhcp::InvalidIfaceName
Exception thrown when specified interface name is invalid.
Definition cfg_iface.h:31
isc::dhcp::InvalidSocketType
Exception thrown when invalid socket type has been specified for the given family.
Definition cfg_iface.h:61
isc::dhcp::NoSuchAddress
Exception thrown when specified unicast address is not assigned to the interface specified.
Definition cfg_iface.h:53
isc::dhcp::NoSuchIface
Exception thrown when specified interface doesn't exist in a system.
Definition cfg_iface.h:38
isc::dhcp::TimerMgr::instance
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Definition timer_mgr.cc:446
dhcpsrv_log.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
iface_mgr.h
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
multi_threading_mgr.h
isc::asiolink
Definition addr_utilities.cc:170
isc::data
Definition base_stamped_element.cc:12
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
isc::dhcp::DHCPSRV_CFGMGR_ADD_IFACE
const isc::log::MessageID DHCPSRV_CFGMGR_ADD_IFACE
Definition dhcpsrv_messages.h:11
isc::dhcp::IfacePtr
boost::shared_ptr< Iface > IfacePtr
Type definition for the pointer to an Iface object.
Definition iface_mgr.h:555
isc::dhcp::DHCPSRV_CFGMGR_USE_ADDRESS
const isc::log::MessageID DHCPSRV_CFGMGR_USE_ADDRESS
Definition dhcpsrv_messages.h:48
isc::dhcp::DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE
const isc::log::MessageID DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE
Definition dhcpsrv_messages.h:157
isc::dhcp::DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT
const isc::log::MessageID DHCPSRV_CFGMGR_SOCKET_TYPE_SELECT
Definition dhcpsrv_messages.h:36
isc::dhcp::DHCPSRV_CFGMGR_ALL_IFACES_ACTIVE
const isc::log::MessageID DHCPSRV_CFGMGR_ALL_IFACES_ACTIVE
Definition dhcpsrv_messages.h:14
isc::dhcp::DHCPSRV_CFGMGR_UNICAST_LINK_LOCAL
const isc::log::MessageID DHCPSRV_CFGMGR_UNICAST_LINK_LOCAL
Definition dhcpsrv_messages.h:45
isc::dhcp::DHCPSRV_NO_SOCKETS_OPEN
const isc::log::MessageID DHCPSRV_NO_SOCKETS_OPEN
Definition dhcpsrv_messages.h:159
isc::dhcp::DHCPSRV_OPEN_SOCKET_FAIL
const isc::log::MessageID DHCPSRV_OPEN_SOCKET_FAIL
Definition dhcpsrv_messages.h:161
isc::dhcp::DHCPSRV_DBG_TRACE
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
isc::dhcp::DHCPSRV_CFGMGR_SOCKET_RAW_UNSUPPORTED
const isc::log::MessageID DHCPSRV_CFGMGR_SOCKET_RAW_UNSUPPORTED
Definition dhcpsrv_messages.h:34
isc::dhcp::DHCPSRV_CFGMGR_USE_UNICAST
const isc::log::MessageID DHCPSRV_CFGMGR_USE_UNICAST
Definition dhcpsrv_messages.h:50
isc::util::str::trim
string trim(const string &input)
Trim leading and trailing spaces.
Definition str.cc:32
isc::util
Definition time_utils.cc:43
isc::util::ReconnectCtlPtr
boost::shared_ptr< ReconnectCtl > ReconnectCtlPtr
Pointer to an instance of ReconnectCtl.
Definition reconnect_ctl.h:153
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
reconnect_ctl.h
str.h
isc::data::UserContext::contextToElement
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition user_context.cc:15
timer_mgr.h