diff options
Diffstat (limited to 'src/lib/dhcpsrv/d2_client_cfg.cc')
-rw-r--r-- | src/lib/dhcpsrv/d2_client_cfg.cc | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/d2_client_cfg.cc b/src/lib/dhcpsrv/d2_client_cfg.cc new file mode 100644 index 0000000..78d7ffd --- /dev/null +++ b/src/lib/dhcpsrv/d2_client_cfg.cc @@ -0,0 +1,222 @@ +// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dhcp_ddns/ncr_udp.h> +#include <dhcpsrv/d2_client_cfg.h> +#include <dhcpsrv/cfgmgr.h> +#include <dhcpsrv/dhcpsrv_log.h> + +#include <string> + +using namespace std; +using namespace isc::asiolink; +using namespace isc::data; +using namespace isc::util; + +namespace isc { +namespace dhcp { + +/// These values need to match those used in D2ClientConfigParser::SimpleDefaults +const char* D2ClientConfig::DFT_SERVER_IP = "127.0.0.1"; +const size_t D2ClientConfig::DFT_SERVER_PORT = 53001; +const char* D2ClientConfig::DFT_V4_SENDER_IP = "0.0.0.0"; +const char* D2ClientConfig::DFT_V6_SENDER_IP = "::"; +const size_t D2ClientConfig::DFT_SENDER_PORT = 0; +const size_t D2ClientConfig::DFT_MAX_QUEUE_SIZE = 1024; +const char* D2ClientConfig::DFT_NCR_PROTOCOL = "UDP"; +const char* D2ClientConfig::DFT_NCR_FORMAT = "JSON"; +const bool D2ClientConfig::DFT_OVERRIDE_NO_UPDATE = false; +const bool D2ClientConfig::DFT_OVERRIDE_CLIENT_UPDATE = false; +const char* D2ClientConfig::DFT_REPLACE_CLIENT_NAME_MODE = "NEVER"; +const char* D2ClientConfig::DFT_GENERATED_PREFIX = "myhost"; +const char* D2ClientConfig::DFT_HOSTNAME_CHAR_SET = ""; +const char* D2ClientConfig::DFT_HOSTNAME_CHAR_REPLACEMENT = ""; + +D2ClientConfig::ReplaceClientNameMode +D2ClientConfig::stringToReplaceClientNameMode(const std::string& mode_str) { + if (mode_str == "never") { + return (D2ClientConfig::RCM_NEVER); + } + + if (mode_str == "always") { + return (D2ClientConfig::RCM_ALWAYS); + } + + if (mode_str == "when-present") { + return (D2ClientConfig::RCM_WHEN_PRESENT); + } + + if (mode_str == "when-not-present") { + return (D2ClientConfig::RCM_WHEN_NOT_PRESENT); + } + + isc_throw(BadValue, + "Invalid ReplaceClientNameMode: " << mode_str); +} + +std::string +D2ClientConfig::replaceClientNameModeToString(const ReplaceClientNameMode& mode) { + switch (mode) { + case D2ClientConfig::RCM_NEVER: + return ("never"); + case D2ClientConfig::RCM_ALWAYS: + return ("always"); + case D2ClientConfig::RCM_WHEN_PRESENT: + return ("when-present"); + case D2ClientConfig::RCM_WHEN_NOT_PRESENT: + return ("when-not-present"); + default: + break; + } + + std::ostringstream stream; + stream << "unknown(" << mode << ")"; + return (stream.str()); +} + +D2ClientConfig::D2ClientConfig(const bool enable_updates, + const isc::asiolink::IOAddress& server_ip, + const size_t server_port, + const isc::asiolink::IOAddress& sender_ip, + const size_t sender_port, + const size_t max_queue_size, + const dhcp_ddns:: + NameChangeProtocol& ncr_protocol, + const dhcp_ddns:: + NameChangeFormat& ncr_format) + : enable_updates_(enable_updates), + server_ip_(server_ip), + server_port_(server_port), + sender_ip_(sender_ip), + sender_port_(sender_port), + max_queue_size_(max_queue_size), + ncr_protocol_(ncr_protocol), + ncr_format_(ncr_format) { + validateContents(); +} + +D2ClientConfig::D2ClientConfig() + : enable_updates_(false), + server_ip_(isc::asiolink::IOAddress(DFT_SERVER_IP)), + server_port_(DFT_SERVER_PORT), + sender_ip_(isc::asiolink::IOAddress(DFT_V4_SENDER_IP)), + sender_port_(DFT_SENDER_PORT), + max_queue_size_(DFT_MAX_QUEUE_SIZE), + ncr_protocol_(dhcp_ddns::stringToNcrProtocol(DFT_NCR_PROTOCOL)), + ncr_format_(dhcp_ddns::stringToNcrFormat(DFT_NCR_FORMAT)) { + validateContents(); +} + +D2ClientConfig::~D2ClientConfig(){}; + +void +D2ClientConfig::enableUpdates(bool enable) { + enable_updates_ = enable; +} + +void +D2ClientConfig::validateContents() { + if (ncr_format_ != dhcp_ddns::FMT_JSON) { + isc_throw(D2ClientError, "D2ClientConfig: NCR Format: " + << dhcp_ddns::ncrFormatToString(ncr_format_) + << " is not yet supported"); + } + + if (ncr_protocol_ != dhcp_ddns::NCR_UDP) { + isc_throw(D2ClientError, "D2ClientConfig: NCR Protocol: " + << dhcp_ddns::ncrProtocolToString(ncr_protocol_) + << " is not yet supported"); + } + + if (sender_ip_.getFamily() != server_ip_.getFamily()) { + isc_throw(D2ClientError, "D2ClientConfig: address family mismatch: " + << "server-ip: " << server_ip_.toText() + << " is: " << (server_ip_.isV4() ? "IPv4" : "IPv6") + << " while sender-ip: " << sender_ip_.toText() + << " is: " << (sender_ip_.isV4() ? "IPv4" : "IPv6")); + } + + if (server_ip_ == sender_ip_ && server_port_ == sender_port_) { + isc_throw(D2ClientError, "D2ClientConfig: server and sender cannot" + " share the exact same IP address/port: " + << server_ip_.toText() << "/" << server_port_); + } + + /// @todo perhaps more validation we should do yet? + /// Are there any invalid combinations of options we need to test against? +} + +bool +D2ClientConfig::operator == (const D2ClientConfig& other) const { + return ((enable_updates_ == other.enable_updates_) && + (server_ip_ == other.server_ip_) && + (server_port_ == other.server_port_) && + (sender_ip_ == other.sender_ip_) && + (sender_port_ == other.sender_port_) && + (max_queue_size_ == other.max_queue_size_) && + (ncr_protocol_ == other.ncr_protocol_) && + (ncr_format_ == other.ncr_format_)); +} + +bool +D2ClientConfig::operator != (const D2ClientConfig& other) const { + return (!(*this == other)); +} + +std::string +D2ClientConfig::toText() const { + std::ostringstream stream; + + stream << "enable_updates: " << (enable_updates_ ? "yes" : "no"); + if (enable_updates_) { + stream << ", server-ip: " << server_ip_.toText() + << ", server-port: " << server_port_ + << ", sender-ip: " << sender_ip_.toText() + << ", sender-port: " << sender_port_ + << ", max-queue-size: " << max_queue_size_ + << ", ncr-protocol: " << ncrProtocolToString(ncr_protocol_) + << ", ncr-format: " << ncrFormatToString(ncr_format_); + } + + + return (stream.str()); +} + +ElementPtr +D2ClientConfig::toElement() const { + ElementPtr result = Element::createMap(); + // Set user context + contextToElement(result); + // Set enable-updates + result->set("enable-updates", Element::create(enable_updates_)); + // Set server-ip + result->set("server-ip", Element::create(server_ip_.toText())); + // Set server-port + result->set("server-port", Element::create(static_cast<long long>(server_port_))); + // Set sender-ip + result->set("sender-ip", Element::create(sender_ip_.toText())); + // Set sender-port + result->set("sender-port", Element::create(static_cast<long long>(sender_port_))); + // Set max-queue-size + result->set("max-queue-size", Element::create(static_cast<long long>(max_queue_size_))); + // Set ncr-protocol + result->set("ncr-protocol", Element::create(dhcp_ddns::ncrProtocolToString(ncr_protocol_))); + // Set ncr-format + result->set("ncr-format", Element::create(dhcp_ddns::ncrFormatToString(ncr_format_))); + // Set override-no-update + return (result); +} + +std::ostream& +operator<<(std::ostream& os, const D2ClientConfig& config) { + os << config.toText(); + return (os); +} + +}; // namespace dhcp +}; // namespace isc |