Commit cb330a06 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[2324] Documentation updated, {Hashed,Random}Allocator skeletons implemented.

parent 461164b5
......@@ -113,6 +113,32 @@ AllocEngine::IterativeAllocator::pickAddress(const Subnet6Ptr& subnet,
return (next);
}
AllocEngine::HashedAllocator::HashedAllocator()
:Allocator() {
isc_throw(NotImplemented, "Hashed allocator is not implemented");
}
isc::asiolink::IOAddress
AllocEngine::HashedAllocator::pickAddress(const Subnet6Ptr&,
const DuidPtr&,
const IOAddress&) {
isc_throw(NotImplemented, "Hashed allocator is not implemented");
}
AllocEngine::RandomAllocator::RandomAllocator()
:Allocator() {
isc_throw(NotImplemented, "Random allocator is not implemented");
}
isc::asiolink::IOAddress
AllocEngine::RandomAllocator::pickAddress(const Subnet6Ptr&,
const DuidPtr&,
const IOAddress&) {
isc_throw(NotImplemented, "Random allocator is not implemented");
}
AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
:attempts_(attempts) {
......@@ -120,14 +146,12 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
case ALLOC_ITERATIVE:
allocator_ = new IterativeAllocator();
break;
#if 0
case ALLOC_HASHED:
allocator_ = new HashedAllocator();
break;
case ALLOC_RANDOM:
allocator_ = new RandomAllocator();
break;
#endif
default:
isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
......
......@@ -44,51 +44,113 @@ AllocFailed(const char* file, size_t line, const char* what)
/// This class represents DHCP allocation engine. It is responsible
/// for picking subnets, choosing and allocating a lease, extending,
/// renewing, releasing and possibly expiring leases.
///
/// @todo: Does not handle out of leases well
/// @todo: Does not handle out of allocation attempts well
class AllocEngine : public boost::noncopyable {
protected:
/// @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.
class Allocator {
public:
/// @brief picks one address out of available pools in a given subnet
///
/// 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.
virtual isc::asiolink::IOAddress
pickAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0;
protected:
/// @brief protected constructor
///
/// Prevents anyone from attempting to instantiate Allocator objects
/// directly. Derived classes should be used instead.
Allocator() {
}
};
/// @brief Address/prefix allocator that iterates over all addresses
///
/// This class implements iterative algorithm that returns all addresses in
/// a pool iteratively, one after another.
class IterativeAllocator : public Allocator {
public:
/// @brief default constructor
///
/// Does not do anything
IterativeAllocator();
/// @brief returns the next address from pools in a subnet
///
/// @param subnet next address will be returned from pool of that subnet
/// @param duid Client's DUID (ignored)
/// @param hint client's hint (ignored)
/// @return the next address
virtual isc::asiolink::IOAddress
pickAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
private:
/// @brief returns an address by one
/// @param addr address to be increased
/// @return address increased by one
isc::asiolink::IOAddress increaseAddress(const isc::asiolink::IOAddress& addr);
};
#if 0
class HashedAllocator {
/// @brief Address/prefix allocator that gets an address based on a hash
///
/// @todo: This is a skeleton class for now and is missing implementation.
class HashedAllocator : public Allocator {
public:
IterativeAllocator(unsigned int attempts);
virtual isc::asiolink::IOAddress allocateAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const DUIOAddress& hint);
}
class RandomAllocator() {
/// @brief default constructor (does nothing)
HashedAllocator();
/// @brief returns an address based on hash calculated from client's DUID.
///
/// @todo: Implement this method
///
/// @param subnet an address will be picked from pool of that subnet
/// @param duid Client's DUID
/// @param hint a hint (last address that was picked)
/// @return selected address
virtual isc::asiolink::IOAddress pickAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
};
/// @brief Random allocator that picks address randomly
///
/// @todo: This is a skeleton class for now and is missing implementation.
class RandomAllocator : public Allocator {
public:
IterativeAllocator(unsigned int attempts);
/// @brief default constructor (does nothing)
RandomAllocator();
/// @brief returns an random address from pool of specified subnet
///
/// @todo: Implement this method
///
/// @param subnet an address will be picked from pool of that subnet
/// @param duid Client's DUID (ignored)
/// @param hint the last address that was picked (ignored)
/// @return a random address from the pool
virtual isc::asiolink::IOAddress
allocateAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const DUIOAddress& hint);
}
#endif
pickAddress(const Subnet6Ptr& subnet, const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
};
public:
......@@ -108,8 +170,22 @@ protected:
/// old or create new DUID.
///
/// @param engine_type selects allocation algorithm
/// @param attempts number of attempts for each lease allocation before
/// we give up (0 mean unlimited)
AllocEngine(AllocType engine_type, unsigned int attempts);
/// @brief Allocates an IPv6 lease
///
/// This method uses currently selected allocator to pick an address from
/// specified subnet, creates a lease for that address and then inserts
/// it into LeaseMgr (if this allocation is not fake).
///
/// @param subnet subnet the allocation should come from
/// @param duid Client'd DUID
/// @param iaid iaid field from the IA_NA container that client sent
/// @param hint a hint that the client provided
/// @param fake is this real (REQUEST) or fake (SOLICIT) allocation
/// @return Allocated IPv6 lease (or NULL if allocation failed)
Lease6Ptr
allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
......@@ -120,19 +196,28 @@ protected:
/// @brief Destructor. Used during DHCPv6 service shutdown.
virtual ~AllocEngine();
private:
isc::asiolink::IOAddress
allocateAddress(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const isc::asiolink::IOAddress& hint);
Lease6Ptr createLease(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
const isc::asiolink::IOAddress& addr,
/// @brief creates a lease and inserts it in LeaseMgr if necessary
///
/// Creates a lease based on specified parameters and tries to insert it
/// into the database. That may fail in some cases, i.e. when there is another
/// allocation process and we lost a race to a specific lease.
///
/// @param subnet subnet the lease is allocated from
/// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us
/// @param addr an address that was selected and is confirmed to be available
/// @param fake is this SOLICIT (true) or a real/REQUEST allocation (false)?
/// @return allocated lease (or NULL in the unlikely case of the lease just
/// becomed unavailable)
Lease6Ptr createLease(const Subnet6Ptr& subnet, const DuidPtr& duid,
uint32_t iaid, const isc::asiolink::IOAddress& addr,
bool fake = false);
/// @brief a pointer to currently used allocator
Allocator* allocator_;
/// @brief number of attempts before we give up lease allocation (0=unlimited)
unsigned int attempts_;
};
......
......@@ -96,8 +96,8 @@ TEST_F(AllocEngineTest, constructor) {
AllocEngine* x = NULL;
// Hashed and random allocators are not supported yet
ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_HASHED, 5), BadValue);
ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_RANDOM, 5), BadValue);
ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_HASHED, 5), NotImplemented);
ASSERT_THROW(x = new AllocEngine(AllocEngine::ALLOC_RANDOM, 5), NotImplemented);
ASSERT_NO_THROW(x = new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment