]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1082] More advanced PoC
authorFrancis Dupont <fdupont@isc.org>
Fri, 18 Dec 2020 17:53:18 +0000 (18:53 +0100)
committerRazvan Becheriu <razvan@isc.org>
Thu, 6 Jan 2022 12:48:45 +0000 (14:48 +0200)
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/cfg_globals.cc [new file with mode: 0644]
src/lib/dhcpsrv/cfg_globals.h [new file with mode: 0644]

index 7a0218ac5a529d6f7cbb41bc0d89f2fee285ec59..8826e337e24253e1224db9036c5a510d2735d00c 100644 (file)
@@ -77,6 +77,7 @@ libkea_dhcpsrv_la_SOURCES += cfg_4o6.cc cfg_4o6.h
 libkea_dhcpsrv_la_SOURCES += cfg_consistency.cc cfg_consistency.h
 libkea_dhcpsrv_la_SOURCES += cfg_db_access.cc cfg_db_access.h
 libkea_dhcpsrv_la_SOURCES += cfg_duid.cc cfg_duid.h
+libkea_dhcpsrv_la_SOURCES += cfg_globals.cc cfg_globals.h
 libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
 libkea_dhcpsrv_la_SOURCES += cfg_hosts_util.cc cfg_hosts_util.h
 libkea_dhcpsrv_la_SOURCES += cfg_iface.cc cfg_iface.h
