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 (
unsigned 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 (
unsigned 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);
 
  121        isc_throw(Unexpected, 
"Wrong type of pool: " 
  126    auto pool_state = getPoolState(pool);
 
  128    auto free_lease = pool_state->offerFreeLease();
 
  130    if (!free_lease.isV6Zero()) {
 
  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())
 
  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())
 
  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) {
 
  299    MultiThreadingLock lock(
mutex_);
 
  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) {
 
  317    MultiThreadingLock lock(
mutex_);
 
  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) {
 
  337    MultiThreadingLock lock(
mutex_);
 
  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_));
 
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.
virtual void initAfterConfigureInternal()
Allocator-specific initialization function.
Lease::Type pool_type_
Defines pool type allocation.
std::mutex mutex_
The mutex to protect the allocated lease.
Allocator(Lease::Type type, const WeakSubnetPtr &subnet)
Constructor.
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.
virtual Lease6Collection getLeases6(Lease::Type type, const DUID &duid, uint32_t iaid) const =0
Returns existing IPv6 leases for a given DUID+IA combination.
virtual Lease4Collection getLeases4(SubnetID subnet_id) const =0
Returns all IPv4 leases for the particular subnet identifier.
static PoolFreeLeaseQueueAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from a pool.
void stop()
Stops the stopwatch.
std::string logFormatLastDuration() const
Returns the last measured duration in the format directly usable in log messages.
#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