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>
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
28namespace isc {
29namespace dhcp {
30
41typedef
42boost::function<void(const dhcp_ddns::NameChangeSender::Result result,
44
79 boost::noncopyable {
80public:
86
89
94 void setD2ClientConfig(D2ClientConfigPtr& new_config);
95
99 bool ddnsEnabled();
100
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
383protected:
394 virtual void operator ()(const dhcp_ddns::NameChangeSender::Result result,
396
407 int getSelectFd();
408
416
417private:
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
436template <class T>
437void
438D2ClientMgr::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
455template <class T>
456void
458 bool& forward, bool& reverse) {
459 forward = fqdn_resp.getFlag(T::FLAG_S);
460 reverse = !(fqdn_resp.getFlag(T::FLAG_N));
461}
462
463template <class T>
464void
465D2ClientMgr::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
510typedef boost::shared_ptr<D2ClientMgr> D2ClientMgrPtr;
511
512
513} // namespace isc
514} // namespace dhcp
515
516#endif
D2ClientMgr isolates Kea from the details of being a D2 client.
Definition: d2_client_mgr.h:79
void invokeClientErrorHandler(const dhcp_ddns::NameChangeSender::Result result, dhcp_ddns::NameChangeRequestPtr &ncr)
Calls the client's error handler.
bool ddnsEnabled()
Convenience method for checking if DHCP-DDNS is enabled.
const D2ClientConfigPtr & getD2ClientConfig() const
Fetches the DHCP-DDNS configuration pointer.
void startSender(D2ClientErrorHandler error_handler, isc::asiolink::IOService &io_service)
Enables sending NameChangeRequests to kea-dhcp-ddns.
void getUpdateDirections(const T &fqdn_resp, bool &forward, bool &reverse)
Get directional update flags based on server FQDN flags.
void suspendUpdates()
Suspends sending requests.
void adjustFqdnFlags(const T &fqdn, T &fqdn_resp)
Set server FQDN flags based on configuration and a given FQDN.
int getRegisteredSelectFd()
Fetches the select-fd that is currently registered.
void adjustDomainName(const T &fqdn, T &fqdn_resp)
Set server FQDN name based on configuration and a given FQDN.
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.
std::string generateFqdn(const asiolink::IOAddress &address, const bool trailing_dot=true) const
Builds a FQDN based on the configuration and given IP address.
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 bool trailing_dot) const
Adds a qualifying suffix to a given domain name.
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.
Abstract class for defining application layer send callbacks.
Definition: ncr_io.h:479
Abstract interface for sending NameChangeRequests.
Definition: ncr_io.h:457
Result
Defines the outcome of an asynchronous NCR send.
Definition: ncr_io.h:467
The Name class encapsulates DNS names.
Definition: name.h:223
std::string toRawText(bool omit_final_dot=false) const
Convert the LabelSequence to a string without escape sequences.
Definition: name.cc:513
Defines the D2ClientConfig class.
boost::shared_ptr< NameChangeSender > NameChangeSenderPtr
Defines a smart pointer to an instance of a sender.
Definition: ncr_io.h:777
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition: ncr_msg.h:214
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
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
boost::shared_ptr< D2ClientMgr > D2ClientMgrPtr
Defines a pointer for D2ClientMgr instances.
Defines the logger used by the top-level component of kea-dhcp-ddns.
This file defines abstract classes for exchanging NameChangeRequests.