14 #include <boost/bind.hpp> 24 name_change_sender_(), private_io_service_(),
25 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)
const {
131 const uint8_t mask = ((client_n ? 2 : 0) + (client_s ? 1 : 0));
135 if (!d2_client_config_->getEnableUpdates()) {
141 server_s = d2_client_config_->getOverrideClientUpdate();
147 server_s = d2_client_config_->getEnableUpdates();
148 server_n = !server_s;
154 server_s = (d2_client_config_->getEnableUpdates() &&
155 d2_client_config_->getOverrideNoUpdate());
156 server_n = !server_s;
162 "Invalid client FQDN - N and S cannot both be 1");
169 const bool trailing_dot)
const {
170 std::string hostname = address.
toText();
171 std::replace(hostname.begin(), hostname.end(),
172 (address.
isV4() ?
'.' :
':'),
'-');
174 std::ostringstream gen_name;
175 gen_name << d2_client_config_->getGeneratedPrefix() <<
"-" << hostname;
176 return (
qualifyName(gen_name.str(), trailing_dot));
182 const bool trailing_dot)
const {
183 std::ostringstream gen_name;
185 gen_name << partial_name;
186 if (!d2_client_config_->getQualifyingSuffix().empty()) {
187 std::string str = gen_name.str();
188 size_t len = str.length();
189 if ((len > 0) && (str[len - 1] !=
'.')) {
193 gen_name << d2_client_config_->getQualifyingSuffix();
196 std::string str = gen_name.str();
197 size_t len = str.length();
202 if ((len > 0) && (str[len - 1] !=
'.')) {
209 if ((len > 0) && (str[len - 1] ==
'.')) {
210 gen_name.str(str.substr(0,len-1));
215 return (gen_name.str());
229 .arg(d2_client_config_->toText());
239 if (!name_change_sender_) {
243 if (!error_handler) {
248 client_error_handler_ = error_handler;
251 name_change_sender_->startSending(io_service);
256 registered_select_fd_ = name_change_sender_->getSelectFd();
264 return (name_change_sender_ && name_change_sender_->amSending());
277 name_change_sender_->stopSending();
290 name_change_sender_->sendRequest(ncr);
291 }
catch (
const std::exception& ex) {
293 .arg(ex.what()).arg((ncr ? ncr->toText() :
" NULL "));
303 if (!client_error_handler_) {
308 (client_error_handler_)(result, ncr);
309 }
catch (
const std::exception& ex) {
318 if (!name_change_sender_) {
322 return(name_change_sender_->getQueueSize());
327 if (!name_change_sender_) {
331 return(name_change_sender_->getQueueMaxSize());
338 if (!name_change_sender_) {
342 return (name_change_sender_->peekAt(index));
347 if (!name_change_sender_) {
351 name_change_sender_->clearSendQueue();
359 DHCPSRV_DHCP_DDNS_NCR_SENT).arg(ncr->toText());
369 " not in send mode");
372 return (name_change_sender_->getSelectFd());
377 if (!name_change_sender_) {
380 " name_change_sender is null");
383 name_change_sender_->runReadyIO();
std::string generateFqdn(const asiolink::IOAddress &address, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
std::string qualifyName(const std::string &partial_name, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
~D2ClientMgr()
Destructor.
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
Result
Defines the outcome of an asynchronous NCR send.
virtual void operator()(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Function operator implementing the NCR sender callback.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
This file provides UDP socket based implementation for sending and receiving NameChangeRequests.
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
The IOService class is a wrapper for the ASIO io_service class.
#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...
An exception that is thrown if an error occurs while configuring the D2 DHCP DDNS client.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Acts as a storage vault for D2 client configuration.
void deleteExternalSocket(int socketfd)
Deletes external socket.
boost::function< void(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)> D2ClientErrorHandler
Defines the type for D2 IO error handler.
void analyzeFqdn(const bool client_s, const bool client_n, bool &server_s, bool &server_n) const
Determines server flags based on configuration and client flags.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
void clearQueue()
Removes all NCRs queued for transmission.
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
const dhcp_ddns::NameChangeRequestPtr & peekAt(const size_t index) const
Returns the nth NCR queued for transmission.
void invokeClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Calls the client's error handler.
Provides the ability to send NameChangeRequests via UDP socket.
boost::shared_ptr< NameChangeSender > NameChangeSenderPtr
Defines a smart pointer to an instance of a sender.
bool isV4() const
Convenience function to check for an IPv4 address.
Defines the logger used by the top-level component of kea-dhcp-ddns.
std::string toText() const
Convert the address to a string.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
void suspendUpdates()
Suspends sending requests.
Abstract interface for sending NameChangeRequests.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
int getSelectFd()
Fetches the sender's select-fd.
The IOAddress class represents an IP addresses (version agnostic)
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
Defines the D2ClientMgr class.
void runReadyIO()
Processes sender IO events.
size_t getQueueMaxSize() const
Returns the maximum number of NCRs allowed in the queue.
void setD2ClientConfig(D2ClientConfigPtr &new_config)
Updates the DHCP-DDNS client configuration to the given value.
static const int SOCKET_NOT_VALID
Value used to signify an invalid descriptor.
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
size_t getQueueSize() const
Returns the number of NCRs queued for transmission.