]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#981] Reworked DdnsParams to allow on-demand value fetching
authorThomas Markwalder <tmark@isc.org>
Wed, 4 Dec 2019 13:27:07 +0000 (08:27 -0500)
committerThomas Markwalder <tmark@isc.org>
Mon, 27 Jan 2020 17:55:24 +0000 (12:55 -0500)
src/lib/dhcpsrv/d2_client_cfg.*
    Moved DdnsParams to srv_config.*

src/lib/dhcpsrv/network.h
    respaced

src/lib/dhcpsrv/srv_config.*
    DdnsParams relocated here from d2_client_cfg.*.
    Added SubnetPtr member.
    Added constructors from Subnet4Ptr and Subnet6Ptr
    Replaced individual members with getters.

src/lib/dhcpsrv/tests/d2_client_unittest.cc
src/lib/dhcpsrv/tests/srv_config_unittest.cc
    Retrofitted tests accordingly.

src/lib/dhcpsrv/alloc_engine.*
src/lib/dhcpsrv/d2_client_mgr.*
    Updated DdnsParams references

src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/fqdn_unittest.cc
    Updated DdnsParams references

src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/fqdn_unittest.cc
    Updated DdnsParams references

15 files changed:
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/fqdn_unittest.cc
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/fqdn_unittest.cc
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/alloc_engine.h
src/lib/dhcpsrv/d2_client_cfg.cc
src/lib/dhcpsrv/d2_client_cfg.h
src/lib/dhcpsrv/d2_client_mgr.cc
src/lib/dhcpsrv/d2_client_mgr.h
src/lib/dhcpsrv/network.h
src/lib/dhcpsrv/srv_config.cc
src/lib/dhcpsrv/srv_config.h
src/lib/dhcpsrv/tests/d2_client_unittest.cc
src/lib/dhcpsrv/tests/srv_config_unittest.cc

