From: Francis Dupont Date: Fri, 29 May 2020 12:49:00 +0000 (+0200) Subject: [#1256] Protected subnet last allocated X-Git-Tag: Kea-1.7.9~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72c6be772bf1a1a6fc94b7584e1f35dd52d9f3d4;p=thirdparty%2Fkea.git [#1256] Protected subnet last allocated --- diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc index e3c3c0ae22..7a54538f38 100644 --- a/src/lib/dhcpsrv/subnet.cc +++ b/src/lib/dhcpsrv/subnet.cc @@ -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 #include #include +#include #include #include #include @@ -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 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 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 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 diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h index 650b83f8dd..94f4d17a03 100644 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@ -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 @@ -23,9 +23,11 @@ #include #include #include +#include #include #include #include +#include #include 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 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 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 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 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 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 mutex_; }; /// @brief A generic pointer to either Subnet4 or Subnet6 object