From: Thomas Markwalder Date: Wed, 28 May 2014 11:40:34 +0000 (-0400) Subject: [master] Merge branch 'trac3432' X-Git-Tag: trac3434_base~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=80fea12a53d1e832d4e7b710ca6ea613300f73ea;p=thirdparty%2Fkea.git [master] Merge branch 'trac3432' Implements TSIG in D2 Fixed Conflicts: src/bin/d2/nc_trans.cc src/bin/d2/nc_trans.h src/bin/d2/tests/nc_test_utils.cc src/bin/d2/tests/nc_trans_unittests.cc --- 80fea12a53d1e832d4e7b710ca6ea613300f73ea diff --cc src/bin/d2/d2_config.cc index c8e331e30e,21cb23db0f..45edc59895 --- a/src/bin/d2/d2_config.cc +++ b/src/bin/d2/d2_config.cc @@@ -27,103 -27,15 +27,111 @@@ namespace isc { namespace d2 { +// *********************** D2Params ************************* + +const char *D2Params::DFT_IP_ADDRESS = "127.0.0.1"; +const size_t D2Params::DFT_PORT = 53001; +const size_t D2Params::DFT_DNS_SERVER_TIMEOUT = 100; +const char *D2Params::DFT_NCR_PROTOCOL = "UDP"; +const char *D2Params::DFT_NCR_FORMAT = "JSON"; + +D2Params::D2Params(const isc::asiolink::IOAddress& ip_address, + const size_t port, + const size_t dns_server_timeout, + const dhcp_ddns::NameChangeProtocol& ncr_protocol, + const dhcp_ddns::NameChangeFormat& ncr_format) + : ip_address_(ip_address), + port_(port), + dns_server_timeout_(dns_server_timeout), + ncr_protocol_(ncr_protocol), + ncr_format_(ncr_format) { + validateContents(); +} + +D2Params::D2Params() + : ip_address_(isc::asiolink::IOAddress(DFT_IP_ADDRESS)), + port_(DFT_PORT), + dns_server_timeout_(DFT_DNS_SERVER_TIMEOUT), + ncr_protocol_(dhcp_ddns::NCR_UDP), + ncr_format_(dhcp_ddns::FMT_JSON) { + validateContents(); +} + +D2Params::~D2Params(){}; + +void +D2Params::validateContents() { + if ((ip_address_.toText() == "0.0.0.0") || (ip_address_.toText() == "::")) { + isc_throw(D2CfgError, + "D2Params: IP address cannot be \"" << ip_address_ << "\""); + } + + if (port_ == 0) { + isc_throw(D2CfgError, "D2Params: port cannot be 0"); + } + + if (dns_server_timeout_ < 1) { + isc_throw(D2CfgError, + "D2Params: DNS server timeout must be larger than 0"); + } + + if (ncr_format_ != dhcp_ddns::FMT_JSON) { + isc_throw(D2CfgError, "D2Params: NCR Format:" + << dhcp_ddns::ncrFormatToString(ncr_format_) + << " is not yet supported"); + } + + if (ncr_protocol_ != dhcp_ddns::NCR_UDP) { + isc_throw(D2CfgError, "D2Params: NCR Protocol:" + << dhcp_ddns::ncrProtocolToString(ncr_protocol_) + << " is not yet supported"); + } +} + +bool +D2Params::operator == (const D2Params& other) const { + return ((ip_address_ == other.ip_address_) && + (port_ == other.port_) && + (dns_server_timeout_ == other.dns_server_timeout_) && + (ncr_protocol_ == other.ncr_protocol_) && + (ncr_format_ == other.ncr_format_)); +} + +bool +D2Params::operator != (const D2Params& other) const { + return (!(*this == other)); +} + +std::string +D2Params::toText() const { + std::ostringstream stream; + + stream << ", ip_address: " << ip_address_.toText() + << ", port: " << port_ + << ", dns_server_timeout_: " << dns_server_timeout_ + << ", ncr_protocol: " + << dhcp_ddns::ncrProtocolToString(ncr_protocol_) + << ", ncr_format: " << ncr_format_ + << dhcp_ddns::ncrFormatToString(ncr_format_); + + return (stream.str()); +} + +std::ostream& +operator<<(std::ostream& os, const D2Params& config) { + os << config.toText(); + return (os); +} + // *********************** TSIGKeyInfo ************************* + // Note these values match correpsonding values for Bind9's + // dnssec-keygen + const char* TSIGKeyInfo::HMAC_MD5_STR = "HMAC-MD5"; + const char* TSIGKeyInfo::HMAC_SHA1_STR = "HMAC-SHA1"; + const char* TSIGKeyInfo::HMAC_SHA224_STR = "HMAC-SHA224"; + const char* TSIGKeyInfo::HMAC_SHA256_STR = "HMAC-SHA256"; + const char* TSIGKeyInfo::HMAC_SHA384_STR = "HMAC-SHA384"; + const char* TSIGKeyInfo::HMAC_SHA512_STR = "HMAC-SHA512"; TSIGKeyInfo::TSIGKeyInfo(const std::string& name, const std::string& algorithm, const std::string& secret) diff --cc src/bin/d2/d2_config.h index 168559b192,26198d2c3d..28e67bd925 --- a/src/bin/d2/d2_config.h +++ b/src/bin/d2/d2_config.h @@@ -143,135 -144,24 +144,143 @@@ public isc::Exception(file, line, what) { }; }; +/// @brief Acts as a storage vault for D2 global scalar parameters +class D2Params { +public: + /// @brief Default configuration constants. + //@{ + /// @todo For now these are hard-coded as configuration layer cannot + /// readily provide them (see Trac #3358). + static const char *DFT_IP_ADDRESS; + static const size_t DFT_PORT; + static const size_t DFT_DNS_SERVER_TIMEOUT; + static const char *DFT_NCR_PROTOCOL; + static const char *DFT_NCR_FORMAT; + //@} + + /// @brief Constructor + /// + /// @param ip_address IP address at which D2 should listen for NCRs + /// @param port port on which D2 should listen NCRs + /// @param dns_server_timeout maximum amount of time in milliseconds to + /// wait for a response to a single DNS update request. + /// @param ncr_protocol socket protocol D2 should use to receive NCRS + /// @param ncr_format packet format of the inbound NCRs + /// + /// @throw D2CfgError if: + /// -# ip_address is 0.0.0.0 or :: + /// -# port is 0 + /// -# dns_server_timeout is < 1 + /// -# ncr_protocol is invalid, currently only NCR_UDP is supported + /// -# ncr_format is invalid, currently only FMT_JSON is supported + D2Params(const isc::asiolink::IOAddress& ip_address, + const size_t port, + const size_t dns_server_timeout, + const dhcp_ddns::NameChangeProtocol& ncr_protocol, + const dhcp_ddns::NameChangeFormat& ncr_format); + + /// @brief Default constructor + /// The default constructor creates an instance that has updates disabled. + D2Params(); + + /// @brief Destructor + virtual ~D2Params(); + + /// @brief Return the IP address D2 listens on. + const isc::asiolink::IOAddress& getIpAddress() const { + return(ip_address_); + } + + /// @brief Return the TCP/UPD port D2 listens on. + size_t getPort() const { + return(port_); + } + + /// @brief Return the DNS server timeout value. + size_t getDnsServerTimeout() const { + return(dns_server_timeout_); + } + + /// @brief Return the socket protocol in use. + const dhcp_ddns::NameChangeProtocol& getNcrProtocol() const { + return(ncr_protocol_); + } + + /// @brief Return the expected format of inbound requests (NCRs). + const dhcp_ddns::NameChangeFormat& getNcrFormat() const { + return(ncr_format_); + } + + /// @brief Compares two D2Paramss for equality + bool operator == (const D2Params& other) const; + + /// @brief Compares two D2Paramss for inequality + bool operator != (const D2Params& other) const; + + /// @brief Generates a string representation of the class contents. + std::string toText() const; + +protected: + /// @brief Validates member values. + /// + /// Method is used by the constructor to validate member contents. + /// Currently checks: + /// -# ip_address is not 0.0.0.0 or :: + /// -# port is not 0 + /// -# dns_server_timeout is 0 + /// -# ncr_protocol is UDP + /// -# ncr_format is JSON + /// + /// @throw D2CfgError if contents are invalid + virtual void validateContents(); + +private: + /// @brief IP address D2 listens on. + isc::asiolink::IOAddress ip_address_; + + /// @brief IP port D2 listens on. + size_t port_; + + /// @brief Timeout for a single DNS packet exchange in milliseconds. + size_t dns_server_timeout_; + + /// @brief The socket protocol to use. + /// Currently only UDP is supported. + dhcp_ddns::NameChangeProtocol ncr_protocol_; + + /// @brief Format of the inbound requests (NCRs). + /// Currently only JSON format is supported. + dhcp_ddns::NameChangeFormat ncr_format_; +}; + +/// @brief Dumps the contents of a D2Params as text to an output stream +/// +/// @param os output stream to which text should be sent +/// @param config D2Param instnace to dump +std::ostream& +operator<<(std::ostream& os, const D2Params& config); + +/// @brief Defines a pointer for D2Params instances. +typedef boost::shared_ptr D2ParamsPtr; + /// @brief Represents a TSIG Key. /// - /// Currently, this is simple storage class containing the basic attributes of - /// a TSIG Key. It is intended primarily as a reference for working with - /// actual keys and may eventually be replaced by isc::dns::TSIGKey. TSIG Key - /// functionality at this stage is strictly limited to configuration parsing. - /// @todo full functionality for using TSIG during DNS updates will be added - /// in a future release. + /// Acts as both a storage class containing the basic attributes which + /// describe a TSIG Key, as well as owning and providing access to an + /// instance of the actual key (@ref isc::dns::TSIGKey) that can be used + /// by the IO layer for signing and verifying messages. + /// class TSIGKeyInfo { public: + /// @brief Defines string values for the supported TSIG algorithms + //@{ + static const char* HMAC_MD5_STR; + static const char* HMAC_SHA1_STR; + static const char* HMAC_SHA256_STR; + static const char* HMAC_SHA224_STR; + static const char* HMAC_SHA384_STR; + static const char* HMAC_SHA512_STR; + //}@ /// @brief Constructor /// diff --cc src/bin/d2/nc_trans.cc index f615a03572,72e0096102..da82ab7160 --- a/src/bin/d2/nc_trans.cc +++ b/src/bin/d2/nc_trans.cc @@@ -54,9 -54,9 +54,9 @@@ NameChangeTransaction(IOServicePtr& io_ dns_update_status_(DNSClient::OTHER), dns_update_response_(), forward_change_completed_(false), reverse_change_completed_(false), current_server_list_(), current_server_(), next_server_pos_(0), - update_attempts_(0), cfg_mgr_(cfg_mgr) { - update_attempts_(0), tsig_key_() { - // @todo if io_service is NULL we are multi-threading and should - // instantiate our own ++ update_attempts_(0), cfg_mgr_(cfg_mgr), tsig_key_() { + /// @todo if io_service is NULL we are multi-threading and should + /// instantiate our own if (!io_service_) { isc_throw(NameChangeTransactionError, "IOServicePtr cannot be null"); } @@@ -176,11 -170,14 +175,10 @@@ NameChangeTransaction::sendUpdate(cons // use_tsig_ is true. We should be able to navigate to the TSIG key // for the current server. If not we would need to add that. - // @todo time out should ultimately be configurable, down to - // server level? + D2ParamsPtr d2_params = cfg_mgr_->getD2Params(); dns_client_->doUpdate(*io_service_, current_server_->getIpAddress(), - current_server_->getPort(), - *dns_update_request_, - DNS_UPDATE_DEFAULT_TIMEOUT, - tsig_key_); - + current_server_->getPort(), *dns_update_request_, - d2_params->getDnsServerTimeout()); - ++ d2_params->getDnsServerTimeout(), tsig_key_); // Message is on its way, so the next event should be NOP_EVT. postNextEvent(NOP_EVT); LOG_DEBUG(dctl_logger, DBGLVL_TRACE_DETAIL, diff --cc src/bin/d2/nc_trans.h index 17f7f46ce9,494b68458b..7f1b62ae68 --- a/src/bin/d2/nc_trans.h +++ b/src/bin/d2/nc_trans.h @@@ -573,8 -573,8 +575,11 @@@ private /// @brief Number of transmit attempts for the current request. size_t update_attempts_; + /// @brief Pointer to the configuration manager. + D2CfgMgrPtr cfg_mgr_; ++ + /// @brief Pointer to the TSIG key which should be used (if any). + dns::TSIGKeyPtr tsig_key_; }; /// @brief Defines a pointer to a NameChangeTransaction.