index d2142b77eef8f255d358cb8fee491900a588a5ad..ee04f525d7970e8f76b706277ff70369c4e6e946 100644 (file)
@@ -1842,7 +1842,7 @@ Dhcpv4Srv::processHostnameOption(Dhcpv4Exchange& ex) {
     // but there is no reservation, or the configuration of the server requires
     // that we send the option regardless.
     D2ClientConfig::ReplaceClientNameMode replace_name_mode =
-        ex.getContext()->getDdnsParams()->replace_client_name_mode_;
+        ex.getContext()->getDdnsParams()->getReplaceClientNameMode();
 
     // If we don't have a hostname then either we'll supply it or do nothing.
     if (!opt_hostname) {
@@ -2312,7 +2312,7 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
 
         // Create NameChangeRequests if DDNS is enabled and this is a
         // real allocation.
-        if (!fake_allocation && (ex.getContext()->getDdnsParams()->enable_updates_)) {
+        if (!fake_allocation && (ex.getContext()->getDdnsParams()->getEnableUpdates())) {
             try {
                 LOG_DEBUG(ddns4_logger, DBG_DHCP4_DETAIL, DHCP4_NCR_CREATE)
                     .arg(query->getLabel());
index 1560db92e73dcfbf90d72dd02c0e4cca8afa4899..e5b9ce855a24d068ddeeef7107b14c4ba5e86196 100644 (file)
@@ -348,7 +348,7 @@ public:
             return (DdnsParamsPtr(new DdnsParams()));
         }
 
-        return(CfgMgr::instance().getCurrentCfg()->getDdnsParams(*subnet_));
+        return(CfgMgr::instance().getCurrentCfg()->getDdnsParams(subnet_));
     }
 
     // Create a lease to be used by various tests.
index 2f1240de728b0c9c4f510c485a8da8d68b4ef491..59d5f367f1b0a35a8848f8ad409b79bd7257ecf3 100644 (file)
@@ -1621,9 +1621,9 @@ Dhcpv6Srv::processClientFqdn(const Pkt6Ptr& question, const Pkt6Ptr& answer,
     Option6ClientFqdnPtr fqdn = boost::dynamic_pointer_cast<
         Option6ClientFqdn>(question->getOption(D6O_CLIENT_FQDN));
     if (!fqdn) {
-        if (ddns_params->enable_updates_ &&
-            (ddns_params->replace_client_name_mode_ == D2ClientConfig::RCM_ALWAYS ||
-             ddns_params->replace_client_name_mode_ == D2ClientConfig::RCM_WHEN_NOT_PRESENT)) {
+        if (ddns_params->getEnableUpdates() &&
+            (ddns_params->getReplaceClientNameMode() == D2ClientConfig::RCM_ALWAYS ||
+             ddns_params->getReplaceClientNameMode() == D2ClientConfig::RCM_WHEN_NOT_PRESENT)) {
             // Fabricate an empty "client" FQDN with flags requesting
             // the server do all the updates.  The flags will get modified
             // below according the configuration options, the name will
@@ -1686,7 +1686,7 @@ void
 Dhcpv6Srv::createNameChangeRequests(const Pkt6Ptr& answer,
                                     AllocEngine::ClientContext6& ctx) {
     // Don't create NameChangeRequests if DNS updates are disabled.
-    if (!(ctx.getDdnsParams()->enable_updates_)) {
+    if (!(ctx.getDdnsParams()->getEnableUpdates())) {
         return;
     }
 
index b327969b44619659795759e62c212092d0395707..e8ca83a82f1f23c4e0d80090b42b85bde87d14cc 100644 (file)
@@ -144,7 +144,7 @@ public:
             return (DdnsParamsPtr(new DdnsParams()));
         }
 
-        return(CfgMgr::instance().getCurrentCfg()->getDdnsParams(*subnet_));
+        return(CfgMgr::instance().getCurrentCfg()->getDdnsParams(subnet_));
     }
 
     /// @brief Construct the DHCPv6 Client FQDN option using flags and
@@ -1663,8 +1663,8 @@ TEST_F(FqdnDhcpv6SrvTest, ddnsScopeTest) {
 
     Subnet6Ptr subnet = (CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getSubnet(2));
     ASSERT_TRUE(subnet);
-    DdnsParamsPtr p = (CfgMgr::instance().getCurrentCfg()->getDdnsParams(*subnet));
-    ASSERT_TRUE(p->enable_updates_);
+    DdnsParamsPtr p = (CfgMgr::instance().getCurrentCfg()->getDdnsParams(subnet));
+    ASSERT_TRUE(p->getEnableUpdates());
 
     // ddns-send-udpates for subnet 2 are enabled, verify the NCR is correct.
     ASSERT_EQ(1, CfgMgr::instance().getD2ClientMgr().getQueueSize());
index 5c2a1e6883925a9d60a4e029ab8e62778628325c..c99d977bf077993b81b464ebe28fd9da737add29 100644 (file)
@@ -545,7 +545,7 @@ AllocEngine::ClientContext6::getDdnsParams() {
     // Haven't created it, so this is the first time we've needed it
     // since being given a subnet.
     if (subnet_) {
-        ddns_params_ = CfgMgr::instance().getCurrentCfg()->getDdnsParams(*subnet_);
+        ddns_params_ = CfgMgr::instance().getCurrentCfg()->getDdnsParams(subnet_);
         return (ddns_params_);
     }
 
@@ -3093,7 +3093,7 @@ AllocEngine::ClientContext4::getDdnsParams() {
     // Haven't created it, so this is the first time we've needed it
     // since being given a subnet.
     if (subnet_) {
-        ddns_params_ = CfgMgr::instance().getCurrentCfg()->getDdnsParams(*subnet_);
+        ddns_params_ = CfgMgr::instance().getCurrentCfg()->getDdnsParams(subnet_);
         return (ddns_params_);
     }
 
index d6b4b1ecf0ff388c3eeee9a769112c76310dcfe4..81a38e6524f79ee3e7e3893486c92bb0037d7c78 100644 (file)
@@ -20,6 +20,7 @@
 #include <dhcpsrv/host.h>
 #include <dhcpsrv/subnet.h>
 #include <dhcpsrv/lease_mgr.h>
+#include <dhcpsrv/srv_config.h>
 #include <hooks/callout_handle.h>
 
 #include <boost/function.hpp>
index e6ca69fb870bf6fc601be142c19db50f8f9ffc34..d9520ae3e1269b64c9e6ff464359e424294e1dc8 100644 (file)
@@ -214,23 +214,6 @@ D2ClientConfig::toElement() const {
     return (result);
 }
 
-str::StringSanitizerPtr
-DdnsParams::getHostnameSanitizer() const {
-    str::StringSanitizerPtr sanitizer;
-    // If we have a local char_set we need to create the sanitizer.
-    if (!hostname_char_set_.empty()) {
-        try {
-            sanitizer.reset(new str::StringSanitizer(hostname_char_set_,
-                                                     hostname_char_replacement_));
-        } catch (const std::exception& ex) {
-            isc_throw(BadValue, "hostname_char_set_: '" << hostname_char_set_ <<
-                      "' is not a valid regular expression");
-        }
-    }
-
-    return (sanitizer);
-}
-
 std::ostream&
 operator<<(std::ostream& os, const D2ClientConfig& config) {
     os << config.toText();
@@ -238,5 +221,4 @@ operator<<(std::ostream& os, const D2ClientConfig& config) {
 }
 
 };  // namespace dhcp
-
 };  // namespace isc
index dcb21aa3c7790d3b71e97622a229b9c54c0ba9da..f1f33eedfabe7e5958e1919f9ae715029f09e107 100644 (file)
@@ -235,58 +235,6 @@ operator<<(std::ostream& os, const D2ClientConfig& config);
 /// @brief Defines a pointer for D2ClientConfig instances.
 typedef boost::shared_ptr<D2ClientConfig> D2ClientConfigPtr;
 
-/// @brief Convenience container for conveying DDNS behaviorial parameters
-/// It is intended to be populated per Packet exchange and passed into
-/// functions that require them
-struct DdnsParams {
-    DdnsParams() :
-        enable_updates_(false), override_no_update_(false), override_client_update_(false),
-        replace_client_name_mode_(D2ClientConfig::RCM_NEVER),
-        generated_prefix_("myhost"), qualifying_suffix_(""), hostname_char_set_(""),
-        hostname_char_replacement_("") {};
-
-    /// @brief Indicates whether or not DHCP DDNS updating is enabled.
-    bool enable_updates_;
-
-    /// @brief Should Kea perform updates, even if client requested no updates.
-    /// Overrides the client request for no updates via the N flag.
-    bool override_no_update_;
-
-    /// @brief Should Kea perform updates, even if client requested delegation.
-    bool override_client_update_;
-
-    /// @brief How Kea should handle the domain-name supplied by the client.
-    D2ClientConfig::ReplaceClientNameMode replace_client_name_mode_;
-
-    /// @brief Prefix Kea should use when generating domain-names.
-    std::string generated_prefix_;
-
-    /// @brief Suffix Kea should use when to qualify partial domain-names.
-    std::string qualifying_suffix_;
-
-    /// @brief Regular expression describing invalid characters for client hostnames.
-    /// If empty, host name scrubbing should not be done.
-    std::string hostname_char_set_;
-
-    /// @brief A string to replace invalid characters when scrubbing hostnames.
-    /// Meaningful only if hostname_char_set_ is not empty.
-    std::string hostname_char_replacement_;
-
-    /// @brief Returns a regular expression string sanitizer
-    ///
-    /// If hostname_char_set_ is not empty, then it is used in conjunction
-    /// hostname_char_replacment_ (which may be empty) to create and
-    /// return a StringSanitizer instance.  Otherwise it will return
-    /// an empty pointer.
-    ///
-    /// @return pointer to the StringSanitizer instance or an empty pointer
-    /// @throw BadValue if the compilation fails.
-    isc::util::str::StringSanitizerPtr getHostnameSanitizer() const;
-};
-
-/// @brief Defines a pointer for DdnsParams instances.
-typedef boost::shared_ptr<DdnsParams> DdnsParamsPtr;
-
 } // namespace isc
 } // namespace dhcp
 
index 8160e6642bbc45ed874b4aa14541b9005b6b9d71..5c40ae02eecfe53e3db7ddc2daf9bd1525ff5ca2 100644 (file)
@@ -114,7 +114,7 @@ D2ClientMgr::getD2ClientConfig() const {
 
 void
 D2ClientMgr::analyzeFqdn(const bool client_s, const bool client_n,
-                         bool& server_s, bool& server_n, 
+                         bool& server_s, bool& server_n,
                          const DdnsParams& ddns_params) const {
     // Per RFC 4702 & 4704, the client N and S flags allow the client to
     // request one of three options:
@@ -133,27 +133,27 @@ D2ClientMgr::analyzeFqdn(const bool client_s, const bool client_n,
 
     switch (mask) {
     case 0:
-        if (!ddns_params.enable_updates_) {
+        if (!ddns_params.getEnableUpdates()) {
             server_s = false;
             server_n = true;
         } else {
             // If updates are enabled and we are overriding client delegation
             // then S flag should be true.  N-flag should be false.
-            server_s = ddns_params.override_client_update_;
+            server_s = ddns_params.getOverrideClientUpdate();
             server_n = false;
         }
         break;
 
     case 1:
-        server_s = ddns_params.enable_updates_;
+        server_s = ddns_params.getEnableUpdates();
         server_n = !server_s;
         break;
 
     case 2:
         // If updates are enabled and we are overriding "no updates" then
         // S flag should be true.
-        server_s = (ddns_params.enable_updates_ &&
-                    ddns_params.override_no_update_);
+        server_s = (ddns_params.getEnableUpdates() &&
+                    ddns_params.getOverrideNoUpdate());
         server_n = !server_s;
         break;
 
@@ -174,7 +174,7 @@ D2ClientMgr::generateFqdn(const asiolink::IOAddress& address,
                  (address.isV4() ? '.' : ':'), '-');
 
     std::ostringstream gen_name;
-    gen_name << ddns_params.generated_prefix_ << "-" << hostname;
+    gen_name << ddns_params.getGeneratedPrefix() << "-" << hostname;
     return (qualifyName(gen_name.str(), ddns_params, trailing_dot));
 }
 
@@ -186,14 +186,15 @@ D2ClientMgr::qualifyName(const std::string& partial_name,
     std::ostringstream gen_name;
 
     gen_name << partial_name;
-    if (!ddns_params.qualifying_suffix_.empty()) {
+    std::string suffix = ddns_params.getQualifyingSuffix();
+    if (!suffix.empty()) {
         std::string str = gen_name.str();
         size_t len = str.length();
         if ((len > 0) && (str[len - 1] != '.')) {
             gen_name << ".";
         }
 
-        gen_name << ddns_params.qualifying_suffix_;
+        gen_name << suffix;
     }
 
     std::string str = gen_name.str();
index db8469436b4e267f00e27226c2b9608990b4ca5e..5d7b444a2713f1173d5a1d5919a5d15b2e546569 100644 (file)
@@ -14,6 +14,7 @@
 #include <asiolink/io_address.h>
 #include <dhcp_ddns/ncr_io.h>
 #include <dhcpsrv/d2_client_cfg.h>
+#include <dhcpsrv/srv_config.h>
 #include <exceptions/exceptions.h>
 
 #include <boost/algorithm/string.hpp>
@@ -208,7 +209,7 @@ public:
     /// @tparam T FQDN Option class containing the FQDN data such as
     /// dhcp::Option4ClientFqdn or dhcp::Option6ClientFqdn
     template <class T>
-    void adjustFqdnFlags(const T& fqdn, T& fqdn_resp, 
+    void adjustFqdnFlags(const T& fqdn, T& fqdn_resp,
                          const DdnsParams& ddns_params);
 
     /// @brief Get directional update flags based on server FQDN flags
@@ -474,8 +475,8 @@ void
 D2ClientMgr::adjustDomainName(const T& fqdn, T& fqdn_resp, const DdnsParams& ddns_params) {
     // If we're configured to replace it or the supplied name is blank
     // set the response name to blank.
-    if ((ddns_params.replace_client_name_mode_ == D2ClientConfig::RCM_ALWAYS ||
-         ddns_params.replace_client_name_mode_ == D2ClientConfig::RCM_WHEN_PRESENT) ||
+    D2ClientConfig::ReplaceClientNameMode mode = ddns_params.getReplaceClientNameMode();
+    if ((mode == D2ClientConfig::RCM_ALWAYS || mode == D2ClientConfig::RCM_WHEN_PRESENT) ||
         fqdn.getDomainName().empty()) {
         fqdn_resp.setDomainName("", T::PARTIAL);
     } else {
index 75a5c6051627a046d536875c508cf93e91a2e928..a71ca2c5b33d3119575224d9547ba347fd7890ad 100644 (file)
@@ -542,7 +542,8 @@ public:
     /// @param inheritance inheritance mode to be used.
     util::Optional<bool>
     getDdnsOverrideNoUpdate(const Inheritance& inheritance = Inheritance::ALL) const {
-        return (getProperty<Network>(&Network::getDdnsOverrideNoUpdate, ddns_override_no_update_,
+        return (getProperty<Network>(&Network::getDdnsOverrideNoUpdate,
+                                     ddns_override_no_update_,
                                      inheritance, "ddns-override-no-update"));
     }
 
@@ -558,14 +559,16 @@ public:
     /// @param inheritance inheritance mode to be used.
     util::Optional<bool>
     getDdnsOverrideClientUpdate(const Inheritance& inheritance = Inheritance::ALL) const {
-        return (getProperty<Network>(&Network::getDdnsOverrideClientUpdate, ddns_override_client_update_,
+        return (getProperty<Network>(&Network::getDdnsOverrideClientUpdate,
+                                     ddns_override_client_update_,
                                      inheritance, "ddns-override-client-update"));
     }
 
     /// @brief Sets new ddns-override-client-update
     ///
     /// @param ddns_override_client_update New value to use.
-    void setDdnsOverrideClientUpdate(const util::Optional<bool>& ddns_override_client_update) {
+    void setDdnsOverrideClientUpdate(const util::Optional<bool>&
+                                     ddns_override_client_update) {
         ddns_override_client_update_ = ddns_override_client_update;
     }
 
@@ -608,8 +611,9 @@ public:
     /// @brief Sets new ddns-replace-client-name-mode
     ///
     /// @param ddns_replace_client_name_mode New value to use.
-    void setDdnsReplaceClientNameMode(const util::Optional<D2ClientConfig::ReplaceClientNameMode>&
-                                          ddns_replace_client_name_mode) {
+    void
+    setDdnsReplaceClientNameMode(const util::Optional<D2ClientConfig::ReplaceClientNameMode>&
+                                 ddns_replace_client_name_mode) {
         ddns_replace_client_name_mode_ = ddns_replace_client_name_mode;
     }
 
@@ -618,7 +622,8 @@ public:
     /// @param inheritance inheritance mode to be used.
     util::Optional<std::string>
     getDdnsGeneratedPrefix(const Inheritance& inheritance = Inheritance::ALL) const {
-        return (getProperty<Network>(&Network::getDdnsGeneratedPrefix, ddns_generated_prefix_,
+        return (getProperty<Network>(&Network::getDdnsGeneratedPrefix,
+                                     ddns_generated_prefix_,
                                      inheritance, "ddns-generated-prefix"));
     }
 
@@ -634,7 +639,8 @@ public:
     /// @param inheritance inheritance mode to be used.
     util::Optional<std::string>
     getDdnsQualifyingSuffix(const Inheritance& inheritance = Inheritance::ALL) const {
-        return (getProperty<Network>(&Network::getDdnsQualifyingSuffix, ddns_qualifying_suffix_,
+        return (getProperty<Network>(&Network::getDdnsQualifyingSuffix,
+                                     ddns_qualifying_suffix_,
                                      inheritance, "ddns-qualifying-suffix"));
     }
 
@@ -662,14 +668,16 @@ public:
     /// @brief Return the invalid char replacement used to sanitize client hostnames.
     util::Optional<std::string>
     getHostnameCharReplacement(const Inheritance& inheritance = Inheritance::ALL) const {
-        return (getProperty<Network>(&Network::getHostnameCharReplacement, hostname_char_replacement_,
+        return (getProperty<Network>(&Network::getHostnameCharReplacement,
+                                     hostname_char_replacement_,
                                      inheritance, "hostname-char-replacement"));
     }
 
     /// @brief Sets new hostname-char-replacement
     ///
     /// @param hostname_char_replacement New value to use.
-    void setHostnameCharReplacement(const util::Optional<std::string>& hostname_char_replacement) {
+    void setHostnameCharReplacement(const util::Optional<std::string>&
+                                    hostname_char_replacement) {
         hostname_char_replacement_ = hostname_char_replacement;
     }
 
index 213ef0263f687fada64f03e0ba5b4a9c4dc4e899..cfe926694c60a1d05d117c138ce4cd2c7f0981ce 100644 (file)
@@ -16,6 +16,8 @@
 #include <log/logger_manager.h>
 #include <log/logger_specification.h>
 #include <dhcp/pkt.h> // Needed for HWADDR_SOURCE_*
+#include <util/strutil.h>
+
 #include <list>
 #include <sstream>
 
@@ -273,7 +275,7 @@ SrvConfig::updateStatistics() {
     }
 }
 
-isc::data::ConstElementPtr 
+isc::data::ConstElementPtr
 SrvConfig::getConfiguredGlobal(std::string name) const {
     isc::data::ConstElementPtr global;
     if (configured_globals_->contains(name)) {
@@ -590,20 +592,16 @@ SrvConfig::toElement() const {
 }
 
 DdnsParamsPtr
-SrvConfig::getDdnsParams(const Subnet& subnet) const {
-    DdnsParamsPtr params(new DdnsParams());
-
-    params->enable_updates_ = (getD2ClientConfig()->getEnableUpdates() &&
-                               subnet.getDdnsSendUpdates().get());
-
-    params->override_no_update_ = subnet.getDdnsOverrideNoUpdate().get();
-    params->override_client_update_ = subnet.getDdnsOverrideClientUpdate().get();
-    params->replace_client_name_mode_= subnet.getDdnsReplaceClientNameMode().get();
-    params->generated_prefix_ = subnet.getDdnsGeneratedPrefix().get();
-    params->qualifying_suffix_ = subnet.getDdnsQualifyingSuffix().get();
-    params->hostname_char_set_ = subnet.getHostnameCharSet().get();
-    params->hostname_char_replacement_ = subnet.getHostnameCharReplacement().get();
+SrvConfig::getDdnsParams(const Subnet4Ptr& subnet) const {
+    DdnsParamsPtr params(new DdnsParams(subnet,
+                         getD2ClientConfig()->getEnableUpdates()));
+    return params;
+}
 
+DdnsParamsPtr
+SrvConfig::getDdnsParams(const Subnet6Ptr& subnet) const {
+    DdnsParamsPtr params(new DdnsParams(subnet,
+                         getD2ClientConfig()->getEnableUpdates()));
     return params;
 }
 
@@ -657,5 +655,96 @@ SrvConfig::moveDdnsParams(isc::data::ElementPtr srv_elem) {
     }
 }
 
+bool
+DdnsParams::getEnableUpdates() const {
+    if (!subnet_) {
+        return (false);
+    }
+
+    return (enable_updates_ && subnet_->getDdnsSendUpdates().get());
+}
+
+bool
+DdnsParams::getOverrideNoUpdate() const {
+    if (!subnet_) {
+        return (false);
+    }
+
+    return (subnet_->getDdnsOverrideNoUpdate().get());
+}
+
+bool
+DdnsParams::getOverrideClientUpdate() const {
+    if (!subnet_) {
+        return (false);
+    }
+
+    return (subnet_->getDdnsOverrideClientUpdate().get());
+}
+
+D2ClientConfig::ReplaceClientNameMode
+DdnsParams::getReplaceClientNameMode() const {
+    if (!subnet_) {
+        return (D2ClientConfig::RCM_NEVER);
+    }
+
+    return (subnet_->getDdnsReplaceClientNameMode().get());
+}
+
+std::string
+DdnsParams::getGeneratedPrefix() const {
+    if (!subnet_) {
+        return ("");
+    }
+
+    return (subnet_->getDdnsGeneratedPrefix().get());
+}
+
+std::string
+DdnsParams::getQualifyingSuffix() const {
+    if (!subnet_) {
+        return ("");
+    }
+
+    return (subnet_->getDdnsQualifyingSuffix().get());
+}
+
+std::string
+DdnsParams::getHostnameCharSet() const {
+    if (!subnet_) {
+        return ("");
+    }
+
+    return (subnet_->getHostnameCharSet().get());
+}
+
+std::string
+DdnsParams::getHostnameCharReplacement() const {
+    if (!subnet_) {
+        return ("");
+    }
+
+    return (subnet_->getHostnameCharReplacement().get());
+}
+
+util::str::StringSanitizerPtr
+DdnsParams::getHostnameSanitizer() const {
+    util::str::StringSanitizerPtr sanitizer;
+    if (subnet_) {
+        std::string char_set = getHostnameCharSet();
+        if (!char_set.empty()) {
+            try {
+                sanitizer.reset(new util::str::StringSanitizer(char_set,
+                                                               getHostnameCharReplacement()));
+            } catch (const std::exception& ex) {
+                isc_throw(BadValue, "hostname_char_set_: '" << char_set <<
+                                    "' is not a valid regular expression");
+            }
+        }
+    }
+
+    return (sanitizer);
+}
+
 } // namespace dhcp
 } // namespace isc
index 4d4dca7297fecda1760a1b658f4bd4fe2bb1acf5..d4b893090728feda913ffad6c4902f5449683adf 100644 (file)
@@ -38,6 +38,66 @@ namespace dhcp {
 
 class CfgMgr;
 
+/// @brief Convenience container for conveying DDNS behaviorial parameters
+/// It is intended to be populated per Packet exchange and passed into
+/// functions that require them
+class DdnsParams {
+public:
+    DdnsParams() : subnet_(), enable_updates_(false) {};
+
+    DdnsParams(const Subnet4Ptr& subnet, bool enable_updates)
+        : subnet_(boost::dynamic_pointer_cast<Subnet>(subnet)),
+          enable_updates_(enable_updates) {}
+
+    DdnsParams(const Subnet6Ptr& subnet, bool enable_updates)
+        : subnet_(boost::dynamic_pointer_cast<Subnet>(subnet)),
+          enable_updates_(enable_updates) {}
+
+    /// @brief Indicates whether or not DHCP DDNS updating is enabled.
+    bool getEnableUpdates() const;
+
+    /// @brief Should Kea perform updates, even if client requested no updates.
+    /// Overrides the client request for no updates via the N flag.
+    bool getOverrideNoUpdate() const;
+
+    /// @brief Should Kea perform updates, even if client requested delegation.
+    bool getOverrideClientUpdate() const;
+
+    /// @brief How Kea should handle the domain-name supplied by the client.
+    D2ClientConfig::ReplaceClientNameMode getReplaceClientNameMode() const;
+
+    /// @brief Prefix Kea should use when generating domain-names.
+    std::string getGeneratedPrefix() const;
+
+    /// @brief Suffix Kea should use when to qualify partial domain-names.
+    std::string getQualifyingSuffix() const;
+
+    /// @brief Regular expression describing invalid characters for client
+    /// hostnames.  If empty, host name scrubbing should not be done.
+    std::string getHostnameCharSet() const;
+
+    /// @brief A string to replace invalid characters when scrubbing hostnames.
+    /// Meaningful only if hostname_char_set_ is not empty.
+    std::string getHostnameCharReplacement() const;
+
+    /// @brief Returns a regular expression string sanitizer
+    ///
+    /// If hostname_char_set_ is not empty, then it is used in conjunction
+    /// hostname_char_replacment_ (which may be empty) to create and
+    /// return a StringSanitizer instance.  Otherwise it will return
+    /// an empty pointer.
+    ///
+    /// @return pointer to the StringSanitizer instance or an empty pointer
+    /// @throw BadValue if the compilation fails.
+    isc::util::str::StringSanitizerPtr getHostnameSanitizer() const;
+
+private:
+    SubnetPtr subnet_;
+    bool enable_updates_;
+};
+
+/// @brief Defines a pointer for DdnsParams instances.
+typedef boost::shared_ptr<DdnsParams> DdnsParamsPtr;
 
 /// @brief Specifies current DHCP configuration
 ///
@@ -420,7 +480,9 @@ public:
     ///
     /// @param subnet Subnet for which DDNS parameters are desired.
     /// @return pointer to DddnParams instance
-    DdnsParamsPtr getDdnsParams(const Subnet& subnet) const;
+    DdnsParamsPtr getDdnsParams(const Subnet4Ptr& subnet) const;
+
+    DdnsParamsPtr getDdnsParams(const Subnet6Ptr& subnet) const;
 
     /// @brief Copies the current configuration to a new configuration.
     ///
index 67509d6549588b72359b7591be608c6f70034cf8..6a5e789d2e22fa907e8d5fd9f5452daeb492e0a4 100644 (file)
@@ -338,6 +338,30 @@ TEST(D2ClientMgr, ipv6Config) {
     EXPECT_NE(*original_config, *updated_config);
 }
 
+/// @brief Test class for execerising manager functions that are
+/// influenced by DDNS parameters.
+class D2ClientMgrParamsTest : public ::testing::Test {
+private:
+    /// @brief Prepares the class for a test.
+    virtual void SetUp() {
+        // Create a subnet and then a DdnsParams instance.
+        // We'll use the subnet's setters to alter DDNS parameter values.
+        subnet_.reset(new Subnet4(IOAddress("192.0.2.2"), 16, 1, 2, 3, 10));
+        ddns_params_.reset(new DdnsParams(subnet_, true));
+    }
+
+    /// @brief Cleans up after the test.
+    virtual void TearDown() {};
+
+public:
+    /// @brief Acts as the "selected" subnet.  It is passed into the
+    /// constructor of ddns_params_.  This allows DDNS parameters to
+    /// be modified via setters on subnet_.
+    Subnet4Ptr subnet_;
+    /// @brief Parameter instance based into D2ClientMgr functions
+    DdnsParamsPtr ddns_params_;
+};
+
 /// @brief Tests that analyzeFqdn detects invalid combination of both the
 /// client S and N flags set to true.
 TEST(D2ClientMgr, analyzeFqdnInvalidCombination) {
@@ -354,31 +378,32 @@ TEST(D2ClientMgr, analyzeFqdnInvalidCombination) {
 
 /// @brief Tests that analyzeFqdn generates correct server S and N flags when
 /// updates are enabled and all overrides are off.
-TEST(D2ClientMgr, analyzeFqdnEnabledNoOverrides) {
+TEST_F(D2ClientMgrParamsTest, analyzeFqdnEnabledNoOverrides) {
     D2ClientMgr mgr;
     bool server_s = false;
     bool server_n = false;
 
     // Create enabled configuration with all controls off (no overrides).
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "";
-    ddns_params.qualifying_suffix_ = "";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("");
+    subnet_->setDdnsQualifyingSuffix("");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // client S=0 N=0 means client wants to do forward update.
     // server S should be 0 (server is not doing forward updates)
     // and server N should be 0 (server doing reverse updates)
-    mgr.analyzeFqdn(false, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, false, server_s, server_n, *ddns_params_);
     EXPECT_FALSE(server_s);
     EXPECT_FALSE(server_n);
 
     // client S=1 N=0 means client wants server to do forward update.
     // server S should be 1 (server is doing forward updates)
     // and server N should be 0 (server doing updates)
-    mgr.analyzeFqdn(true, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(true, false, server_s, server_n, *ddns_params_);
     EXPECT_TRUE(server_s);
     EXPECT_FALSE(server_n);
 
@@ -386,84 +411,85 @@ TEST(D2ClientMgr, analyzeFqdnEnabledNoOverrides) {
     // client S=0 N=1 means client wants no one to do forward updates.
     // server S should be 0 (server is  not forward updates)
     // and server N should be 1 (server is not doing any updates)
-    mgr.analyzeFqdn(false, true, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, true, server_s, server_n, *ddns_params_);
     EXPECT_FALSE(server_s);
     EXPECT_TRUE(server_n);
 }
 
 /// @brief Tests that analyzeFqdn generates correct server S and N flags when
 /// updates are enabled and override-no-update is on.
-TEST(D2ClientMgr, analyzeFqdnEnabledOverrideNoUpdate) {
+TEST_F(D2ClientMgrParamsTest, analyzeFqdnEnabledOverrideNoUpdate) {
     D2ClientMgr mgr;
     bool server_s = false;
     bool server_n = false;
 
     // Create enabled configuration with override-no-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = true;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "";
-    ddns_params.qualifying_suffix_ = "";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(true);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("");
+    subnet_->setDdnsQualifyingSuffix("");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // client S=0 N=0 means client wants to do forward update.
     // server S should be 0 (server is not doing forward updates)
     // and server N should be 0 (server is doing reverse updates)
-    mgr.analyzeFqdn(false, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, false, server_s, server_n, *ddns_params_);
     EXPECT_FALSE(server_s);
     EXPECT_FALSE(server_n);
 
     // client S=1 N=0 means client wants server to do forward update.
     // server S should be 1 (server is doing forward updates)
     // and server N should be 0 (server doing updates)
-    mgr.analyzeFqdn(true, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(true, false, server_s, server_n, *ddns_params_);
     EXPECT_TRUE(server_s);
     EXPECT_FALSE(server_n);
 
     // client S=0 N=1 means client wants no one to do forward updates.
     // server S should be 1 (server is doing forward updates)
     // and server N should be 0 (server is doing updates)
-    mgr.analyzeFqdn(false, true, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, true, server_s, server_n, *ddns_params_);
     EXPECT_TRUE(server_s);
     EXPECT_FALSE(server_n);
 }
 
 /// @brief Tests that analyzeFqdn generates correct server S and N flags when
 /// updates are enabled and override-client-update is on.
-TEST(D2ClientMgr, analyzeFqdnEnabledOverrideClientUpdate) {
+TEST_F(D2ClientMgrParamsTest, analyzeFqdnEnabledOverrideClientUpdate) {
     D2ClientMgr mgr;
     bool server_s = false;
     bool server_n = false;
 
     // Create enabled configuration with override-client-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = true;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "";
-    ddns_params.qualifying_suffix_ = "";
-
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(true);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("");
+    subnet_->setDdnsQualifyingSuffix("");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // client S=0 N=0 means client wants to do forward update.
     // server S should be 1 (server is doing forward updates)
     // and server N should be 0 (server doing updates)
-    mgr.analyzeFqdn(false, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, false, server_s, server_n, *ddns_params_);
     EXPECT_TRUE(server_s);
     EXPECT_FALSE(server_n);
 
     // client S=1 N=0 means client wants server to do forward update.
     // server S should be 1 (server is doing forward updates)
     // and server N should be 0 (server doing updates)
-    mgr.analyzeFqdn(true, false, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(true, false, server_s, server_n, *ddns_params_);
     EXPECT_TRUE(server_s);
     EXPECT_FALSE(server_n);
 
     // client S=0 N=1 means client wants no one to do forward updates.
     // server S should be 0 (server is  not forward updates)
     // and server N should be 1 (server is not doing any updates)
-    mgr.analyzeFqdn(false, true, server_s, server_n, ddns_params);
+    mgr.analyzeFqdn(false, true, server_s, server_n, *ddns_params_);
     EXPECT_FALSE(server_s);
     EXPECT_TRUE(server_n);
 }
@@ -471,19 +497,20 @@ TEST(D2ClientMgr, analyzeFqdnEnabledOverrideClientUpdate) {
 /// @brief Verifies the adustFqdnFlags template with Option4ClientFqdn objects.
 /// Ensures that the method can set the N, S, and O flags properly.
 /// Other permutations are covered by analyzeFqdnFlag tests.
-TEST(D2ClientMgr, adjustFqdnFlagsV4) {
+TEST_F(D2ClientMgrParamsTest, adjustFqdnFlagsV4) {
     D2ClientMgr mgr;
     Option4ClientFqdnPtr request;
     Option4ClientFqdnPtr response;
 
     // Create enabled configuration with override-no-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = true;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "";
-    ddns_params.qualifying_suffix_ = "";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(true);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("");
+    subnet_->setDdnsQualifyingSuffix("");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // client S=0 N=0 means client wants to do forward update.
     // server S should be 0 (server is not doing forward updates)
@@ -494,7 +521,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV4) {
     response.reset(new Option4ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_O));
@@ -509,7 +536,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV4) {
     response.reset(new Option4ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_O));
@@ -524,7 +551,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV4) {
     response.reset(new Option4ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
     EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_O));
@@ -567,117 +594,119 @@ TEST(D2ClientMgr, updateDirectionsV4) {
 }
 
 /// @brief Tests the qualifyName method's ability to construct FQDNs
-TEST(D2ClientMgr, qualifyName) {
+TEST_F(D2ClientMgrParamsTest, qualifyName) {
     D2ClientMgr mgr;
     bool do_not_dot = false;
     bool do_dot = true;
 
     // Create enabled configuration
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // Verify that the qualifying suffix gets appended with a trailing dot added.
     std::string partial_name = "somehost";
-    std::string qualified_name = mgr.qualifyName(partial_name, ddns_params, do_dot);
+    std::string qualified_name = mgr.qualifyName(partial_name, *ddns_params_, do_dot);
     EXPECT_EQ("somehost.suffix.com.", qualified_name);
 
     // Verify that the qualifying suffix gets appended without a trailing dot.
     partial_name = "somehost";
-    qualified_name = mgr.qualifyName(partial_name, ddns_params, do_not_dot);
+    qualified_name = mgr.qualifyName(partial_name, *ddns_params_, do_not_dot);
     EXPECT_EQ("somehost.suffix.com", qualified_name);
 
     // Verify that an empty suffix and false flag, does not change the name
-    ddns_params.qualifying_suffix_ = "";
+    subnet_->setDdnsQualifyingSuffix("");
     partial_name = "somehost";
-    qualified_name = mgr.qualifyName(partial_name, ddns_params, do_not_dot);
+    qualified_name = mgr.qualifyName(partial_name, *ddns_params_, do_not_dot);
     EXPECT_EQ("somehost", qualified_name);
 
     // Verify that a qualifying suffix that already has a trailing
     // dot gets appended without doubling the dot.
-    ddns_params.qualifying_suffix_ = "hasdot.com.";
-    qualified_name = mgr.qualifyName(partial_name, ddns_params, do_dot);
+    subnet_->setDdnsQualifyingSuffix("hasdot.com.");
+    qualified_name = mgr.qualifyName(partial_name, *ddns_params_, do_dot);
     EXPECT_EQ("somehost.hasdot.com.", qualified_name);
 
     // Verify that the qualifying suffix gets appended without an
     // extraneous dot when partial_name ends with a "."
-    qualified_name = mgr.qualifyName("somehost.", ddns_params, do_dot);
+    qualified_name = mgr.qualifyName("somehost.", *ddns_params_, do_dot);
     EXPECT_EQ("somehost.hasdot.com.", qualified_name);
 
     // Verify that a name with a trailing dot does not get an extraneous
     // dot when the suffix is blank
-    ddns_params.qualifying_suffix_ = "";
-    qualified_name = mgr.qualifyName("somehost.", ddns_params, do_dot);
+    subnet_->setDdnsQualifyingSuffix("");
+    qualified_name = mgr.qualifyName("somehost.", *ddns_params_, do_dot);
     EXPECT_EQ("somehost.", qualified_name);
 
     // Verify that a name with no trailing dot gets just a dot when the
     // suffix is blank
-    qualified_name = mgr.qualifyName("somehost", ddns_params, do_dot);
+    qualified_name = mgr.qualifyName("somehost", *ddns_params_, do_dot);
     EXPECT_EQ("somehost.", qualified_name);
 
     // Verify that a name with no trailing dot does not get dotted when the
     // suffix is blank and trailing dot is false
-    qualified_name = mgr.qualifyName("somehost", ddns_params, do_not_dot);
+    qualified_name = mgr.qualifyName("somehost", *ddns_params_, do_not_dot);
     EXPECT_EQ("somehost", qualified_name);
 
     // Verify that a name with trailing dot gets "undotted" when the
     // suffix is blank and trailing dot is false
-    qualified_name = mgr.qualifyName("somehost.", ddns_params, do_not_dot);
+    qualified_name = mgr.qualifyName("somehost.", *ddns_params_, do_not_dot);
     EXPECT_EQ("somehost", qualified_name);
 
 }
 
-
 /// @brief Tests the generateFdqn method's ability to construct FQDNs
-TEST(D2ClientMgr, generateFqdn) {
+TEST_F(D2ClientMgrParamsTest, generateFqdn) {
     D2ClientMgr mgr;
     bool do_dot = true;
 
     // Create enabled configuration
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // Verify that it works with an IPv4 address.
     asiolink::IOAddress v4address("192.0.2.75");
     EXPECT_EQ("prefix-192-0-2-75.suffix.com.",
-              mgr.generateFqdn(v4address, ddns_params, do_dot));
+              mgr.generateFqdn(v4address, *ddns_params_, do_dot));
 
     // Verify that it works with an IPv6 address.
     asiolink::IOAddress v6address("2001:db8::2");
     EXPECT_EQ("prefix-2001-db8--2.suffix.com.",
-              mgr.generateFqdn(v6address, ddns_params, do_dot));
+              mgr.generateFqdn(v6address, *ddns_params_, do_dot));
 
     // Create a disabled config.
-    ddns_params.enable_updates_ = false;
+    subnet_->setDdnsSendUpdates(false);
 
     // Verify names generate properly with a disabled configuration.
     EXPECT_EQ("prefix-192-0-2-75.suffix.com.",
-               mgr.generateFqdn(v4address, ddns_params, do_dot));
+               mgr.generateFqdn(v4address, *ddns_params_, do_dot));
     EXPECT_EQ("prefix-2001-db8--2.suffix.com.",
-               mgr.generateFqdn(v6address, ddns_params, do_dot));
+               mgr.generateFqdn(v6address, *ddns_params_, do_dot));
 }
 
 /// @brief Tests adjustDomainName template method with Option4ClientFqdn
-TEST(D2ClientMgr, adjustDomainNameV4) {
+TEST_F(D2ClientMgrParamsTest, adjustDomainNameV4) {
     D2ClientMgr mgr;
 
     // Create enabled configuration
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     struct Scenario {
         std::string description_;
@@ -766,31 +795,33 @@ TEST(D2ClientMgr, adjustDomainNameV4) {
     for (auto scenario : scenarios) {
         SCOPED_TRACE(scenario.description_);
         {
-            ddns_params.replace_client_name_mode_ = scenario.mode_;
+            subnet_->setDdnsReplaceClientNameMode(scenario.mode_);
             Option4ClientFqdn request (0, Option4ClientFqdn::RCODE_CLIENT(),
                                        scenario.client_name_,
                                        scenario.client_name_type_);
 
             Option4ClientFqdn response(request);
-            mgr.adjustDomainName<Option4ClientFqdn>(request, response, ddns_params);
+            mgr.adjustDomainName<Option4ClientFqdn>(request, response, *ddns_params_);
             EXPECT_EQ(scenario.expected_name_, response.getDomainName());
             EXPECT_EQ(scenario.expected_name_type_, response.getDomainNameType());
         }
     }
 }
 
+
 /// @brief Tests adjustDomainName template method with Option6ClientFqdn
-TEST(D2ClientMgr, adjustDomainNameV6) {
+TEST_F(D2ClientMgrParamsTest, adjustDomainNameV6) {
     D2ClientMgr mgr;
 
     // Create enabled configuration
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     struct Scenario {
         std::string description_;
@@ -879,12 +910,12 @@ TEST(D2ClientMgr, adjustDomainNameV6) {
     for (auto scenario : scenarios) {
         SCOPED_TRACE(scenario.description_);
         {
-            ddns_params.replace_client_name_mode_ = scenario.mode_;
+            subnet_->setDdnsReplaceClientNameMode(scenario.mode_);
             Option6ClientFqdn request(0, scenario.client_name_,
                                       scenario.client_name_type_);
 
             Option6ClientFqdn response(request);
-            mgr.adjustDomainName<Option6ClientFqdn>(request, response, ddns_params);
+            mgr.adjustDomainName<Option6ClientFqdn>(request, response, *ddns_params_);
             EXPECT_EQ(scenario.expected_name_, response.getDomainName());
             EXPECT_EQ(scenario.expected_name_type_, response.getDomainNameType());
         }
@@ -894,19 +925,20 @@ TEST(D2ClientMgr, adjustDomainNameV6) {
 /// @brief Verifies the adustFqdnFlags template with Option6ClientFqdn objects.
 /// Ensures that the method can set the N, S, and O flags properly.
 /// Other permutations are covered by analyzeFqdnFlags tests.
-TEST(D2ClientMgr, adjustFqdnFlagsV6) {
+TEST_F(D2ClientMgrParamsTest, adjustFqdnFlagsV6) {
     D2ClientMgr mgr;
     Option6ClientFqdnPtr request;
     Option6ClientFqdnPtr response;
 
     // Create enabled configuration with override-no-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = true;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "";
-    ddns_params.qualifying_suffix_ = "";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(true);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("");
+    subnet_->setDdnsQualifyingSuffix("");
+    subnet_->setHostnameCharSet("");
+    subnet_->setHostnameCharReplacement("");
 
     // client S=0 N=0 means client wants to do forward update.
     // server S should be 0 (server is not doing forward updates)
@@ -916,7 +948,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV6) {
     response.reset(new Option6ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_O));
@@ -930,7 +962,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV6) {
     response.reset(new Option6ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_O));
@@ -944,7 +976,7 @@ TEST(D2ClientMgr, adjustFqdnFlagsV6) {
     response.reset(new Option6ClientFqdn(*request));
     response->resetFlags();
 
-    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, ddns_params);
+    mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response, *ddns_params_);
     EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_S));
     EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
     EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_O));
@@ -985,23 +1017,22 @@ TEST(D2ClientMgr, updateDirectionsV6) {
 }
 
 /// @brief Tests v4 FQDN name sanitizing
-TEST(D2ClientMgr, sanitizeFqdnV4) {
+TEST_F(D2ClientMgrParamsTest, sanitizeFqdnV4) {
     D2ClientMgr mgr;
 
     // Create enabled configuration with override-no-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
-    ddns_params.hostname_char_set_ = "[^A-Za-z0-9-]";
-    ddns_params.hostname_char_replacement_ = "x";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("[^A-Za-z0-9-]");
+    subnet_->setHostnameCharReplacement("x");
 
     // Get the sanitizer.
     str::StringSanitizerPtr hostname_sanitizer;
-    ASSERT_NO_THROW(hostname_sanitizer = ddns_params.getHostnameSanitizer());
+    ASSERT_NO_THROW(hostname_sanitizer = ddns_params_->getHostnameSanitizer());
     ASSERT_TRUE(hostname_sanitizer);
 
     struct Scenario {
@@ -1057,7 +1088,7 @@ TEST(D2ClientMgr, sanitizeFqdnV4) {
                                       scenario.client_name_, scenario.name_type_);
             Option4ClientFqdn response(request);
 
-            mgr.adjustDomainName<Option4ClientFqdn>(request, response, ddns_params);
+            mgr.adjustDomainName<Option4ClientFqdn>(request, response, *ddns_params_);
             EXPECT_EQ(scenario.expected_name_, response.getDomainName());
             EXPECT_EQ(Option4ClientFqdn::FULL, response.getDomainNameType());
         }
@@ -1069,23 +1100,22 @@ TEST(D2ClientMgr, sanitizeFqdnV4) {
 /// downcases strings used to construct it.  For some reason, currently
 /// uknown, Option4ClientFqdn preserves the case, while Option6ClientFqdn
 /// downcases it (see setDomainName() in both classes.  See Trac #5700.
-TEST(D2ClientMgr, sanitizeFqdnV6) {
+TEST_F(D2ClientMgrParamsTest, sanitizeFqdnV6) {
     D2ClientMgr mgr;
 
     // Create enabled configuration with override-no-update true.
-    DdnsParams ddns_params;
-    ddns_params.enable_updates_ = true;
-    ddns_params.override_no_update_ = false;
-    ddns_params.override_client_update_ = false;
-    ddns_params.replace_client_name_mode_ = D2ClientConfig::RCM_NEVER;
-    ddns_params.generated_prefix_ = "prefix";
-    ddns_params.qualifying_suffix_ = "suffix.com";
-    ddns_params.hostname_char_set_ = "[^A-Za-z0-9-]";
-    ddns_params.hostname_char_replacement_ = "x";
+    subnet_->setDdnsSendUpdates(true);
+    subnet_->setDdnsOverrideNoUpdate(false);
+    subnet_->setDdnsOverrideClientUpdate(false);
+    subnet_->setDdnsReplaceClientNameMode(D2ClientConfig::RCM_NEVER);
+    subnet_->setDdnsGeneratedPrefix("prefix");
+    subnet_->setDdnsQualifyingSuffix("suffix.com");
+    subnet_->setHostnameCharSet("[^A-Za-z0-9-]");
+    subnet_->setHostnameCharReplacement("x");
 
     // Get the sanitizer.
     str::StringSanitizerPtr hostname_sanitizer;
-    ASSERT_NO_THROW(hostname_sanitizer = ddns_params.getHostnameSanitizer());
+    ASSERT_NO_THROW(hostname_sanitizer = ddns_params_->getHostnameSanitizer());
     ASSERT_TRUE(hostname_sanitizer);
 
     struct Scenario {
@@ -1141,7 +1171,7 @@ TEST(D2ClientMgr, sanitizeFqdnV6) {
             Option6ClientFqdn request(0, scenario.client_name_, scenario.name_type_);
             Option6ClientFqdn response(request);
 
-            mgr.adjustDomainName<Option6ClientFqdn>(request, response, ddns_params);
+            mgr.adjustDomainName<Option6ClientFqdn>(request, response, *ddns_params_);
             EXPECT_EQ(scenario.expected_name_, response.getDomainName());
             EXPECT_EQ(Option6ClientFqdn::FULL, response.getDomainNameType());
         }
index 0dfc62a8e4c42beb6dc4d5f47c9c6b8bc4a188ad..534c4cc493d0b3984a7a7c9b97e0f3eff7542cba 100644 (file)
@@ -1031,7 +1031,7 @@ TEST_F(SrvConfigTest, mergeGlobals4) {
     EXPECT_EQ(300, cfg_to.getDeclinePeriod());
 
     // echo-client-id should be the preserved "to" member value.
-    EXPECT_EQ(false, cfg_to.getEchoClientId());
+    EXPECT_FALSE(cfg_to.getEchoClientId());
 
     //  dhcp4o6-port should be the "from" configured value.
     EXPECT_EQ(999, cfg_to.getDhcp4o6Port());
@@ -1322,17 +1322,17 @@ TEST_F(SrvConfigTest, getDdnsParamsTest4) {
     subnet2->setHostnameCharSet("");
 
     // Get DDNS params for subnet1.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
 
     // Verify subnet1 values are right. Note, updates should be disabled.
-    EXPECT_FALSE(params->enable_updates_);
-    EXPECT_FALSE(params->override_no_update_);
-    EXPECT_FALSE(params->override_client_update_);
-    EXPECT_EQ(D2ClientConfig::RCM_NEVER, params->replace_client_name_mode_);
-    EXPECT_TRUE(params->generated_prefix_.empty());
-    EXPECT_TRUE(params->qualifying_suffix_.empty());
-    EXPECT_EQ("[^A-Z]", params->hostname_char_set_);
-    EXPECT_EQ("x", params->hostname_char_replacement_);
+    EXPECT_FALSE(params->getEnableUpdates());
+    EXPECT_FALSE(params->getOverrideNoUpdate());
+    EXPECT_FALSE(params->getOverrideClientUpdate());
+    EXPECT_EQ(D2ClientConfig::RCM_NEVER, params->getReplaceClientNameMode());
+    EXPECT_TRUE(params->getGeneratedPrefix().empty());
+    EXPECT_TRUE(params->getQualifyingSuffix().empty());
+    EXPECT_EQ("[^A-Z]", params->getHostnameCharSet());
+    EXPECT_EQ("x", params->getHostnameCharReplacement());
 
     // We inherited a non-blank hostname_char_set so we
     // should get a sanitizer instance.
@@ -1341,18 +1341,18 @@ TEST_F(SrvConfigTest, getDdnsParamsTest4) {
     EXPECT_TRUE(sanitizer);
 
     // Get DDNS params for subnet2.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet2));
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet2));
 
     // Verify subnet2 values are right. Note, updates should be disabled,
     // because D2Client is disabled.
-    EXPECT_FALSE(params->enable_updates_);
-    EXPECT_TRUE(params->override_no_update_);
-    EXPECT_TRUE(params->override_client_update_);
-    EXPECT_EQ(D2ClientConfig::RCM_ALWAYS, params->replace_client_name_mode_);
-    EXPECT_EQ("prefix", params->generated_prefix_);
-    EXPECT_EQ("example.com.", params->qualifying_suffix_);
-    EXPECT_EQ("", params->hostname_char_set_);
-    EXPECT_EQ("x", params->hostname_char_replacement_);
+    EXPECT_FALSE(params->getEnableUpdates());
+    EXPECT_TRUE(params->getOverrideNoUpdate());
+    EXPECT_TRUE(params->getOverrideClientUpdate());
+    EXPECT_EQ(D2ClientConfig::RCM_ALWAYS, params->getReplaceClientNameMode());
+    EXPECT_EQ("prefix", params->getGeneratedPrefix());
+    EXPECT_EQ("example.com.", params->getQualifyingSuffix());
+    EXPECT_EQ("", params->getHostnameCharSet());
+    EXPECT_EQ("x", params->getHostnameCharReplacement());
 
     // We have a blank hostname-char-set so we should not get a sanitizer instance.
     ASSERT_NO_THROW(sanitizer = params->getHostnameSanitizer());
@@ -1362,19 +1362,19 @@ TEST_F(SrvConfigTest, getDdnsParamsTest4) {
     enableD2Client(true);
 
     // Make sure subnet1 udpates are still disabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
-    EXPECT_FALSE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
+    EXPECT_FALSE(params->getEnableUpdates());
 
     // Make sure subnet2 udpates are now enabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet2));
-    EXPECT_TRUE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet2));
+    EXPECT_TRUE(params->getEnableUpdates());
 
     // Enable sending updates globally.  This should inherit down subnet1.
     conf.addConfiguredGlobal("ddns-send-updates", Element::create(true));
 
     // Make sure subnet1 udpates are now enabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
-    EXPECT_TRUE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
+    EXPECT_TRUE(params->getEnableUpdates());
 }
 
 // Verifies that the scoped values for DDNS parameters can be fetched
@@ -1394,7 +1394,6 @@ TEST_F(SrvConfigTest, getDdnsParamsTest6) {
     // Configure global host sanitizing.
     conf.addConfiguredGlobal("hostname-char-set", Element::create("[^A-Z]"));
     conf.addConfiguredGlobal("hostname-char-replacement", Element::create("x"));
-
     // Add a plain subnet
     Triplet<uint32_t> def_triplet;
     Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64,
@@ -1433,17 +1432,17 @@ TEST_F(SrvConfigTest, getDdnsParamsTest6) {
     subnet2->setHostnameCharSet("");
 
     // Get DDNS params for subnet1.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
 
     // Verify subnet1 values are right. Note, updates should be disabled.
-    EXPECT_FALSE(params->enable_updates_);
-    EXPECT_FALSE(params->override_no_update_);
-    EXPECT_FALSE(params->override_client_update_);
-    EXPECT_EQ(D2ClientConfig::RCM_NEVER, params->replace_client_name_mode_);
-    EXPECT_TRUE(params->generated_prefix_.empty());
-    EXPECT_TRUE(params->qualifying_suffix_.empty());
-    EXPECT_EQ("[^A-Z]", params->hostname_char_set_);
-    EXPECT_EQ("x", params->hostname_char_replacement_);
+    EXPECT_FALSE(params->getEnableUpdates());
+    EXPECT_FALSE(params->getOverrideNoUpdate());
+    EXPECT_FALSE(params->getOverrideClientUpdate());
+    EXPECT_EQ(D2ClientConfig::RCM_NEVER, params->getReplaceClientNameMode());
+    EXPECT_TRUE(params->getGeneratedPrefix().empty());
+    EXPECT_TRUE(params->getQualifyingSuffix().empty());
+    EXPECT_EQ("[^A-Z]", params->getHostnameCharSet());
+    EXPECT_EQ("x", params->getHostnameCharReplacement());
 
     // We inherited a non-blank hostname_char_set so we
     // should get a sanitizer instance.
@@ -1452,18 +1451,18 @@ TEST_F(SrvConfigTest, getDdnsParamsTest6) {
     EXPECT_TRUE(sanitizer);
 
     // Get DDNS params for subnet2.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet2));
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet2));
 
     // Verify subnet1 values are right. Note, updates should be disabled,
     // because D2Client is disabled.
-    EXPECT_FALSE(params->enable_updates_);
-    EXPECT_TRUE(params->override_no_update_);
-    EXPECT_TRUE(params->override_client_update_);
-    EXPECT_EQ(D2ClientConfig::RCM_ALWAYS, params->replace_client_name_mode_);
-    EXPECT_EQ("prefix", params->generated_prefix_);
-    EXPECT_EQ("example.com.", params->qualifying_suffix_);
-    EXPECT_EQ("", params->hostname_char_set_);
-    EXPECT_EQ("x", params->hostname_char_replacement_);
+    EXPECT_FALSE(params->getEnableUpdates());
+    EXPECT_TRUE(params->getOverrideNoUpdate());
+    EXPECT_TRUE(params->getOverrideClientUpdate());
+    EXPECT_EQ(D2ClientConfig::RCM_ALWAYS, params->getReplaceClientNameMode());
+    EXPECT_EQ("prefix", params->getGeneratedPrefix());
+    EXPECT_EQ("example.com.", params->getQualifyingSuffix());
+    EXPECT_EQ("", params->getHostnameCharSet());
+    EXPECT_EQ("x", params->getHostnameCharReplacement());
 
     // We have a blank hostname-char-set so we should not get a sanitizer instance.
     ASSERT_NO_THROW(sanitizer = params->getHostnameSanitizer());
@@ -1473,19 +1472,19 @@ TEST_F(SrvConfigTest, getDdnsParamsTest6) {
     enableD2Client(true);
 
     // Make sure subnet1 udpates are still disabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
-    EXPECT_FALSE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
+    EXPECT_FALSE(params->getEnableUpdates());
 
     // Make sure subnet2 udpates are now enabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet2));
-    EXPECT_TRUE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet2));
+    EXPECT_TRUE(params->getEnableUpdates());
 
     // Enable sending updates globally.  This should inherit down subnet1.
     conf.addConfiguredGlobal("ddns-send-updates", Element::create(true));
 
     // Make sure subnet1 udpates are now enabled.
-    ASSERT_NO_THROW(params = conf_.getDdnsParams(*subnet1));
-    EXPECT_TRUE(params->enable_updates_);
+    ASSERT_NO_THROW(params = conf_.getDdnsParams(subnet1));
+    EXPECT_TRUE(params->getEnableUpdates());
 }
 
 } // end of anonymous namespace