diff --git a/src/lib/dhcpsrv/cfg_globals.cc b/src/lib/dhcpsrv/cfg_globals.cc
new file mode 100644 (file)
index 0000000..e40c865
--- /dev/null
@@ -0,0 +1,191 @@
+// Copyright (C) 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 <dhcpsrv/cfg_globals.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+const std::map<std::string, int>
+CfgGlobals::nameToIndex = {
+    // Common parameters.
+    { "valid-lifetime", VALID_LIFETIME },
+    { "min-valid-lifetime", MIN_VALID_LIFETIME },
+    { "max-valid-lifetime", MAX_VALID_LIFETIME },
+    { "renew-timer", RENEW_TIMER },
+    { "rebind-timer", REBIND_TIMER },
+    { "decline-probation-period", DECLINE_PROBATION_PERIOD },
+    { "shared-networks", SHARED_NETWORKS },
+    { "interfaces-config", INTERFACES_CONFIG },
+    { "lease-database", LEASE_DATABASE },
+    { "hosts-database", HOSTS_DATABASE },
+    { "hosts-databases", HOSTS_DATABASES },
+    { "host-reservation-identifiers", HOST_RESERVATION_IDENTIFIERS },
+    { "client-classes", CLIENT_CLASSES },
+    { "option-def", OPTION_DEF },
+    { "option-data", OPTION_DATA },
+    { "hooks-libraries", HOOKS_LIBRARIES },
+    { "expired-leases-processing", EXPIRED_LEASES_PROCESSING },
+    { "dhcp4o6-port", DHCP4O6_PORT },
+    { "control-socket", CONTROL_SOCKET },
+    { "dhcp-queue-control", DHCP_QUEUE_CONTROL },
+    { "dhcp-ddns", DHCP_DDNS },
+    { "user-context", USER_CONTEXT },
+    { "comment", COMMENT },
+    { "sanity-checks", SANITY_CHECKS },
+    { "reservations", RESERVATIONS },
+    { "config-control", CONFIG_CONTROL },
+    { "server-tag", SERVER_TAG },
+    { "reservation-mode", RESERVATION_MODE },
+    { "reservations-global", RESERVATIONS_GLOBAL },
+    { "reservations-in-subnet", RESERVATIONS_IN_SUBNET },
+    { "reservations-out-of-pool", RESERVATIONS_OUT_OF_POOL },
+    { "calculate-tee-times", CALCULATE_TEE_TIMES },
+    { "t1-percent", T1_PERCENT },
+    { "t2-percent", T2_PERCENT },
+    { "loggers", LOGGERS },
+    { "hostname-char-set", HOSTNAME_CHAR_SET },
+    { "hostname-char-replacement", HOSTNAME_CHAR_REPLACEMENT },
+    { "ddns-send-updates", DDNS_SEND_UPDATES },
+    { "ddns-override-no-update", DDNS_OVERRIDE_NO_UPDATE },
+    { "ddns-override-client-update", DDNS_OVERRIDE_CLIENT_UPDATE },
+    { "ddns-replace-client-name", DDNS_REPLACE_CLIENT_NAME },
+    { "ddns-generated-prefix", DDNS_GENERATED_PREFIX },
+    { "ddns-qualifying-suffix", DDNS_QUALIFYING_SUFFIX },
+    { "store-extended-info", STORE_EXTENDED_INFO },
+    { "statistic-default-sample-count", STATISTIC_DEFAULT_SAMPLE_COUNT },
+    { "statistic-default-sample-age", STATISTIC_DEFAULT_SAMPLE_AGE },
+    { "multi-threading", MULTI_THREADING },
+    { "cache-threshold", CACHE_THRESHOLD },
+    { "cache-max-age", CACHE_MAX_AGE },
+    { "ip-reservations-unique", IP_RESERVATIONS_UNIQUE },
+    { "ddns-update-on-renew", DDNS_UPDATE_ON_RENEW },
+    { "ddns-use-conflict-resolution", DDNS_USE_CONFLICT_RESOLUTION },
+
+    // DHCPv4 specific parameters.
+    { "subnet4", SUBNET4 },
+    { "echo-client-id", ECHO_CLIENT_ID },
+    { "match-client-id", MATCH_CLIENT_ID },
+    { "authoritative", AUTHORITATIVE },
+    { "next-server", NEXT_SERVER },
+    { "server-hostname", SERVER_HOSTNAME },
+    { "boot-file-name", BOOT_FILE_NAME },
+
+    // DHCPv6 specific parameters.
+    { "data-directory", DATA_DIRECTORY },
+    { "preferred-lifetime", PREFERRED_LIFETIME },
+    { "min-preferred-lifetime", MIN_PREFERRED_LIFETIME },
+    { "max-preferred-lifetime", MAX_PREFERRED_LIFETIME },
+    { "subnet6", SUBNET6 },
+    { "mac-sources", MAC_SOURCES },
+    { "relay-supplied-options", RELAY_SUPPLIED_OPTIONS },
+    { "server-id", SERVER_ID }
+};
+
+// Load time sanity check.
+namespace {
+struct CfgGlobalsChecks {
+    CfgGlobalsChecks() {
+        // Check the size for missing entries.
+        if (CfgGlobals::nameToIndex.size() != CfgGlobals::SIZE) {
+            isc_throw(Unexpected, "CfgGlobals::nameToIndex has "
+                      << CfgGlobals::nameToIndex.size()
+                      << " elements (expected " << CfgGlobals::SIZE << ")");
+        }
+
+        // Build the name vector.
+        std::vector<std::string> names;
+        names.resize(CfgGlobals::SIZE);
+        for (auto it = CfgGlobals::nameToIndex.cbegin();
+             it != CfgGlobals::nameToIndex.cend(); ++it) {
+            int idx = it->second;
+            if ((idx < 0) || (idx > CfgGlobals::MAX_INDEX)) {
+                isc_throw(Unexpected, "invalid index " << idx
+                          << " for name " << it->first);
+            }
+            if (!names[idx].empty()) {
+                isc_throw(Unexpected, "duplicated names for " << idx
+                          << " got " << names[idx]);
+            }
+            names[idx] = it->first;
+        }
+
+        // No name should be empty.
+        for (int idx = 0; idx <= CfgGlobals::MAX_INDEX; ++idx) {
+            if (names[idx].empty()) {
+                isc_throw(Unexpected, "missing name for " << idx);
+            }
+        }
+    }
+};
+
+CfgGlobalsChecks check;
+} // end of anonymous namespace
+
+CfgGlobals::CfgGlobals() : values_(SIZE) {
+}
+
+ConstElementPtr
+CfgGlobals::get(const std::string& name) const {
+    auto const& it = nameToIndex.find(name);
+    if (it == nameToIndex.cend()) {
+        isc_throw(NotFound, "invalid global parameter name '" << name << "'");
+    }
+    return (get(it->second));
+}
+
+ConstElementPtr
+CfgGlobals::get(int index) const {
+    if ((index < 0) || (index > MAX_INDEX)) {
+        isc_throw(OutOfRange, "invalid global parameter index " << index);
+    }
+    return (values_[index]);
+}
+
+void
+CfgGlobals::set(const std::string& name, ConstElementPtr value) {
+    auto const& it = nameToIndex.find(name);
+    if (it == nameToIndex.cend()) {
+        isc_throw(NotFound, "invalid global parameter name '" << name << "'");
+    }
+    set(it->second, value);
+}
+
+void
+CfgGlobals::set(int index, ConstElementPtr value) {
+    if ((index < 0) || (index > MAX_INDEX)) {
+        isc_throw(OutOfRange, "invalid global parameter index " << index);
+    }
+    values_[index] = value;
+}
+
+void
+CfgGlobals::clear() {
+    for (int idx = 0; idx <= MAX_INDEX; ++idx) {
+        if (values_[idx]) {
+            values_[idx] = ConstElementPtr();
+        }
+    }
+}
+
+ElementPtr
+CfgGlobals::toElement() const {
+    ElementPtr result = Element::createMap();
+    for (auto it = nameToIndex.cbegin(); it != nameToIndex.cend(); ++it) {
+        int idx = it->second;
+        ConstElementPtr value = values_[idx];
+        if (value) {
+            result->set(it->first, value);
+        }
+    }
+    return (result);
+}
+
+} // namespace isc::dhcp
+} // namespace isc
diff --git a/src/lib/dhcpsrv/cfg_globals.h b/src/lib/dhcpsrv/cfg_globals.h
new file mode 100644 (file)
index 0000000..7c9d8aa
--- /dev/null
@@ -0,0 +1,179 @@
+// Copyright (C) 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/.
+
+#ifndef CFG_GLOBALS_H
+#define CFG_GLOBALS_H
+
+#include <cc/cfg_to_element.h>
+#include <cc/data.h>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief Class to store configured global parameters.
+///
+/// This class provides a direct access to a global parameter value
+/// using a vector as soon as the parameter name is known at compile
+/// time so in constant time vs in logarithm time using a map.
+class CfgGlobals : public isc::data::CfgToElement {
+public:
+
+    /// Class members.
+
+    /// @brief Enumeration of global parameters.
+    ///
+    /// The C++ compiler is required to start with 0 and to increment by 1
+    /// so gives an index.
+    ///
+    /// Names taken from @c SimpleParser4::GLOBAL4_PARAMETERS and
+    /// @c SimpleParser6::GLOBAL6_PARAMETERS, first part with common
+    /// parameters followed by DHCPv4 and DHCPv6 specific parameters.
+    /// Keep the order, enum element names is uppercase with - replaced by _.
+    enum Index : int {
+        // Common parameters.
+        VALID_LIFETIME,
+        MIN_VALID_LIFETIME,
+        MAX_VALID_LIFETIME,
+        RENEW_TIMER,
+        REBIND_TIMER,
+        DECLINE_PROBATION_PERIOD,
+        SHARED_NETWORKS,
+        INTERFACES_CONFIG,
+        LEASE_DATABASE,
+        HOSTS_DATABASE,
+        HOSTS_DATABASES,
+        HOST_RESERVATION_IDENTIFIERS,
+        CLIENT_CLASSES,
+        OPTION_DEF,
+        OPTION_DATA,
+        HOOKS_LIBRARIES,
+        EXPIRED_LEASES_PROCESSING,
+        DHCP4O6_PORT,
+        CONTROL_SOCKET,
+        DHCP_QUEUE_CONTROL,
+        DHCP_DDNS,
+        USER_CONTEXT,
+        COMMENT,
+        SANITY_CHECKS,
+        RESERVATIONS,
+        CONFIG_CONTROL,
+        SERVER_TAG,
+        RESERVATION_MODE,
+        RESERVATIONS_GLOBAL,
+        RESERVATIONS_IN_SUBNET,
+        RESERVATIONS_OUT_OF_POOL,
+        CALCULATE_TEE_TIMES,
+        T1_PERCENT,
+        T2_PERCENT,
+        LOGGERS,
+        HOSTNAME_CHAR_SET,
+        HOSTNAME_CHAR_REPLACEMENT,
+        DDNS_SEND_UPDATES,
+        DDNS_OVERRIDE_NO_UPDATE,
+        DDNS_OVERRIDE_CLIENT_UPDATE,
+        DDNS_REPLACE_CLIENT_NAME,
+        DDNS_GENERATED_PREFIX,
+        DDNS_QUALIFYING_SUFFIX,
+        STORE_EXTENDED_INFO,
+        STATISTIC_DEFAULT_SAMPLE_COUNT,
+        STATISTIC_DEFAULT_SAMPLE_AGE,
+        MULTI_THREADING,
+        CACHE_THRESHOLD,
+        CACHE_MAX_AGE,
+        IP_RESERVATIONS_UNIQUE,
+        DDNS_UPDATE_ON_RENEW,
+        DDNS_USE_CONFLICT_RESOLUTION,
+
+        // DHCPv4 specific parameters.
+        SUBNET4,
+        ECHO_CLIENT_ID,
+        MATCH_CLIENT_ID,
+        AUTHORITATIVE,
+        NEXT_SERVER,
+        SERVER_HOSTNAME,
+        BOOT_FILE_NAME,
+
+        // DHCPv6 specific parameters.
+        DATA_DIRECTORY,
+        PREFERRED_LIFETIME,
+        MIN_PREFERRED_LIFETIME,
+        MAX_PREFERRED_LIFETIME,
+        SUBNET6,
+        MAC_SOURCES,
+        RELAY_SUPPLIED_OPTIONS,
+        SERVER_ID
+    };
+
+    /// @brief Last index.
+    ///
+    /// @note: please update when a new element is appended to the Index enum.
+    static const int MAX_INDEX = SERVER_ID;
+
+    /// @brief Size of configured global objects.
+    static const size_t SIZE = MAX_INDEX + 1;
+
+    /// @brief Name to index map.
+    static const std::map<std::string, int> nameToIndex;
+
+    /// Instance members.
+
+    /// Constructor.
+    ///
+    /// Create a vector of null values.
+    CfgGlobals();
+
+    /// @brief Get a configured parameter value by name.
+    ///
+    /// @param name Name of the global parameter.
+    /// @return The value of the global parameter with the given name.
+    /// @throw NotFound if no global parameter has the given name.
+    isc::data::ConstElementPtr get(const std::string& name) const;
+
+    /// @brief Get a configured parameter value by index.
+    ///
+    /// @param index Index of the global parameter.
+    /// @return The value of the global parameter with the index.
+    /// @throw OutOfRange if the index is out of bounds.
+    isc::data::ConstElementPtr get(int index) const;
+
+    /// @brief Set a configured parameter value by name.
+    ///
+    /// @param name Name of the global parameter.
+    /// @param value Value of the configured parameter to set.
+    /// @throw NotFound if no global parameter has the given name.
+    void set(const std::string& name, isc::data::ConstElementPtr value);
+
+    /// @brief Set a configured parameter value by index.
+    ///
+    /// @param index Index of the global parameter.
+    /// @param value Value of the configured parameter to set.
+    /// @throw OutOfRange if the index is out of bounds.
+    void set(int index, isc::data::ConstElementPtr value);
+
+    /// @brief Clear configured parameter values.
+    void clear();
+
+    /// @brief Unparse configured globals.
+    ///
+    /// @return a pointer to unparsed globals.
+    isc::data::ElementPtr toElement() const;
+
+protected:
+    /// @brief Vectors of values.
+    std::vector<isc::data::ConstElementPtr> values_;
+};
+
+/// @brief Shared pointer to a CfgGlobals instance.
+typedef boost::shared_ptr<CfgGlobals> CfgGlobalsPtr;
+
+} // namespace isc::dhcp
+} // namespace isc
+
+#endif // CFG_GLOBALS_H