Kea  1.5.0
d2_client_mgr.h
Go to the documentation of this file.
1 // Copyright (C) 2014-2018 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 #ifndef D2_CLIENT_MGR_H
8 #define D2_CLIENT_MGR_H
9 
14 #include <asiolink/io_address.h>
15 #include <dhcp_ddns/ncr_io.h>
16 #include <dhcpsrv/d2_client_cfg.h>
17 #include <exceptions/exceptions.h>
18 
19 #include <boost/algorithm/string.hpp>
20 #include <boost/shared_ptr.hpp>
21 #include <boost/noncopyable.hpp>
22 
23 #include <stdint.h>
24 #include <string>
25 #include <vector>
26 #include <sstream>
27 
28 namespace isc {
29 namespace dhcp {
30 
41 typedef
42 boost::function<void(const dhcp_ddns::NameChangeSender::Result result,
44 
79  boost::noncopyable {
80 public:
85  D2ClientMgr();
86 
88  ~D2ClientMgr();
89 
94  void setD2ClientConfig(D2ClientConfigPtr& new_config);
95 
99  bool ddnsEnabled();
100 
104  const D2ClientConfigPtr& getD2ClientConfig() const;
105 
153  void analyzeFqdn(const bool client_s, const bool client_n, bool& server_s,
154  bool& server_n) const;
155 
173  std::string generateFqdn(const asiolink::IOAddress& address,
174  const bool trailing_dot = true) const;
175 
190  std::string qualifyName(const std::string& partial_name,
191  const bool trailing_dot) const;
192 
204  template <class T>
205  void adjustFqdnFlags(const T& fqdn, T& fqdn_resp);
206 
224  template <class T>
225  void getUpdateDirections(const T& fqdn_resp, bool& forward, bool& reverse);
226 
253  template <class T>
254  void adjustDomainName(const T& fqdn, T& fqdn_resp);
255 
276  void startSender(D2ClientErrorHandler error_handler,
277  isc::asiolink::IOService& io_service);
278 
294  void startSender(D2ClientErrorHandler error_handler);
295 
300  bool amSending() const;
301 
310  void stopSender();
311 
324 
336  Result result,
338 
340  size_t getQueueSize() const;
341 
343  size_t getQueueMaxSize() const;
344 
356  const dhcp_ddns::NameChangeRequestPtr& peekAt(const size_t index) const;
357 
362  void clearQueue();
363 
370  void runReadyIO();
371 
381  void suspendUpdates();
382 
383 protected:
394  virtual void operator ()(const dhcp_ddns::NameChangeSender::Result result,
396 
407  int getSelectFd();
408 
416 
417 private:
419  D2ClientConfigPtr d2_client_config_;
420 
422  dhcp_ddns::NameChangeSenderPtr name_change_sender_;
423 
426  boost::shared_ptr<asiolink::IOService> private_io_service_;
427 
430  D2ClientErrorHandler client_error_handler_;
431 
433  int registered_select_fd_;
434 };
435 
436 template <class T>
437 void
438 D2ClientMgr::adjustFqdnFlags(const T& fqdn, T& fqdn_resp) {
439  bool server_s = false;
440  bool server_n = false;
441  analyzeFqdn(fqdn.getFlag(T::FLAG_S), fqdn.getFlag(T::FLAG_N),
442  server_s, server_n);
443 
444  // Reset the flags to zero to avoid triggering N and S both 1 check.
445  fqdn_resp.resetFlags();
446 
447  // Set S and N flags.
448  fqdn_resp.setFlag(T::FLAG_S, server_s);
449  fqdn_resp.setFlag(T::FLAG_N, server_n);
450 
451  // Set O flag true if server S overrides client S.
452  fqdn_resp.setFlag(T::FLAG_O, (fqdn.getFlag(T::FLAG_S) != server_s));
453 }
454 
455 template <class T>
456 void
458  bool& forward, bool& reverse) {
459  forward = fqdn_resp.getFlag(T::FLAG_S);
460  reverse = !(fqdn_resp.getFlag(T::FLAG_N));
461 }
462 
463 template <class T>
464 void
465 D2ClientMgr::adjustDomainName(const T& fqdn, T& fqdn_resp) {
466  // If we're configured to replace it or the supplied name is blank
467  // set the response name to blank.
468  if ((d2_client_config_->getReplaceClientNameMode() == D2ClientConfig::RCM_ALWAYS ||
469  d2_client_config_->getReplaceClientNameMode() == D2ClientConfig::RCM_WHEN_PRESENT) ||
470  fqdn.getDomainName().empty()) {
471  fqdn_resp.setDomainName("", T::PARTIAL);
472  } else {
473  // Sanitize the name the client sent us, if we're configured to do so.
474  std::string client_name = fqdn.getDomainName();
475 
476  if (d2_client_config_->getHostnameSanitizer()) {
477  // We need the raw text form, so we can replace escaped chars
478  dns::Name tmp(client_name);
479  std::string raw_name = tmp.toRawText();
480 
481  // We do not know if the sanitizer's regexp preserves dots, so
482  // we'll scrub it label by label. Yeah, lucky us.
483  // Using boost::split is simpler than using dns::Name::split() as
484  // that returns Names which have trailing dots etc.
485  std::vector<std::string> labels;
486  boost::algorithm::split(labels, raw_name, boost::is_any_of("."));
487  std::stringstream ss;
488  for (auto label = labels.begin(); label != labels.end(); ++label ) {
489  if (label != labels.begin()) {
490  ss << ".";
491  }
492 
493  ss << d2_client_config_->getHostnameSanitizer()->scrub(*label);
494  }
495 
496  client_name = ss.str();
497  }
498 
499  // If the supplied name is partial, qualify it by adding the suffix.
500  if (fqdn.getDomainNameType() == T::PARTIAL) {
501  fqdn_resp.setDomainName(qualifyName(client_name,true), T::FULL);
502  }
503  else {
504  fqdn_resp.setDomainName(client_name, T::FULL);
505  }
506  }
507 }
508 
510 typedef boost::shared_ptr<D2ClientMgr> D2ClientMgrPtr;
511 
512 
513 } // namespace isc
514 } // namespace dhcp
515 
516 #endif
isc::dhcp::D2ClientMgr::qualifyName
std::string qualifyName(const std::string &partial_name, const bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
Definition: d2_client_mgr.cc:181
isc::dhcp::D2ClientMgr::runReadyIO
void runReadyIO()
Processes sender IO events.
Definition: d2_client_mgr.cc:376
isc::dhcp::D2ClientMgr::startSender
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
Definition: d2_client_mgr.cc:233
isc::dhcp_ddns::NameChangeSender
Abstract interface for sending NameChangeRequests.
Definition: ncr_io.h:457
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:299
isc::dhcp::D2ClientMgr::D2ClientMgr
D2ClientMgr()
Constructor.
Definition: d2_client_mgr.cc:23
isc::dhcp::D2ClientMgr::~D2ClientMgr
~D2ClientMgr()
Destructor.
Definition: d2_client_mgr.cc:29
isc::dhcp_ddns::NameChangeSender::Result
Result
Defines the outcome of an asynchronous NCR send.
Definition: ncr_io.h:467
io_address.h
isc::dhcp::D2ClientMgr::generateFqdn
std::string generateFqdn(const asiolink::IOAddress &address, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
Definition: d2_client_mgr.cc:168
isc::dhcp::D2ClientErrorHandler
boost::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:43
isc::dhcp::D2ClientMgr::getQueueMaxSize
size_t getQueueMaxSize() const
Returns the maximum number of NCRs allowed in the queue.
Definition: d2_client_mgr.cc:326
d2_client_cfg.h
isc::dhcp_ddns::NameChangeRequestPtr
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition: ncr_msg.h:212
isc::dhcp::D2ClientMgr::amSending
bool amSending() const
Returns true if the sender is in send mode, false otherwise.
Definition: d2_client_mgr.cc:263
isc::dhcp::D2ClientConfig::RCM_WHEN_PRESENT
@ RCM_WHEN_PRESENT
Definition: d2_client_cfg.h:75
isc::dhcp_ddns::NameChangeSender::RequestSendHandler
Abstract class for defining application layer send callbacks.
Definition: ncr_io.h:479
isc::dhcp::D2ClientMgr::suspendUpdates
void suspendUpdates()
Suspends sending requests.
Definition: d2_client_mgr.cc:34
isc::dns::Name::toRawText
std::string toRawText(bool omit_final_dot=false) const
Convert the LabelSequence to a string without escape sequences.
Definition: name.cc:513
isc::dhcp::D2ClientMgr::ddnsEnabled
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
Definition: d2_client_mgr.cc:106
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::dhcp::D2ClientMgr::adjustFqdnFlags
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp)
Set server FQDN flags based on configuration and a given FQDN.
Definition: d2_client_mgr.h:438
isc::dhcp::D2ClientMgr::getSelectFd
int getSelectFd()
Fetches the sender's select-fd.
Definition: d2_client_mgr.cc:366
isc::dhcp::D2ClientMgr::adjustDomainName
void adjustDomainName(const T &fqdn, T &fqdn_resp)
Set server FQDN name based on configuration and a given FQDN.
Definition: d2_client_mgr.h:465
isc::dhcp::D2ClientMgr::sendRequest
void sendRequest(dhcp_ddns::NameChangeRequestPtr &ncr)
Send the given NameChangeRequests to kea-dhcp-ddns.
Definition: d2_client_mgr.cc:283
isc::dhcp::D2ClientConfig::RCM_ALWAYS
@ RCM_ALWAYS
Definition: d2_client_cfg.h:74
isc::dns::Name
The Name class encapsulates DNS names.
Definition: name.h:223
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:337
isc::dhcp::D2ClientConfigPtr
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
Definition: d2_client_cfg.h:323
isc::dhcp_ddns::NameChangeSenderPtr
boost::shared_ptr< NameChangeSender > NameChangeSenderPtr
Defines a smart pointer to an instance of a sender.
Definition: ncr_io.h:777
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
D2ClientMgr isolates Kea from the details of being a D2 client.
Definition: d2_client_mgr.h:79
isc::dhcp::D2ClientMgr::getUpdateDirections
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
Definition: d2_client_mgr.h:457
isc::dhcp::D2ClientMgr::getRegisteredSelectFd
int getRegisteredSelectFd()
Fetches the select-fd that is currently registered.
exceptions.h
isc::dhcp::D2ClientMgr::getQueueSize
size_t getQueueSize() const
Returns the number of NCRs queued for transmission.
Definition: d2_client_mgr.cc:317
ncr_io.h
This file defines abstract classes for exchanging NameChangeRequests.
isc::dhcp::D2ClientMgr::stopSender
void stopSender()
Disables sending NameChangeRequests to kea-dhcp-ddns.
Definition: d2_client_mgr.cc:268
isc::dhcp::D2ClientMgr::getD2ClientConfig
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
Definition: d2_client_mgr.cc:111
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:355
isc::dhcp::D2ClientMgrPtr
boost::shared_ptr< D2ClientMgr > D2ClientMgrPtr
Defines a pointer for D2ClientMgr instances.
Definition: d2_client_mgr.h:510
isc::dhcp::D2ClientMgr::analyzeFqdn
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.
Definition: d2_client_mgr.cc:116
isc::dhcp::D2ClientMgr::clearQueue
void clearQueue()
Removes all NCRs queued for transmission.
Definition: d2_client_mgr.cc:346