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") {
+ isc_throw(D2CfgError, "D2Params: IP address cannot be \"0.0.0.0\"");
+ }
+
+ if (ip_address_.toText() == "::") {
+ isc_throw(D2CfgError, "D2Params: IP address cannot be \"::\"");
+ }
+
+ 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 *************************
TSIGKeyInfo::TSIGKeyInfo(const std::string& name, const std::string& algorithm,
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
+ ///
+ /// @throw D2CfgError if given an invalid protocol or format.
+ D2Params(const isc::asiolink::IOAddress& ip_address,
+ const size_t port,
+ const size_t DFT_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 D2 listens on.
+ const isc::asiolink::IOAddress& getIpAddress() const {
+ return(ip_address_);
+ }
+
+ /// @brief Return the IP 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_;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const D2Params& config);
+
+/// @brief Defines a pointer for D2Params instances.
+typedef boost::shared_ptr<D2Params> D2ParamsPtr;
+
/// @brief Represents a TSIG Key.
///
/// Currently, this is simple storage class containing the basic attributes of