2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-22 18:08:16 +00:00
kea/src/lib/dhcpsrv/allocator.h

200 lines
7.1 KiB
C
Raw Normal View History

// Copyright (C) 2022 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 ALLOCATOR_H
#define ALLOCATOR_H
#include <asiolink/io_address.h>
#include <dhcp/classify.h>
#include <dhcp/duid.h>
#include <exceptions/exceptions.h>
2022-10-20 18:10:47 +02:00
#include <dhcpsrv/lease.h>
#include <dhcpsrv/pool.h>
#include <util/multi_threading_mgr.h>
#include <boost/shared_ptr.hpp>
2022-10-20 18:10:47 +02:00
#include <boost/weak_ptr.hpp>
#include <mutex>
namespace isc {
namespace dhcp {
2022-10-20 18:10:47 +02:00
/// @brief Forward declaration of a @c Subnet.
///
/// We don't include the subnet header because it would cause a
/// circular dependency.
class Subnet;
/// @brief Weak pointer to the @c Subnet.
typedef boost::weak_ptr<Subnet> WeakSubnetPtr;
/// An exception that is thrown when allocation module fails (e.g. due to
/// lack of available addresses)
class AllocFailed : public Exception {
public:
/// @brief Constructor
///
/// @param file name of the file, where exception occurred
/// @param line line of the file, where exception occurred
/// @param what text description of the issue that caused exception
AllocFailed(const char* file, size_t line, const char* what)
: Exception(file, line, what) {}
};
/// @brief Base class for all address/prefix allocation algorithms.
///
/// This is an abstract class that should not be used directly, but rather
/// specialized implementations should be used instead.
2022-10-20 18:10:47 +02:00
///
/// This class holds a weak pointer to the subnet owning it because
/// it must not exist without the subnet. Also, it can't hold a shared
/// pointer to the subnet because it would cause a circular dependency
/// between the two.
class Allocator {
public:
/// @brief Type of preferred PD-pool prefix length selection criteria
enum PrefixLenMatchType {
PREFIX_LEN_EQUAL, // select PD-pools with specific prefix length
PREFIX_LEN_SMALLER, // select PD-pools with smaller prefix length
PREFIX_LEN_GREATER // select PD-pools with greater prefix length
};
2022-10-20 18:10:47 +02:00
/// @brief Constructor
///
/// Specifies which type of leases this allocator will assign.
///
/// @param type specifies pool type (addresses, temporary addresses
/// or prefixes).
/// @param subnet weak pointer to the subnet owning the allocator.
Allocator(Lease::Type type, const WeakSubnetPtr& subnet)
: pool_type_(type),
subnet_(subnet) {
}
/// @brief Virtual destructor
virtual ~Allocator() = default;
2022-10-20 18:10:47 +02:00
/// @brief Picks an address.
///
/// This method returns one address from the available pools in the
/// specified subnet. It should not check if the address is used or
/// reserved - AllocEngine will check that and will call pickAddress
/// again if necessary. The number of times this method is called will
/// increase as the number of available leases will decrease.
///
/// Pools which are not allowed for client classes are skipped.
///
/// @param client_classes list of classes client belongs to
/// @param duid Client's DUID
/// @param hint Client's hint
///
/// @return the next address.
virtual isc::asiolink::IOAddress
2022-10-20 18:10:47 +02:00
pickAddress(const ClientClasses& client_classes,
const DuidPtr& duid,
const asiolink::IOAddress& hint) {
util::MultiThreadingLock lock(mutex_);
return (pickAddressInternal(client_classes, duid, hint));
}
/// @brief Picks a delegated prefix.
///
/// This method returns one prefix from the available pools in the
/// specified subnet. It should not check if the prefix is used or
/// reserved - AllocEngine will check that and will call pickPrefix
/// again if necessary. The number of times this method is called will
/// increase as the number of available leases will decrease.
///
/// Pools which are not allowed for client classes are skipped.
///
/// @param client_classes list of classes client belongs to
/// @param pool the selected pool satisfying all required conditions.
/// @param duid Client's DUID
/// @param prefix_length_match type which indicates the selection criteria
/// for the pools relative to the provided hint prefix length
/// @param hint Client's hint
/// @param hint_prefix_length the hint prefix length that the client
/// provided
///
/// @return the next prefix.
virtual isc::asiolink::IOAddress
pickPrefix(const ClientClasses& client_classes,
Pool6Ptr& pool,
const DuidPtr& duid,
PrefixLenMatchType prefix_length_match,
const asiolink::IOAddress& hint,
uint8_t hint_prefix_length) {
util::MultiThreadingLock lock(mutex_);
return (pickPrefixInternal(client_classes, pool, duid,
prefix_length_match, hint,
hint_prefix_length));
}
2022-10-20 18:10:47 +02:00
private:
/// @brief Picks an address.
2022-10-20 18:10:47 +02:00
///
/// Internal thread-unsafe implementation of the @c pickAddress.
/// Derived classes must provide their specific implementations of
/// this function.
///
/// @param client_classes list of classes client belongs to
/// @param duid Client's DUID
/// @param hint Client's hint
///
/// @return the next address.
virtual isc::asiolink::IOAddress
pickAddressInternal(const ClientClasses& client_classes,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0;
/// @brief Picks a delegated prefix.
///
/// Internal thread-unsafe implementation of the @c pickPrefix.
/// Derived classes must provide their specific implementations of
/// this function.
///
/// @param client_classes list of classes client belongs to
/// @param pool the selected pool satisfying all required conditions.
/// @param duid Client's DUID
/// @param prefix_length_match type which indicates the selection criteria
/// for the pools relative to the provided hint prefix length
/// @param hint Client's hint
/// @param hint_prefix_length the hint prefix length that the client
/// provided
///
/// @return the next prefix.
virtual isc::asiolink::IOAddress
pickPrefixInternal(const ClientClasses& client_classes,
Pool6Ptr& pool,
const DuidPtr& duid,
PrefixLenMatchType prefix_length_match,
const isc::asiolink::IOAddress& hint,
uint8_t hint_prefix_length) = 0;
2022-10-20 18:10:47 +02:00
protected:
2022-10-20 18:10:47 +02:00
/// @brief Defines pool type allocation
Lease::Type pool_type_;
2022-10-20 18:10:47 +02:00
/// @brief Weak pointer to the subnet owning the allocator.
WeakSubnetPtr subnet_;
2022-10-20 18:10:47 +02:00
private:
2022-10-20 18:10:47 +02:00
/// @brief The mutex to protect the allocated lease.
std::mutex mutex_;
};
2022-10-20 18:10:47 +02:00
/// Defines a pointer to an allocator.
typedef boost::shared_ptr<Allocator> AllocatorPtr;
} // end of namespace isc::dhcp
} // end of namespace isc
2022-10-20 18:10:47 +02:00
#endif // ALLOCATOR_H