16#include <unordered_set>
25const string FLQ_OWNER =
"flq";
34 generator_.seed(rd());
38FreeLeaseQueueAllocator::pickAddressInternal(
const ClientClasses& client_classes,
42 auto const& pools = subnet->getPools(
pool_type_);
49 std::vector<uint64_t> available;
50 for (
auto i = 0; i < pools.size(); ++i) {
52 if (pools[i]->clientSupported(client_classes)) {
54 auto pool_state = getPoolState(pools[i]);
55 if (!pool_state->exhausted()) {
57 available.push_back(i);
61 if (available.empty()) {
66 auto const& pool = pools[available[getRandomNumber(available.size() - 1)]];
69 auto pool_state = getPoolState(pool);
72 auto free_lease = pool_state->offerFreeLease();
74 if (!free_lease.isV4Zero() && !free_lease.isV6Zero()) {
82FreeLeaseQueueAllocator::pickPrefixInternal(
const ClientClasses& client_classes,
85 PrefixLenMatchType prefix_length_match,
87 uint8_t hint_prefix_length) {
89 auto const& pools = subnet->getPools(
pool_type_);
96 std::vector<uint64_t> available;
97 for (
auto i = 0; i < pools.size(); ++i) {
99 if (pools[i]->clientSupported(client_classes)) {
101 hint_prefix_length)) {
105 auto pool_state = getPoolState(pools[i]);
106 if (!pool_state->exhausted()) {
108 available.push_back(i);
112 if (available.empty()) {
117 auto const& pool = pools[available[getRandomNumber(available.size() - 1)]];
118 pool6 = boost::dynamic_pointer_cast<Pool6>(pool);
126 auto pool_state = getPoolState(pool);
128 auto free_lease = pool_state->offerFreeLease();
130 if (!free_lease.isV6Zero()) {
138FreeLeaseQueueAllocator::initAfterConfigureInternal() {
140 auto const& pools = subnet->getPools(
pool_type_);
150 populateFreeAddressLeases(leases4, pools);
155 populateFreeAddressLeases(leases6, pools);
159 populateFreePrefixDelegationLeases(leases6, pools);
168 std::bind(&FreeLeaseQueueAllocator::addLeaseCallback,
this,
169 std::placeholders::_1));
171 std::bind(&FreeLeaseQueueAllocator::updateLeaseCallback,
this,
172 std::placeholders::_1));
174 std::bind(&FreeLeaseQueueAllocator::deleteLeaseCallback,
this,
175 std::placeholders::_1));
178template<
typename LeaseCollectionType>
180FreeLeaseQueueAllocator::populateFreeAddressLeases(
const LeaseCollectionType& leases,
184 .arg(subnet->toText());
191 unordered_set<IOAddress, IOAddress::Hash> leased_addresses;
192 for (
auto const& lease : leases) {
193 if ((lease->getType() ==
pool_type_) && (!lease->expired()) && (!lease->stateExpiredReclaimed())) {
194 leased_addresses.insert(lease->addr_);
198 size_t free_lease_count = 0;
199 for (
auto const& pool : pools) {
202 IPRangePermutation perm(AddressRange(pool->getFirstAddress(), pool->getLastAddress()));
203 auto pool_state = getPoolState(pool);
206 auto address = perm.next(done);
207 if (address.isV4Zero() || address.isV6Zero()) {
210 if (leased_addresses.count(address) == 0) {
212 pool_state->addFreeLease(address);
215 free_lease_count += pool_state->getFreeLeaseCount();
221 .arg(free_lease_count)
222 .arg(subnet->toText())
223 .arg(stopwatch.logFormatLastDuration());
227FreeLeaseQueueAllocator::populateFreePrefixDelegationLeases(
const Lease6Collection& leases,
231 .arg(subnet->toText());
238 unordered_set<IOAddress, IOAddress::Hash> leased_prefixes;
239 for (
auto const& lease : leases) {
240 if ((lease->getType() ==
Lease::TYPE_PD) && (!lease->expired()) && (!lease->stateExpiredReclaimed())) {
241 leased_prefixes.insert(lease->addr_);
245 size_t free_lease_count = 0;
246 for (
auto const& pool : pools) {
247 auto pool6 = boost::dynamic_pointer_cast<Pool6>(pool);
253 IPRangePermutation perm(PrefixRange(pool->getFirstAddress(),
254 pool->getLastAddress(),
255 pool6->getLength()));
256 auto pool_state = getPoolState(pool);
259 auto prefix = perm.next(done);
260 if (prefix.isV4Zero() || prefix.isV6Zero()) {
263 if (leased_prefixes.count(prefix) == 0) {
265 pool_state->addFreeLease(prefix);
268 free_lease_count += pool_state->getFreeLeaseCount();
274 .arg(free_lease_count)
275 .arg(subnet->toText())
276 .arg(stopwatch.logFormatLastDuration());
280FreeLeaseQueueAllocator::getPoolState(
const PoolPtr& pool)
const {
281 if (!pool->getAllocationState()) {
284 return (boost::dynamic_pointer_cast<PoolFreeLeaseQueueAllocationState>(pool->getAllocationState()));
288FreeLeaseQueueAllocator::getLeasePool(
const LeasePtr& lease)
const {
293 auto pool = subnet->getPool(
pool_type_, lease->addr_,
false);
298FreeLeaseQueueAllocator::addLeaseCallback(
LeasePtr lease) {
300 addLeaseCallbackInternal(lease);
304FreeLeaseQueueAllocator::addLeaseCallbackInternal(
LeasePtr lease) {
305 if (lease->expired()) {
308 auto pool = getLeasePool(lease);
312 getPoolState(pool)->deleteFreeLease(lease->addr_);
316FreeLeaseQueueAllocator::updateLeaseCallback(
LeasePtr lease) {
318 updateLeaseCallbackInternal(lease);
322FreeLeaseQueueAllocator::updateLeaseCallbackInternal(
LeasePtr lease) {
323 auto pool = getLeasePool(lease);
327 auto pool_state = getPoolState(pool);
328 if (lease->stateExpiredReclaimed() || (lease->expired())) {
329 pool_state->addFreeLease(lease->addr_);
331 pool_state->deleteFreeLease(lease->addr_);
336FreeLeaseQueueAllocator::deleteLeaseCallback(
LeasePtr lease) {
338 deleteLeaseCallbackInternal(lease);
342FreeLeaseQueueAllocator::deleteLeaseCallbackInternal(
LeasePtr lease) {
343 auto pool = getLeasePool(lease);
347 getPoolState(pool)->addFreeLease(lease->addr_);
351FreeLeaseQueueAllocator::getRandomNumber(uint64_t limit) {
356 std::uniform_int_distribution<uint64_t> dist(0, limit);
357 return (dist(generator_));
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
Base class for all address/prefix allocation algorithms.
Lease::Type pool_type_
Defines pool type allocation.
std::mutex mutex_
The mutex to protect the allocated lease.
WeakSubnetPtr subnet_
Weak pointer to the subnet owning the allocator.
static bool isValidPrefixPool(Allocator::PrefixLenMatchType prefix_length_match, PoolPtr pool, uint8_t hint_prefix_length)
Check if the pool matches the selection criteria relative to the provided hint prefix length.
Container for storing client class names.
FreeLeaseQueueAllocator(Lease::Type type, const WeakSubnetPtr &subnet)
Constructor.
static TrackingLeaseMgr & instance()
Return current lease manager.
static PoolFreeLeaseQueueAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from a pool.
Utility class to measure code execution times.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
boost::shared_ptr< PoolFreeLeaseQueueAllocationState > PoolFreeLeaseQueueAllocationStatePtr
Type of the pointer to the PoolFreeLeaseQueueAllocationState.
const isc::log::MessageID DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES
boost::weak_ptr< Subnet > WeakSubnetPtr
Weak pointer to the Subnet.
const isc::log::MessageID DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES_DONE
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
const isc::log::MessageID DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES_DONE
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
boost::shared_ptr< IdentifierBaseType > IdentifierBaseTypePtr
Shared pointer to a IdentifierType.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
Defines the logger used by the top-level component of kea-lfc.
Type
Type of lease or pool.
@ TYPE_TA
the lease contains temporary IPv6 address
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
RAII lock object to protect the code in the same scope with a mutex.