d2_client_cfg.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (C) 2013-2016 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. #include <config.h>
  7. #include <dhcp_ddns/ncr_udp.h>
  8. #include <dhcpsrv/d2_client_cfg.h>
  9. #include <dhcpsrv/dhcpsrv_log.h>
  10. #include <boost/algorithm/string/predicate.hpp>
  11. #include <string>
  12. using namespace std;
  13. namespace isc {
  14. namespace dhcp {
  15. const char* D2ClientConfig::DFT_SERVER_IP = "127.0.0.1";
  16. const size_t D2ClientConfig::DFT_SERVER_PORT = 53001;
  17. const char* D2ClientConfig::DFT_V4_SENDER_IP = "0.0.0.0";
  18. const char* D2ClientConfig::DFT_V6_SENDER_IP = "::";
  19. const size_t D2ClientConfig::DFT_SENDER_PORT = 0;
  20. const size_t D2ClientConfig::DFT_MAX_QUEUE_SIZE = 1024;
  21. const char* D2ClientConfig::DFT_NCR_PROTOCOL = "UDP";
  22. const char* D2ClientConfig::DFT_NCR_FORMAT = "JSON";
  23. const bool D2ClientConfig::DFT_ALWAYS_INCLUDE_FQDN = false;
  24. const bool D2ClientConfig::DFT_OVERRIDE_NO_UPDATE = false;
  25. const bool D2ClientConfig::DFT_OVERRIDE_CLIENT_UPDATE = false;
  26. const char* D2ClientConfig::DFT_REPLACE_CLIENT_NAME_MODE = "NEVER";
  27. const char* D2ClientConfig::DFT_GENERATED_PREFIX = "myhost";
  28. D2ClientConfig::ReplaceClientNameMode
  29. D2ClientConfig::stringToReplaceClientNameMode(const std::string& mode_str) {
  30. if (boost::iequals(mode_str, "never")) {
  31. return (D2ClientConfig::RCM_NEVER);
  32. }
  33. if (boost::iequals(mode_str, "always")) {
  34. return (D2ClientConfig::RCM_ALWAYS);
  35. }
  36. if (boost::iequals(mode_str, "when-present")) {
  37. return (D2ClientConfig::RCM_WHEN_PRESENT);
  38. }
  39. if (boost::iequals(mode_str, "when-not-present")) {
  40. return (D2ClientConfig::RCM_WHEN_NOT_PRESENT);
  41. }
  42. isc_throw(BadValue,
  43. "Invalid ReplaceClientNameMode: " << mode_str);
  44. }
  45. std::string
  46. D2ClientConfig::replaceClientNameModeToString(const ReplaceClientNameMode& mode) {
  47. switch (mode) {
  48. case D2ClientConfig::RCM_NEVER:
  49. return ("never");
  50. case D2ClientConfig::RCM_ALWAYS:
  51. return ("always");
  52. case D2ClientConfig::RCM_WHEN_PRESENT:
  53. return ("when-present");
  54. case D2ClientConfig::RCM_WHEN_NOT_PRESENT:
  55. return ("when-not-present");
  56. default:
  57. break;
  58. }
  59. std::ostringstream stream;
  60. stream << "unknown(" << mode << ")";
  61. return (stream.str());
  62. }
  63. D2ClientConfig::D2ClientConfig(const bool enable_updates,
  64. const isc::asiolink::IOAddress& server_ip,
  65. const size_t server_port,
  66. const isc::asiolink::IOAddress& sender_ip,
  67. const size_t sender_port,
  68. const size_t max_queue_size,
  69. const dhcp_ddns::
  70. NameChangeProtocol& ncr_protocol,
  71. const dhcp_ddns::
  72. NameChangeFormat& ncr_format,
  73. const bool always_include_fqdn,
  74. const bool override_no_update,
  75. const bool override_client_update,
  76. const ReplaceClientNameMode replace_client_name_mode,
  77. const std::string& generated_prefix,
  78. const std::string& qualifying_suffix)
  79. : enable_updates_(enable_updates),
  80. server_ip_(server_ip),
  81. server_port_(server_port),
  82. sender_ip_(sender_ip),
  83. sender_port_(sender_port),
  84. max_queue_size_(max_queue_size),
  85. ncr_protocol_(ncr_protocol),
  86. ncr_format_(ncr_format),
  87. always_include_fqdn_(always_include_fqdn),
  88. override_no_update_(override_no_update),
  89. override_client_update_(override_client_update),
  90. replace_client_name_mode_(replace_client_name_mode),
  91. generated_prefix_(generated_prefix),
  92. qualifying_suffix_(qualifying_suffix) {
  93. validateContents();
  94. }
  95. D2ClientConfig::D2ClientConfig()
  96. : enable_updates_(false),
  97. server_ip_(isc::asiolink::IOAddress(DFT_SERVER_IP)),
  98. server_port_(DFT_SERVER_PORT),
  99. sender_ip_(isc::asiolink::IOAddress(DFT_V4_SENDER_IP)),
  100. sender_port_(DFT_SENDER_PORT),
  101. max_queue_size_(DFT_MAX_QUEUE_SIZE),
  102. ncr_protocol_(dhcp_ddns::stringToNcrProtocol(DFT_NCR_PROTOCOL)),
  103. ncr_format_(dhcp_ddns::stringToNcrFormat(DFT_NCR_FORMAT)),
  104. always_include_fqdn_(DFT_ALWAYS_INCLUDE_FQDN),
  105. override_no_update_(DFT_OVERRIDE_NO_UPDATE),
  106. override_client_update_(DFT_OVERRIDE_CLIENT_UPDATE),
  107. replace_client_name_mode_(stringToReplaceClientNameMode(DFT_REPLACE_CLIENT_NAME_MODE)),
  108. generated_prefix_(DFT_GENERATED_PREFIX),
  109. qualifying_suffix_("") {
  110. validateContents();
  111. }
  112. D2ClientConfig::~D2ClientConfig(){};
  113. void
  114. D2ClientConfig::enableUpdates(bool enable) {
  115. enable_updates_ = enable;
  116. }
  117. void
  118. D2ClientConfig::validateContents() {
  119. if (ncr_format_ != dhcp_ddns::FMT_JSON) {
  120. isc_throw(D2ClientError, "D2ClientConfig: NCR Format: "
  121. << dhcp_ddns::ncrFormatToString(ncr_format_)
  122. << " is not yet supported");
  123. }
  124. if (ncr_protocol_ != dhcp_ddns::NCR_UDP) {
  125. isc_throw(D2ClientError, "D2ClientConfig: NCR Protocol: "
  126. << dhcp_ddns::ncrProtocolToString(ncr_protocol_)
  127. << " is not yet supported");
  128. }
  129. if (sender_ip_.getFamily() != server_ip_.getFamily()) {
  130. isc_throw(D2ClientError, "D2ClientConfig: address family mismatch: "
  131. << "server-ip: " << server_ip_.toText()
  132. << " is: " << (server_ip_.isV4() ? "IPv4" : "IPv6")
  133. << " while sender-ip: " << sender_ip_.toText()
  134. << " is: " << (sender_ip_.isV4() ? "IPv4" : "IPv6"));
  135. }
  136. if (server_ip_ == sender_ip_ && server_port_ == sender_port_) {
  137. isc_throw(D2ClientError, "D2ClientConfig: server and sender cannot"
  138. " share the exact same IP address/port: "
  139. << server_ip_.toText() << "/" << server_port_);
  140. }
  141. /// @todo perhaps more validation we should do yet?
  142. /// Are there any invalid combinations of options we need to test against?
  143. }
  144. bool
  145. D2ClientConfig::operator == (const D2ClientConfig& other) const {
  146. return ((enable_updates_ == other.enable_updates_) &&
  147. (server_ip_ == other.server_ip_) &&
  148. (server_port_ == other.server_port_) &&
  149. (sender_ip_ == other.sender_ip_) &&
  150. (sender_port_ == other.sender_port_) &&
  151. (max_queue_size_ == other.max_queue_size_) &&
  152. (ncr_protocol_ == other.ncr_protocol_) &&
  153. (ncr_format_ == other.ncr_format_) &&
  154. (always_include_fqdn_ == other.always_include_fqdn_) &&
  155. (override_no_update_ == other.override_no_update_) &&
  156. (override_client_update_ == other.override_client_update_) &&
  157. (replace_client_name_mode_ == other.replace_client_name_mode_) &&
  158. (generated_prefix_ == other.generated_prefix_) &&
  159. (qualifying_suffix_ == other.qualifying_suffix_));
  160. }
  161. bool
  162. D2ClientConfig::operator != (const D2ClientConfig& other) const {
  163. return (!(*this == other));
  164. }
  165. std::string
  166. D2ClientConfig::toText() const {
  167. std::ostringstream stream;
  168. stream << "enable_updates: " << (enable_updates_ ? "yes" : "no");
  169. if (enable_updates_) {
  170. stream << ", server_ip: " << server_ip_.toText()
  171. << ", server_port: " << server_port_
  172. << ", sender_ip: " << sender_ip_.toText()
  173. << ", sender_port: " << sender_port_
  174. << ", max_queue_size: " << max_queue_size_
  175. << ", ncr_protocol: " << ncrProtocolToString(ncr_protocol_)
  176. << ", ncr_format: " << ncrFormatToString(ncr_format_)
  177. << ", always_include_fqdn: " << (always_include_fqdn_ ?
  178. "yes" : "no")
  179. << ", override_no_update: " << (override_no_update_ ?
  180. "yes" : "no")
  181. << ", override_client_update: " << (override_client_update_ ?
  182. "yes" : "no")
  183. << ", replace_client_name: "
  184. << replaceClientNameModeToString(replace_client_name_mode_)
  185. << ", generated_prefix: [" << generated_prefix_ << "]"
  186. << ", qualifying_suffix: [" << qualifying_suffix_ << "]";
  187. }
  188. return (stream.str());
  189. }
  190. std::ostream&
  191. operator<<(std::ostream& os, const D2ClientConfig& config) {
  192. os << config.toText();
  193. return (os);
  194. }
  195. }; // namespace dhcp
  196. }; // namespace isc