23 name_change_sender_(), private_io_service_(),
24 registered_select_fd_(util::WatchSocket::SOCKET_NOT_VALID) {
39 d2_client_config_->enableUpdates(
false);
40 if (name_change_sender_) {
50 "D2ClientMgr cannot set DHCP-DDNS configuration to NULL.");
54 if (*d2_client_config_ != *new_config) {
57 if (!new_config->getEnableUpdates()) {
60 name_change_sender_.reset();
63 switch (new_config->getNcrProtocol()) {
67 new_config->getSenderIp(),
68 new_config->getSenderPort(),
69 new_config->getServerIp(),
70 new_config->getServerPort(),
71 new_config->getNcrFormat(),
73 new_config->getMaxQueueSize()));
79 << new_config->getNcrProtocol());
89 if (name_change_sender_) {
90 new_sender->assumeQueue(*name_change_sender_);
94 name_change_sender_ = new_sender;
99 d2_client_config_ = new_config;
101 .arg(!
ddnsEnabled() ?
"DHCP-DDNS updates disabled" :
102 "DHCP_DDNS updates enabled");
107 return (d2_client_config_->getEnableUpdates());
112 return (d2_client_config_);
117 bool& server_s,
bool& server_n,
132 const uint8_t mask = ((client_n ? 2 : 0) + (client_s ? 1 : 0));
136 if (!ddns_params.getEnableUpdates()) {
142 server_s = ddns_params.getOverrideClientUpdate();
148 server_s = ddns_params.getEnableUpdates();
149 server_n = !server_s;
155 server_s = (ddns_params.getEnableUpdates() &&
156 ddns_params.getOverrideNoUpdate());
157 server_n = !server_s;
163 "Invalid client FQDN - N and S cannot both be 1");
171 const bool trailing_dot)
const {
172 std::string hostname = address.toText();
173 std::replace(hostname.begin(), hostname.end(),
174 (address.isV4() ?
'.' :
':'),
'-');
176 std::ostringstream gen_name;
177 gen_name << ddns_params.getGeneratedPrefix() <<
"-" << hostname;
178 return (
qualifyName(gen_name.str(), ddns_params, trailing_dot));
184 const bool trailing_dot)
const {
185 std::ostringstream gen_name;
187 gen_name << partial_name;
188 std::string suffix = ddns_params.getQualifyingSuffix();
189 bool suffix_present =
true;
190 if (!suffix.empty()) {
191 std::string str = gen_name.str();
192 auto suffix_rit = suffix.rbegin();
193 if (*suffix_rit ==
'.') {
197 auto gen_rit = str.rbegin();
198 if (*gen_rit ==
'.') {
202 while (suffix_rit != suffix.rend()) {
203 if ((gen_rit == str.rend()) || (*suffix_rit != *gen_rit)) {
205 suffix_present =
false;
215 if ((suffix_present) && (suffix_rit == suffix.rend())) {
216 if ((gen_rit != str.rend()) && (*gen_rit !=
'.')) {
217 suffix_present =
false;
221 if (!suffix_present) {
222 size_t len = str.length();
223 if ((len > 0) && (str[len - 1] !=
'.')) {
231 std::string str = gen_name.str();
232 size_t len = str.length();
237 if ((len > 0) && (str[len - 1] !=
'.')) {
244 if ((len > 0) && (str[len - 1] ==
'.')) {
245 gen_name.str(str.substr(0,len-1));
250 return (gen_name.str());
264 .arg(d2_client_config_->toText());
274 if (!name_change_sender_) {
278 if (!error_handler) {
283 client_error_handler_ = error_handler;
286 name_change_sender_->startSending(io_service);
291 registered_select_fd_ = name_change_sender_->getSelectFd();
299 return (name_change_sender_ && name_change_sender_->amSending());
312 name_change_sender_->stopSending();
316 if (private_io_service_) {
317 private_io_service_->stopAndPoll();
329 name_change_sender_->sendRequest(ncr);
330 }
catch (
const std::exception& ex) {
332 .arg(ex.what()).arg((ncr ? ncr->toText() :
" NULL "));
340 dhcp_ddns::NameChangeRequestPtr& ncr) {
342 if (!client_error_handler_) {
347 (client_error_handler_)(result, ncr);
348 }
catch (
const std::exception& ex) {
357 if (!name_change_sender_) {
361 return (name_change_sender_->getQueueSize());
366 if (!name_change_sender_) {
370 return (name_change_sender_->getQueueMaxSize());
375 if (!name_change_sender_) {
379 return (name_change_sender_->peekAt(index));
384 if (!name_change_sender_) {
388 name_change_sender_->clearSendQueue();
404 name_change_sender_.reset();
411 " not in send mode");
414 return (name_change_sender_->getSelectFd());
419 if (!name_change_sender_) {
422 " name_change_sender is null");
425 name_change_sender_->runReadyIO();
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
The IOAddress class represents an IP addresses (version agnostic)
The IOService class is a wrapper for the ASIO io_service class.
Acts as a storage vault for D2 client configuration.
An exception that is thrown if an error occurs while configuring the D2 DHCP DDNS client.
void invokeClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Calls the client's error handler.
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.
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.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
void stop()
Stop the sender.
void suspendUpdates()
Suspends sending requests.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
size_t getQueueSize() const
Returns the number of NCRs queued for transmission.
void clearQueue()
Removes all NCRs queued for transmission.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
void setD2ClientConfig(D2ClientConfigPtr &new_config)
Updates the DHCP-DDNS client configuration to the given value.
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
int getSelectFd()
Fetches the sender's select-fd.
void runReadyIO()
Processes sender IO events.
~D2ClientMgr()
Destructor.
D2ClientMgr()
Constructor.
size_t getQueueMaxSize() const
Returns the maximum number of NCRs allowed in the queue.
virtual void operator()(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Function operator implementing the NCR sender callback.
const dhcp_ddns::NameChangeRequestPtr & peekAt(const size_t index) const
Returns the nth NCR queued for transmission.
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.
void startSender(D2ClientErrorHandler error_handler, const isc::asiolink::IOServicePtr &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Abstract interface for sending NameChangeRequests.
Result
Defines the outcome of an asynchronous NCR send.
Provides the ability to send NameChangeRequests via UDP socket.
static const int SOCKET_NOT_VALID
Value used to signify an invalid descriptor.
Defines the D2ClientMgr class.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
boost::shared_ptr< NameChangeSender > NameChangeSenderPtr
Defines a smart pointer to an instance of a sender.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID DHCPSRV_DHCP_DDNS_NCR_SENT
std::function< void(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr) D2ClientErrorHandler)
Defines the type for D2 IO error handler.
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SENDER_STOPPED
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SUSPEND_UPDATES
const isc::log::MessageID DHCPSRV_CFGMGR_CFG_DHCP_DDNS
const isc::log::MessageID DHCPSRV_DHCP_DDNS_SENDER_STARTED
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
const isc::log::MessageID DHCPSRV_DHCP_DDNS_NCR_REJECTED
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION
const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL
Defines the logger used by the top-level component of kea-lfc.
This file provides UDP socket based implementation for sending and receiving NameChangeRequests.