]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1256] Protected subnet last allocated
authorFrancis Dupont <fdupont@isc.org>
Fri, 29 May 2020 12:49:00 +0000 (14:49 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 12 Jun 2020 14:57:32 +0000 (16:57 +0200)
src/lib/dhcpsrv/subnet.cc
src/lib/dhcpsrv/subnet.h

index e3c3c0ae226c503fd7ebf4d38b3274ac5cab82d4..7a54538f38950635e99782272e7b937089802acc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-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
@@ -11,6 +11,7 @@
 #include <dhcp/option_space.h>
 #include <dhcpsrv/shared_network.h>
 #include <dhcpsrv/subnet.h>
+#include <util/multi_threading_mgr.h>
 #include <boost/lexical_cast.hpp>
 #include <boost/make_shared.hpp>
 #include <algorithm>
@@ -62,7 +63,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
       last_allocated_pd_(lastAddrInPrefix(prefix, len)),
       last_allocated_time_(),
       iface_(),
-      shared_network_name_() {
+      shared_network_name_(),
+      mutex_() {
     if ((prefix.isV6() && len > 128) ||
         (prefix.isV4() && len > 32)) {
         isc_throw(BadValue,
@@ -74,6 +76,8 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
     last_allocated_time_[Lease::TYPE_NA] = boost::posix_time::neg_infin;
     last_allocated_time_[Lease::TYPE_TA] = boost::posix_time::neg_infin;
     last_allocated_time_[Lease::TYPE_PD] = boost::posix_time::neg_infin;
+
+    mutex_.reset(new std::mutex);
 }
 
 bool
@@ -85,6 +89,15 @@ Subnet::inRange(const isc::asiolink::IOAddress& addr) const {
 }
 
 isc::asiolink::IOAddress Subnet::getLastAllocated(Lease::Type type) const {
+    if (MultiThreadingMgr::instance().getMode()) {
+        std::lock_guard<std::mutex> lock(*mutex_);
+        return (getLastAllocatedInternal(type));
+    } else {
+        return (getLastAllocatedInternal(type));
+    }
+}
+
+isc::asiolink::IOAddress Subnet::getLastAllocatedInternal(Lease::Type type) const {
     // check if the type is valid (and throw if it isn't)
     checkType(type);
 
@@ -103,6 +116,16 @@ isc::asiolink::IOAddress Subnet::getLastAllocated(Lease::Type type) const {
 
 boost::posix_time::ptime
 Subnet::getLastAllocatedTime(const Lease::Type& lease_type) const {
+    if (MultiThreadingMgr::instance().getMode()) {
+        std::lock_guard<std::mutex> lock(*mutex_);
+        return (getLastAllocatedTimeInternal(lease_type));
+    } else {
+        return (getLastAllocatedTimeInternal(lease_type));
+    }
+}
+
+boost::posix_time::ptime
+Subnet::getLastAllocatedTimeInternal(const Lease::Type& lease_type) const {
     auto t = last_allocated_time_.find(lease_type);
     if (t != last_allocated_time_.end()) {
         return (t->second);
@@ -113,9 +136,18 @@ Subnet::getLastAllocatedTime(const Lease::Type& lease_type) const {
     return (boost::posix_time::neg_infin);
 }
 
-
 void Subnet::setLastAllocated(Lease::Type type,
                               const isc::asiolink::IOAddress& addr) {
+    if (MultiThreadingMgr::instance().getMode()) {
+        std::lock_guard<std::mutex> lock(*mutex_);
+        setLastAllocatedInternal(type, addr);
+    } else {
+        setLastAllocatedInternal(type, addr);
+    }
+}
+
+void Subnet::setLastAllocatedInternal(Lease::Type type,
+                                      const isc::asiolink::IOAddress& addr) {
 
     // check if the type is valid (and throw if it isn't)
     checkType(type);
@@ -779,6 +811,5 @@ Subnet6::parsePrefix(const std::string& prefix) {
     return (parsed);
 }
 
-
 } // end of isc::dhcp namespace
 } // end of isc namespace
index 650b83f8dd3810c31b19bab3457e9332d3c947b7..94f4d17a03ecab105c4151e82094d18dd6944b21 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-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
 #include <boost/multi_index_container.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/pointer_cast.hpp>
+#include <boost/scoped_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <cstdint>
 #include <map>
+#include <mutex>
 #include <utility>
 
 namespace isc {
@@ -72,6 +74,8 @@ public:
     /// from this subnet. This is used as helper information for the next
     /// iteration of the allocation algorithm.
     ///
+    /// @note: this routine is Kea thread safe.
+    ///
     /// @todo: Define map<SubnetID, ClientClass, IOAddress> somewhere in the
     ///        AllocEngine::IterativeAllocator and keep the data there
     ///
@@ -82,6 +86,8 @@ public:
     /// @brief Returns the timestamp when the @c setLastAllocated function
     /// was called.
     ///
+    /// @note: this routine is Kea thread safe.
+    ///
     /// @param lease_type Lease type for which last allocation timestamp should
     /// be returned.
     ///
@@ -96,6 +102,8 @@ public:
     /// from this subnet. This is used as helper information for the next
     /// iteration of the allocation algorithm.
     ///
+    /// @note: this routine is Kea thread safe.
+    ///
     /// @todo: Define map<SubnetID, ClientClass, IOAddress> somewhere in the
     ///        AllocEngine::IterativeAllocator and keep the data there
     /// @param addr address/prefix to that was tried last
@@ -430,6 +438,8 @@ protected:
 
     /// @brief Timestamp indicating when a lease of a specified type has been
     /// last allocated from this subnet.
+    ///
+    /// @note: This map is protected by the mutex.
     std::map<Lease::Type, boost::posix_time::ptime> last_allocated_time_;
 
     /// @brief Name of the network interface (if connected directly)
@@ -437,6 +447,51 @@ protected:
 
     /// @brief Shared network name.
     std::string shared_network_name_;
+
+private:
+
+    /// @brief returns the last address that was tried from this subnet
+    ///
+    /// This method returns the last address that was attempted to be allocated
+    /// from this subnet. This is used as helper information for the next
+    /// iteration of the allocation algorithm.
+    ///
+     /// @todo: Define map<SubnetID, ClientClass, IOAddress> somewhere in the
+    ///        AllocEngine::IterativeAllocator and keep the data there
+    ///
+    /// @param type lease type to be returned
+    /// @return address/prefix that was last tried from this subnet
+    isc::asiolink::IOAddress getLastAllocatedInternal(Lease::Type type) const;
+
+    /// @brief Returns the timestamp when the @c setLastAllocated function
+    /// was called.
+    ///
+    /// @param lease_type Lease type for which last allocation timestamp should
+    /// be returned.
+    ///
+    /// @return Time when a lease of a specified type has been allocated from
+    /// this subnet. The negative infinity time is returned if a lease type is
+    /// not recognized (which is unlikely).
+    boost::posix_time::ptime
+    getLastAllocatedTimeInternal(const Lease::Type& lease_type) const;
+
+    /// @brief sets the last address that was tried from this subnet
+    ///
+    /// This method sets the last address that was attempted to be allocated
+    /// from this subnet. This is used as helper information for the next
+    /// iteration of the allocation algorithm.
+    ///
+    /// @note: this routine is Kea thread safe.
+    ///
+    /// @todo: Define map<SubnetID, ClientClass, IOAddress> somewhere in the
+    ///        AllocEngine::IterativeAllocator and keep the data there
+    /// @param addr address/prefix to that was tried last
+    /// @param type lease type to be set
+    void setLastAllocatedInternal(Lease::Type type,
+                                  const isc::asiolink::IOAddress& addr);
+
+    /// @brief The mutex protecting the last_allocated_time_ map.
+    boost::scoped_ptr<std::mutex> mutex_;
 };
 
 /// @brief A generic pointer to either Subnet4 or Subnet6 object