| Kea 3.0.2-git

d2_client_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2025 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/iface_mgr.h>
10#include <dhcp_ddns/ncr_udp.h>
11#include <dhcpsrv/d2_client_mgr.h>
12#include <dhcpsrv/dhcpsrv_log.h>
13
14#include <functional>
15#include <string>
16
17 using namespace std;
18
19 namespace isc {
20 namespace dhcp {
21
22 D2ClientMgr::D2ClientMgr() : d2_client_config_(new D2ClientConfig()),
23 name_change_sender_(), private_io_service_(),
24 registered_select_fd_(util::WatchSocket::SOCKET_NOT_VALID) {
25 // Default constructor initializes with a disabled configuration.
26}
27
28 D2ClientMgr::~D2ClientMgr() {
29 stop();
30 stopSender();
31}
32
33 void
34 D2ClientMgr::suspendUpdates() {
35 if (ddnsEnabled()) {
38 LOG_WARN(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_SUSPEND_UPDATES);
39 d2_client_config_->enableUpdates(false);
40 if (name_change_sender_) {
41 stopSender();
42 }
43 }
44}
45
46 void
47 D2ClientMgr::setD2ClientConfig(D2ClientConfigPtr& new_config) {
48 if (!new_config) {
49 isc_throw(D2ClientError,
50 "D2ClientMgr cannot set DHCP-DDNS configuration to NULL.");
51 }
52
53 // Don't do anything unless configuration values are actually different.
54 if (*d2_client_config_ != *new_config) {
55 // Make sure we stop sending first.
56 stopSender();
57 if (!new_config->getEnableUpdates()) {
58 // Updating has been turned off.
59 // Destroy current sender (any queued requests are tossed).
60 name_change_sender_.reset();
61 } else {
62 dhcp_ddns::NameChangeSenderPtr new_sender;
63 switch (new_config->getNcrProtocol()) {
64 case dhcp_ddns::NCR_UDP: {
65 // Instantiate a new sender.
66 new_sender.reset(new dhcp_ddns::NameChangeUDPSender(
67 new_config->getSenderIp(),
68 new_config->getSenderPort(),
69 new_config->getServerIp(),
70 new_config->getServerPort(),
71 new_config->getNcrFormat(),
72 shared_from_this(),
73 new_config->getMaxQueueSize()));
74 break;
75 }
76 default:
77 // In theory you can't get here.
78 isc_throw(D2ClientError, "Invalid sender Protocol: "
79 << new_config->getNcrProtocol());
80 break;
81 }
82
83 // Transfer queued requests from previous sender to the new one.
89 if (name_change_sender_) {
90 new_sender->assumeQueue(*name_change_sender_);
91 }
92
93 // Replace the old sender with the new one.
94 name_change_sender_ = new_sender;
95 }
96 }
97
98 // Update the configuration.
99 d2_client_config_ = new_config;
100 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_CFG_DHCP_DDNS)
101 .arg(!ddnsEnabled() ? "DHCP-DDNS updates disabled" :
102 "DHCP_DDNS updates enabled");
103}
104
105 bool
106 D2ClientMgr::ddnsEnabled() {
107 return (d2_client_config_->getEnableUpdates());
108}
109
110 const D2ClientConfigPtr&
111 D2ClientMgr::getD2ClientConfig() const {
112 return (d2_client_config_);
113}
114
115 void
116 D2ClientMgr::analyzeFqdn(const bool client_s, const bool client_n,
117 bool& server_s, bool& server_n,
118 const DdnsParams& ddns_params) const {
119 // Per RFC 4702 & 4704, the client N and S flags allow the client to
120 // request one of three options:
121 //
122 // N flag S flag Option
123 // ------------------------------------------------------------------
124 // 0 0 client wants to do forward updates (section 3.2)
125 // 0 1 client wants server to do forward updates (section 3.3)
126 // 1 0 client wants no one to do updates (section 3.4)
127 // 1 1 invalid combination
128 // (Note section numbers cited are for 4702, for 4704 see 5.1, 5.2, and 5.3)
129 //
130 // Make a bit mask from the client's flags and use it to set the response
131 // flags accordingly.
132 const uint8_t mask = ((client_n ? 2 : 0) + (client_s ? 1 : 0));
133
134 switch (mask) {
135 case 0:
136 if (!ddns_params.getEnableUpdates()) {
137 server_s = false;
138 server_n = true;
139 } else {
140 // If updates are enabled and we are overriding client delegation
141 // then S flag should be true. N-flag should be false.
142 server_s = ddns_params.getOverrideClientUpdate();
143 server_n = false;
144 }
145 break;
146
147 case 1:
148 server_s = ddns_params.getEnableUpdates();
149 server_n = !server_s;
150 break;
151
152 case 2:
153 // If updates are enabled and we are overriding "no updates" then
154 // S flag should be true.
155 server_s = (ddns_params.getEnableUpdates() &&
156 ddns_params.getOverrideNoUpdate());
157 server_n = !server_s;
158 break;
159
160 default:
161 // RFCs declare this an invalid combination.
162 isc_throw(isc::BadValue,
163 "Invalid client FQDN - N and S cannot both be 1");
164 break;
165 }
166}
167
168std::string
169 D2ClientMgr::generateFqdn(const asiolink::IOAddress& address,
170 const DdnsParams& ddns_params,
171 const bool trailing_dot) const {
172 std::string hostname = address.toText();
173 std::replace(hostname.begin(), hostname.end(),
174 (address.isV4() ? '.' : ':'), '-');
175
176 if (*(hostname.rbegin()) == '-') {
177 hostname.append("0");
178 }
179
180 std::ostringstream gen_name;
181 gen_name << ddns_params.getGeneratedPrefix() << "-" << hostname;
182 return (qualifyName(gen_name.str(), ddns_params, trailing_dot));
183}
184
185std::string
186 D2ClientMgr::qualifyName(const std::string& partial_name,
187 const DdnsParams& ddns_params,
188 const bool trailing_dot) const {
189 if (partial_name.empty()) {
190 isc_throw(BadValue, "D2ClientMgr::qualifyName"
191 " - partial_name cannot be an empty string");
192 }
193
194 std::ostringstream gen_name;
195 gen_name << partial_name;
196 std::string suffix = ddns_params.getQualifyingSuffix();
197 if (!suffix.empty() && (partial_name.back() != '.')) {
198 bool suffix_present = true;
199 std::string str = gen_name.str();
200 auto suffix_rit = suffix.rbegin();
201 if (*suffix_rit == '.') {
202 ++suffix_rit;
203 }
204
205 auto gen_rit = str.rbegin();
206 while (suffix_rit != suffix.rend()) {
207 if ((gen_rit == str.rend()) || (*suffix_rit != *gen_rit)) {
208 // They don't match.
209 suffix_present = false;
210 break;
211 }
212
213 ++suffix_rit;
214 ++gen_rit;
215 }
216
217 // Catch the case where name has suffix embedded.
218 // input: foo.barexample.com suffix: example.com
219 if ((suffix_present) && (suffix_rit == suffix.rend())) {
220 if ((gen_rit != str.rend()) && (*gen_rit != '.')) {
221 suffix_present = false;
222 }
223 }
224
225 if (!suffix_present) {
226 size_t len = str.length();
227 if ((len > 0) && (str[len - 1] != '.')) {
228 gen_name << ".";
229 }
230
231 gen_name << suffix;
232 }
233 }
234
235 std::string str = gen_name.str();
236 size_t len = str.length();
237
238 if (trailing_dot) {
239 // If trailing dot should be added but there is no trailing dot,
240 // append it.
241 if ((len > 0) && (str[len - 1] != '.')) {
242 gen_name << ".";
243 }
244
245 } else {
246 // If the trailing dot should not be appended but it is present,
247 // remove it.
248 if ((len > 0) && (str[len - 1] == '.')) {
249 gen_name.str(str.substr(0, len-1));
250 }
251
252 }
253
254 return (gen_name.str());
255}
256
257 void
258 D2ClientMgr::startSender(D2ClientErrorHandler error_handler) {
259 if (amSending()) {
260 return;
261 }
262
263 // Create a our own service instance when we are not being multiplexed
264 // into an external service..
265 private_io_service_.reset(new asiolink::IOService());
266 startSender(error_handler, private_io_service_);
267 LOG_INFO(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_SENDER_STARTED)
268 .arg(d2_client_config_->toText());
269}
270
271 void
272 D2ClientMgr::startSender(D2ClientErrorHandler error_handler,
273 const isc::asiolink::IOServicePtr& io_service) {
274 if (amSending()) {
275 return;
276 }
277
278 if (!name_change_sender_) {
279 isc_throw(D2ClientError, "D2ClientMgr::startSender sender is null");
280 }
281
282 if (!error_handler) {
283 isc_throw(D2ClientError, "D2ClientMgr::startSender handler is null");
284 }
285
286 // Set the error handler.
287 client_error_handler_ = error_handler;
288
289 // Start the sender on the given service.
290 name_change_sender_->startSending(io_service);
291
292 // Register sender's select-fd with IfaceMgr.
293 // We need to remember the fd that is registered so we can unregister later.
294 // IO error handling in the sender may alter its select-fd.
295 registered_select_fd_ = name_change_sender_->getSelectFd();
296 IfaceMgr::instance().addExternalSocket(registered_select_fd_,
297 std::bind(&D2ClientMgr::runReadyIO,
298 this));
299}
300
301 bool
302 D2ClientMgr::amSending() const {
303 return (name_change_sender_ && name_change_sender_->amSending());
304}
305
306 void
307 D2ClientMgr::stopSender() {
309 if (registered_select_fd_ != util::WatchSocket::SOCKET_NOT_VALID) {
310 IfaceMgr::instance().deleteExternalSocket(registered_select_fd_);
311 registered_select_fd_ = util::WatchSocket::SOCKET_NOT_VALID;
312 }
313
314 // If its not null, call stop.
315 if (amSending()) {
316 name_change_sender_->stopSending();
317 LOG_INFO(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_SENDER_STOPPED);
318 }
319
320 if (private_io_service_) {
321 private_io_service_->stopAndPoll();
322 }
323}
324
325 void
326 D2ClientMgr::sendRequest(dhcp_ddns::NameChangeRequestPtr& ncr) {
327 if (!amSending()) {
328 // This is programmatic error so bust them for it.
329 isc_throw(D2ClientError, "D2ClientMgr::sendRequest not in send mode");
330 }
331
332 try {
333 name_change_sender_->sendRequest(ncr);
334 } catch (const std::exception& ex) {
335 LOG_ERROR(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_NCR_REJECTED)
336 .arg(ex.what()).arg((ncr ? ncr->toText() : " NULL "));
337 invokeClientErrorHandler(dhcp_ddns::NameChangeSender::ERROR, ncr);
338 }
339}
340
341 void
342 D2ClientMgr::invokeClientErrorHandler(const dhcp_ddns::NameChangeSender::
343 Result result,
344 dhcp_ddns::NameChangeRequestPtr& ncr) {
345 // Handler is mandatory to enter send mode but test it just to be safe.
346 if (!client_error_handler_) {
347 LOG_ERROR(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_HANDLER_NULL);
348 } else {
349 // Handler is not supposed to throw, but catch just in case.
350 try {
351 (client_error_handler_)(result, ncr);
352 } catch (const std::exception& ex) {
353 LOG_ERROR(dhcpsrv_logger, DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION)
354 .arg(ex.what());
355 }
356 }
357}
358
359 size_t
360 D2ClientMgr::getQueueSize() const {
361 if (!name_change_sender_) {
362 isc_throw(D2ClientError, "D2ClientMgr::getQueueSize sender is null");
363 }
364
365 return (name_change_sender_->getQueueSize());
366}
367
368 size_t
369 D2ClientMgr::getQueueMaxSize() const {
370 if (!name_change_sender_) {
371 isc_throw(D2ClientError, "D2ClientMgr::getQueueMaxSize sender is null");
372 }
373
374 return (name_change_sender_->getQueueMaxSize());
375}
376
377 const dhcp_ddns::NameChangeRequestPtr&
378 D2ClientMgr::peekAt(const size_t index) const {
379 if (!name_change_sender_) {
380 isc_throw(D2ClientError, "D2ClientMgr::peekAt sender is null");
381 }
382
383 return (name_change_sender_->peekAt(index));
384}
385
386 void
387 D2ClientMgr::clearQueue() {
388 if (!name_change_sender_) {
389 isc_throw(D2ClientError, "D2ClientMgr::clearQueue sender is null");
390 }
391
392 name_change_sender_->clearSendQueue();
393}
394
395 void
396 D2ClientMgr::operator()(const dhcp_ddns::NameChangeSender::Result result,
397 dhcp_ddns::NameChangeRequestPtr& ncr) {
398 if (result == dhcp_ddns::NameChangeSender::SUCCESS) {
399 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
400 DHCPSRV_DHCP_DDNS_NCR_SENT).arg(ncr->toText());
401 } else {
402 invokeClientErrorHandler(result, ncr);
403 }
404}
405
406 void
407 D2ClientMgr::stop() {
408 name_change_sender_.reset();
409}
410
411 int
412 D2ClientMgr::getSelectFd() {
413 if (!amSending()) {
414 isc_throw (D2ClientError, "D2ClientMgr::getSelectFd "
415 " not in send mode");
416 }
417
418 return (name_change_sender_->getSelectFd());
419}
420
421 void
422 D2ClientMgr::runReadyIO() {
423 if (!name_change_sender_) {
424 // This should never happen.
425 isc_throw(D2ClientError, "D2ClientMgr::runReadyIO"
426 " name_change_sender is null");
427 }
428
429 name_change_sender_->runReadyIO();
430}
431
432} // namespace dhcp
433} // namespace isc
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::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic).
Definition io_address.h:45
isc::asiolink::IOAddress::toText
std::string toText() const
Convert the address to a string.
Definition io_address.cc:61
isc::asiolink::IOAddress::isV4
bool isV4() const
Convenience function to check for an IPv4 address.
Definition io_address.h:114
isc::asiolink::IOService
The IOService class is a wrapper for the ASIO io_context class.
Definition io_service.h:32
isc::dhcp::D2ClientConfig
Acts as a storage vault for D2 client configuration.
Definition d2_client_cfg.h:57
isc::dhcp::D2ClientError
An exception that is thrown if an error occurs while configuring the D2 DHCP DDNS client.
Definition d2_client_cfg.h:34
isc::dhcp::D2ClientMgr::invokeClientErrorHandler
void invokeClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Calls the client's error handler.
Definition d2_client_mgr.cc:342
isc::dhcp::D2ClientMgr::generateFqdn
std::string generateFqdn(const asiolink::IOAddress &address, const DdnsParams &ddns_params, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
Definition d2_client_mgr.cc:169
isc::dhcp::D2ClientMgr::analyzeFqdn
void analyzeFqdn(const bool client_s, const bool client_n, bool &server_s, bool &server_n, const DdnsParams &ddns_params) const
Determines server flags based on configuration and client flags.
Definition d2_client_mgr.cc:116
isc::dhcp::D2ClientMgr::ddnsEnabled
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
Definition d2_client_mgr.cc:106
isc::dhcp::D2ClientMgr::getD2ClientConfig
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
Definition d2_client_mgr.cc:111
isc::dhcp::D2ClientMgr::stop
void stop()
Stop the sender.
Definition d2_client_mgr.cc:407
isc::dhcp::D2ClientMgr::suspendUpdates
void suspendUpdates()
Suspends sending requests.
Definition d2_client_mgr.cc:34
isc::dhcp::D2ClientMgr::sendRequest
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
Definition d2_client_mgr.cc:326
isc::dhcp::D2ClientMgr::getQueueSize
size_t getQueueSize() const
Returns the number of NCRs queued for transmission.
Definition d2_client_mgr.cc:360
isc::dhcp::D2ClientMgr::clearQueue
void clearQueue()
Removes all NCRs queued for transmission.
Definition d2_client_mgr.cc:387
isc::dhcp::D2ClientMgr::stopSender
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
Definition d2_client_mgr.cc:307
isc::dhcp::D2ClientMgr::setD2ClientConfig
void setD2ClientConfig(D2ClientConfigPtr &new_config)
Updates the DHCP-DDNS client configuration to the given value.
Definition d2_client_mgr.cc:47
isc::dhcp::D2ClientMgr::amSending
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
Definition d2_client_mgr.cc:302
isc::dhcp::D2ClientMgr::getSelectFd
int getSelectFd()
Fetches the sender's select-fd.
Definition d2_client_mgr.cc:412
isc::dhcp::D2ClientMgr::runReadyIO
void runReadyIO()
Processes sender IO events.
Definition d2_client_mgr.cc:422
isc::dhcp::D2ClientMgr::~D2ClientMgr
~D2ClientMgr()
Destructor.
Definition d2_client_mgr.cc:28
isc::dhcp::D2ClientMgr::D2ClientMgr
D2ClientMgr()
Constructor.
Definition d2_client_mgr.cc:22
isc::dhcp::D2ClientMgr::getQueueMaxSize
size_t getQueueMaxSize() const
Returns the maximum number of NCRs allowed in the queue.
Definition d2_client_mgr.cc:369
isc::dhcp::D2ClientMgr::operator()
virtual void operator()(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Function operator implementing the NCR sender callback.
Definition d2_client_mgr.cc:396
isc::dhcp::D2ClientMgr::peekAt
const dhcp_ddns::NameChangeRequestPtr & peekAt(const size_t index) const
Returns the nth NCR queued for transmission.
Definition d2_client_mgr.cc:378
isc::dhcp::D2ClientMgr::qualifyName
std::string qualifyName(const std::string &partial_name, const DdnsParams &ddns_params, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
Definition d2_client_mgr.cc:186
isc::dhcp::D2ClientMgr::startSender
void startSender(D2ClientErrorHandler error_handler, const isc::asiolink::IOServicePtr &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
Definition d2_client_mgr.cc:272
isc::dhcp::DdnsParams
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
Definition ddns_params.h:23
isc::dhcp::DdnsParams::getGeneratedPrefix
std::string getGeneratedPrefix() const
Returns the Prefix Kea should use when generating domain-names.
Definition srv_config.cc:1030
isc::dhcp::DdnsParams::getQualifyingSuffix
std::string getQualifyingSuffix() const
Returns the suffix Kea should use when to qualify partial domain-names.
Definition srv_config.cc:1046
isc::dhcp::DdnsParams::getOverrideNoUpdate
bool getOverrideNoUpdate() const
Returns whether or not Kea should perform updates, even if client requested no updates.
Definition srv_config.cc:983
isc::dhcp::DdnsParams::getEnableUpdates
bool getEnableUpdates() const
Returns whether or not DHCP DDNS updating is enabled.
Definition srv_config.cc:967
isc::dhcp::DdnsParams::getOverrideClientUpdate
bool getOverrideClientUpdate() const
Returns whether or not Kea should perform updates, even if client requested delegation.
Definition srv_config.cc:998
isc::dhcp::IfaceMgr::deleteExternalSocket
void deleteExternalSocket(int socketfd)
Deletes external socket.
Definition iface_mgr.cc:352
isc::dhcp::IfaceMgr::instance
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition iface_mgr.cc:54
isc::dhcp::IfaceMgr::addExternalSocket
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
Definition iface_mgr.cc:329
isc::dhcp_ddns::NameChangeSender
Abstract interface for sending NameChangeRequests.
Definition ncr_io.h:468
isc::dhcp_ddns::NameChangeSender::Result
Result
Defines the outcome of an asynchronous NCR send.
Definition ncr_io.h:478
isc::dhcp_ddns::NameChangeSender::SUCCESS
@ SUCCESS
Definition ncr_io.h:479
isc::dhcp_ddns::NameChangeSender::ERROR
@ ERROR
Definition ncr_io.h:482
isc::dhcp_ddns::NameChangeUDPSender
Provides the ability to send NameChangeRequests via UDP socket.
Definition ncr_udp.h:442
isc::util::WatchSocket
Provides an IO "ready" semaphore for use with select() or poll() WatchSocket exposes a single open fi...
Definition watch_socket.h:47
isc::util::WatchSocket::SOCKET_NOT_VALID
static const int SOCKET_NOT_VALID
Value used to signify an invalid descriptor.
Definition watch_socket.h:50
d2_client_mgr.h
Defines the D2ClientMgr class.
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_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
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
isc::asiolink::IOServicePtr
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
Definition io_service.h:28
isc::dhcp_ddns::NCR_UDP
@ NCR_UDP
Definition ncr_io.h:70
isc::dhcp_ddns::NameChangeSenderPtr
boost::shared_ptr< NameChangeSender > NameChangeSenderPtr
Defines a smart pointer to an instance of a sender.
Definition ncr_io.h:857
isc::dhcp_ddns::NameChangeRequestPtr
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition ncr_msg.h:241
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_DHCP_DDNS_NCR_SENT
const isc::log::MessageID DHCPSRV_DHCP_DDNS_NCR_SENT
Definition dhcpsrv_messages.h:59
isc::dhcp::D2ClientConfigPtr
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
Definition d2_client_cfg.h:236
isc::dhcp::DHCPSRV_DHCP_DDNS_SENDER_STOPPED
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SENDER_STOPPED
Definition dhcpsrv_messages.h:61
isc::dhcp::DHCPSRV_DHCP_DDNS_SUSPEND_UPDATES
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SUSPEND_UPDATES
Definition dhcpsrv_messages.h:62
isc::dhcp::DHCPSRV_CFGMGR_CFG_DHCP_DDNS
const isc::log::MessageID DHCPSRV_CFGMGR_CFG_DHCP_DDNS
Definition dhcpsrv_messages.h:15
isc::dhcp::DHCPSRV_DHCP_DDNS_SENDER_STARTED
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SENDER_STARTED
Definition dhcpsrv_messages.h:60
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition dhcpsrv_log.h:38
isc::dhcp::DHCPSRV_DHCP_DDNS_NCR_REJECTED
const isc::log::MessageID DHCPSRV_DHCP_DDNS_NCR_REJECTED
Definition dhcpsrv_messages.h:58
isc::dhcp::D2ClientErrorHandler
std::function< void(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)> D2ClientErrorHandler
Defines the type for D2 IO error handler.
Definition d2_client_mgr.h:53
isc::dhcp::DHCPSRV_DBG_TRACE
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
isc::dhcp::DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION
const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION
Definition dhcpsrv_messages.h:56
isc::dhcp::DHCPSRV_DHCP_DDNS_HANDLER_NULL
const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL
Definition dhcpsrv_messages.h:57
isc::util::str
Definition str.cc:29
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
ncr_udp.h
This file provides UDP socket based implementation for sending and receiving NameChangeRequests.