const IOAddress& hint,
bool fake_allocation /* = false */ ) {
- // That check is not necessary. We create allocator in AllocEngine
- // constructor
+ // Allocator is always created in AllocEngine constructor and there is
+ // currently no other way to set it, so that check is not really necessary.
if (!allocator_) {
isc_throw(InvalidOperation, "No allocator selected");
}
- // check if there's existing lease for that subnet/clientid/hwaddr combination.
+ // Check if there's existing lease for that subnet/clientid/hwaddr combination.
Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(hwaddr->hwaddr_, subnet->getID());
if (existing) {
- // we have a lease already. This is a returning client, probably after
- // his reboot.
-
+ // We have a lease already. This is a returning client, probably after
+ // its reboot.
existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
-
if (existing) {
return (existing);
}
// If renewal failed (e.g. the lease no longer matches current configuration)
- // let's continue allocation process
+ // let's continue the allocation process
}
if (clientid) {
existing = LeaseMgrFactory::instance().getLease4(*clientid, subnet->getID());
if (existing) {
// we have a lease already. This is a returning client, probably after
- // his reboot.
-
+ // its reboot.
existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
-
// @todo: produce a warning. We haven't found him using MAC address, but
// we found him using client-id
if (existing) {
if (subnet->inPool(hint)) {
existing = LeaseMgrFactory::instance().getLease4(hint);
if (!existing) {
- /// @todo: check if the hint is reserved once we have host support
+ /// @todo: Check if the hint is reserved once we have host support
/// implemented
- // the hint is valid and not currently used, let's create a lease for it
+ // The hint is valid and not currently used, let's create a lease for it
Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, hint, fake_allocation);
// It can happen that the lease allocation failed (we could have lost
// the following occurs:
// - we find a free address
// - we find an address for which the lease has expired
- // - we exhaust number of tries
+ // - we exhaust the number of tries
//
// @todo: Current code does not handle pool exhaustion well. It will be
// improved. Current problems:
}
}
- // continue trying allocation until we run out of attempts
+ // Continue trying allocation until we run out of attempts
// (or attempts are set to 0, which means infinite)
--i;
} while ( i || !attempts_);
if (!fake_allocation) {
// That is a real (REQUEST) allocation
bool status = LeaseMgrFactory::instance().addLease(lease);
-
if (status) {
return (lease);
} else {
}
}
-
AllocEngine::~AllocEngine() {
// no need to delete allocator. smart_ptr will do the trick for us
}
/// 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.
+ ///
+ /// @param subnet next address will be returned from pool of that subnet
+ /// @param duid Client's DUID
+ /// @param hint client's hint
+ ///
+ /// @return the next address
virtual isc::asiolink::IOAddress
pickAddress(const SubnetPtr& subnet, const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0;
/// @brief Renews a IPv4 lease
///
- /// Since both request and renew are implemented in DHCPv4 as sending
- /// REQUEST packet, it is difficult to easily distinguish between those
- /// cases. Therefore renew for DHCPv4 is done in allocation engine.
+ /// Since both request and renew are implemented in DHCPv4 as the sending of
+ /// a REQUEST packet, it is difficult to easily distinguish between those
+ /// cases. Therefore renew for DHCPv4 is done in the allocation engine.
/// This method is also used when client crashed/rebooted and tries
/// to get a new lease. It thinks that it gets a new lease, but in fact
- /// we are only renewing still valid lease for that client.
+ /// we are only renewing the still valid lease for that client.
///
/// @param subnet subnet the client is attached to
/// @param clientid client identifier
virtual ~AllocEngine();
private:
- /// @brief creates a lease and inserts it in LeaseMgr if necessary
+ /// @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
+ /// into the database. That may fail in some cases, e.g. when there is another
/// allocation process and we lost a race to a specific lease.
///
/// @param subnet subnet the lease is allocated from
uint32_t iaid, const isc::asiolink::IOAddress& addr,
bool fake_allocation = false);
- /// @brief reuses expired IPv4 lease
+ /// @brief Reuses expired IPv4 lease
///
/// Updates existing expired lease with new information. Lease database
/// is updated if this is real (i.e. REQUEST, fake_allocation = false), not
const HWAddrPtr& hwaddr,
bool fake_allocation = false);
- /// @brief reuses expired IPv6 lease
+ /// @brief Reuses expired IPv6 lease
///
/// Updates existing expired lease with new information. Lease database
/// is updated if this is real (i.e. REQUEST, fake_allocation = false), not
#include <iostream>
#include <sstream>
-#include <map>
+#include <set>
#include <time.h>
using namespace std;
namespace {
+/// @brief Allocation engine with some internal methods exposed
class NakedAllocEngine : public AllocEngine {
public:
+
+ /// @brief the sole constructor
+ /// @param engine_type specifies engine type (e.g. iterative)
+ /// @param attempts number of lease selection attempts before giving up
NakedAllocEngine(AllocEngine::AllocType engine_type, unsigned int attempts)
:AllocEngine(engine_type, attempts) {
}
+
+ // Expose internal classes for testing purposes
using AllocEngine::Allocator;
using AllocEngine::IterativeAllocator;
};
+/// @brief Used in Allocation Engine tests for IPv6
class AllocEngine6Test : public ::testing::Test {
public:
+
+ /// @brief Default constructor
+ ///
+ /// Sets duid_, iaid_, subnet_, pool_ fields to example values used
+ /// in many tests, initializes cfg_mgr configuration and creates
+ /// lease database.
AllocEngine6Test() {
duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
iaid_ = 42;
factory_.create("type=memfile");
}
+ /// @brief checks if Lease6 matches expected configuration
+ ///
+ /// @param lease lease to be checked
void checkLease6(const Lease6Ptr& lease) {
// that is belongs to the right subnet
EXPECT_EQ(lease->subnet_id_, subnet_->getID());
factory_.destroy();
}
- DuidPtr duid_;
- uint32_t iaid_;
- Subnet6Ptr subnet_;
- Pool6Ptr pool_;
- LeaseMgrFactory factory_;
+ DuidPtr duid_; ///< client-identifier (value used in tests)
+ uint32_t iaid_; ///< IA identifier (value used in tests)
+ Subnet6Ptr subnet_; ///< subnet6 (used in tests)
+ Pool6Ptr pool_; ///< pool belonging to subnet_
+ LeaseMgrFactory factory_; ///< pointer to LeaseMgr factory
};
+/// @brief Used in Allocation Engine tests for IPv4
class AllocEngine4Test : public ::testing::Test {
public:
+
+ /// @brief Default constructor
+ ///
+ /// Sets clientid_, hwaddr_, subnet_, pool_ fields to example values
+ /// used in many tests, initializes cfg_mgr configuration and creates
+ /// lease database.
AllocEngine4Test() {
clientid_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, 0x44)));
static uint8_t mac[] = { 0, 1, 22, 33, 44, 55};
factory_.create("type=memfile");
}
+ /// @brief checks if Lease4 matches expected configuration
+ ///
+ /// @param lease lease to be checked
void checkLease4(const Lease4Ptr& lease) {
// that is belongs to the right subnet
EXPECT_EQ(lease->subnet_id_, subnet_->getID());
factory_.destroy();
}
- ClientIdPtr clientid_;
- HWAddrPtr hwaddr_;
- Subnet4Ptr subnet_;
- Pool4Ptr pool_;
- LeaseMgrFactory factory_;
+ ClientIdPtr clientid_; ///< client-identifier (value used in tests)
+ HWAddrPtr hwaddr_; ///< hardware address (value used in tests)
+ Subnet4Ptr subnet_; ///< subnet4 (used in tests)
+ Pool4Ptr pool_; ///< pool belonging to subnet_
+ LeaseMgrFactory factory_; ///< pointer to LeaseMgr factory
};
// This test checks if the Allocation Engine can be instantiated and that it
// there are 8 extra pools with 9 addresses in each.
// Let's keep picked addresses here and check their uniqueness.
- std::map<IOAddress, int> generated_addrs;
+ std::set<IOAddress> generated_addrs;
int cnt = 0;
while (++cnt) {
IOAddress candidate = alloc->pickAddress(subnet_, duid_, IOAddress("::"));
if (generated_addrs.find(candidate) == generated_addrs.end()) {
// we haven't had this
- generated_addrs[candidate] = 0;
+ generated_addrs.insert(candidate);
} else {
// we have seen this address before. That should mean that we
// iterated over all addresses.
Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
IOAddress("0.0.0.0"), false);
- // check that we got a lease
+ // Check that we got a lease
ASSERT_TRUE(lease);
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is indeed in LeaseMgr
Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
IOAddress("0.0.0.0"), true);
- // check that we got a lease
+ // Check that we got a lease
ASSERT_TRUE(lease);
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is NOT in LeaseMgr
IOAddress("192.0.2.105"),
false);
- // check that we got a lease
+ // Check that we got a lease
ASSERT_TRUE(lease);
- // we should get what we asked for
+ // We should get what we asked for
EXPECT_EQ(lease->addr_.toText(), "192.0.2.105");
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is indeed in LeaseMgr
ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_TRUE(engine);
- // let's create a lease and put it in the LeaseMgr
+ // Let's create a lease and put it in the LeaseMgr
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
time_t now = time(NULL);
clientid2, sizeof(clientid2), 1, 2, 3, now, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
- // another client comes in and request an address that is in pool, but
+ // Another client comes in and request an address that is in pool, but
// unfortunately it is used already. The same address must not be allocated
// twice.
Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
IOAddress("192.0.2.106"),
false);
- // check that we got a lease
+ // Check that we got a lease
ASSERT_TRUE(lease);
- // allocated address must be different
+ // Allocated address must be different
EXPECT_TRUE(used->addr_.toText() != lease->addr_.toText());
- // we should NOT get what we asked for, because it is used already
+ // We should NOT get what we asked for, because it is used already
EXPECT_TRUE(lease->addr_.toText() != "192.0.2.106");
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is indeed in LeaseMgr
Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
IOAddress("10.1.1.1"),
false);
- // check that we got a lease
+ // Check that we got a lease
ASSERT_TRUE(lease);
- // we should NOT get what we asked for, because it is used already
+ // We should NOT get what we asked for, because it is used already
EXPECT_TRUE(lease->addr_.toText() != "10.1.1.1");
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is indeed in LeaseMgr
TEST_F(AllocEngine4Test, IterativeAllocator_manyPools4) {
NakedAllocEngine::IterativeAllocator* alloc = new NakedAllocEngine::IterativeAllocator();
- // let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
+ // Let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
for (int i = 2; i < 10; ++i) {
stringstream min, max;
- min << "192.0.2." << i*10 + 1;
- max << "192.0.2." << i*10 + 9;
+ min << "192.0.2." << i * 10 + 1;
+ max << "192.0.2." << i * 10 + 9;
Pool4Ptr pool(new Pool4(IOAddress(min.str()),
IOAddress(max.str())));
subnet_->addPool(pool);
}
- int total = 10 + 8*9; // first pool (.100 - .109) has 10 addresses in it,
- // there are 8 extra pools with 9 addresses in each.
+ int total = 10 + 8 * 9; // first pool (.100 - .109) has 10 addresses in it,
+ // there are 8 extra pools with 9 addresses in each.
// Let's keep picked addresses here and check their uniqueness.
- std::map<IOAddress, int> generated_addrs;
+ std::set<IOAddress> generated_addrs;
int cnt = 0;
while (++cnt) {
IOAddress candidate = alloc->pickAddress(subnet_, clientid_, IOAddress("0.0.0.0"));
// cout << candidate.toText() << endl;
if (generated_addrs.find(candidate) == generated_addrs.end()) {
- // we haven't had this
- generated_addrs[candidate] = 0;
+ // We haven't had this
+ generated_addrs.insert(candidate);
} else {
// we have seen this address before. That should mean that we
// iterated over all addresses.
EXPECT_EQ("192.0.2.17", lease->addr_.toText());
- // do all checks on the lease
+ // Do all checks on the lease
checkLease4(lease);
// Check that the lease is indeed in LeaseMgr
time_t now = time(NULL) - 500; // Allocated 500 seconds ago
Lease4Ptr lease(new Lease4(addr, clientid2, sizeof(clientid2), hwaddr2, sizeof(hwaddr2),
495, 100, 200, now, subnet_->getID()));
- // lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
+ // Lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
// is expired already
ASSERT_TRUE(lease->expired());
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
old_timestamp, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
- // lease was assigned 45 seconds ago and is valid for 100 seconds. Let's
+ // Lease was assigned 45 seconds ago and is valid for 100 seconds. Let's
// renew it.
ASSERT_FALSE(lease->expired());
lease = engine->renewLease4(subnet_, clientid_, hwaddr_, lease, false);