BIND 10 master, updated. 8d8605b657d5e554f0c496143fe1a3b3cb8d3ea8 [master] Merge branch 'trac2327' (DHCPv6 lease expiration)
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Dec 19 11:29:51 UTC 2012
The branch, master has been updated
via 8d8605b657d5e554f0c496143fe1a3b3cb8d3ea8 (commit)
via 62a23854f619349d319d02c3a385d9bc55442d5e (commit)
via 89f2d7507297c5e3c1daf815f45e54499d029e27 (commit)
via 6f27e6fc9819b5807703ff141e31a0d7a6800a26 (commit)
via 95cc8210a2f620d6a2a886cf7577ed2d257d2bad (commit)
from ff7903d22a1cc553ff22f9a6047e590f14c7dd32 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 8d8605b657d5e554f0c496143fe1a3b3cb8d3ea8
Merge: ff7903d 62a2385
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Wed Dec 19 12:29:34 2012 +0100
[master] Merge branch 'trac2327' (DHCPv6 lease expiration)
Conflicts:
ChangeLog
src/lib/dhcpsrv/alloc_engine.cc
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 6 +
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 3 +
src/lib/dhcpsrv/alloc_engine.cc | 74 ++++++++-
src/lib/dhcpsrv/alloc_engine.h | 18 ++
src/lib/dhcpsrv/lease_mgr.cc | 8 +
src/lib/dhcpsrv/lease_mgr.h | 4 +
src/lib/dhcpsrv/memfile_lease_mgr.cc | 5 +-
src/lib/dhcpsrv/tests/Makefile.am | 1 +
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc | 184 ++++++++++++++++++---
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc | 27 ++-
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc | 44 +----
src/lib/dhcpsrv/tests/test_utils.cc | 58 +++++++
src/lib/dhcpsrv/tests/test_utils.h | 49 ++++++
13 files changed, 408 insertions(+), 73 deletions(-)
create mode 100644 src/lib/dhcpsrv/tests/test_utils.cc
create mode 100644 src/lib/dhcpsrv/tests/test_utils.h
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index a418708..977b6ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+531. [func] tomek
+ b10-dhcp6: Added support for expired leases. Leases for IPv6
+ addresses that are past their valid lifetime may be recycled, i.e.
+ rellocated to other clients if needed.
+ (Trac #2327, git 62a23854f619349d319d02c3a385d9bc55442d5e)
+
530. [func]* team
b10-loadzone was fully overhauled. It now uses C++-based zone
parser and loader library, performing stricter checks, having
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 040db35..4c02dde 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -575,6 +575,9 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
checkClientId(reply, clientid);
}
+/// @todo: Add a test that client sends hint that is in pool, but currently
+/// being used by a different client.
+
// This test checks that the server is offering different addresses to different
// clients in ADVERTISEs. Please note that ADVERTISE is not a guarantee that such
// and address will be assigned. Had the pool was very small and contained only
diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc
index 452343c..1c64c04 100644
--- a/src/lib/dhcpsrv/alloc_engine.cc
+++ b/src/lib/dhcpsrv/alloc_engine.cc
@@ -44,9 +44,10 @@ AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress&
// Copy the address. It can be either V4 or V6.
std::memcpy(packed, &vec[0], len);
- // Increase the address.
+ // Start increasing the least significant byte
for (int i = len - 1; i >= 0; --i) {
++packed[i];
+ // if we haven't overflowed (0xff -> 0x0), than we are done
if (packed[i] != 0) {
break;
}
@@ -198,9 +199,31 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
if (lease) {
return (lease);
}
+ } else {
+ if (existing->expired()) {
+ return (reuseExpiredLease(existing, subnet, duid, iaid,
+ fake_allocation));
+ }
+
}
}
+ // Hint is in the pool but is not available. Search the pool until first of
+ // the following occurs:
+ // - we find a free address
+ // - we find an address for which the lease has expired
+ // - we exhaust number of tries
+ //
+ // @todo: Current code does not handle pool exhaustion well. It will be
+ // improved. Current problems:
+ // 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
+ // 10 addresses), we will iterate over it 100 times before giving up
+ // 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
+ // 3. the whole concept of infinite attempts is just asking for infinite loop
+ // We may consider some form or reference counting (this pool has X addresses
+ // left), but this has one major problem. We exactly control allocation
+ // moment, but we currently do not control expiration time at all
+
unsigned int i = attempts_;
do {
IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
@@ -209,9 +232,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
/// implemented
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
- // there's no existing lease for selected candidate, so it is
- // free. Let's allocate it.
if (!existing) {
+ // there's no existing lease for selected candidate, so it is
+ // free. Let's allocate it.
Lease6Ptr lease = createLease(subnet, duid, iaid, candidate,
fake_allocation);
if (lease) {
@@ -221,6 +244,11 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// Although the address was free just microseconds ago, it may have
// been taken just now. If the lease insertion fails, we continue
// allocation attempts.
+ } else {
+ if (existing->expired()) {
+ return (reuseExpiredLease(existing, subnet, duid, iaid,
+ fake_allocation));
+ }
}
// continue trying allocation until we run out of attempts
@@ -232,6 +260,46 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
<< " tries");
}
+Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
+ const Subnet6Ptr& subnet,
+ const DuidPtr& duid,
+ uint32_t iaid,
+ bool fake_allocation /*= false */ ) {
+
+ if (!expired->expired()) {
+ isc_throw(BadValue, "Attempt to recycle lease that is still valid");
+ }
+
+ // address, lease type and prefixlen (0) stay the same
+ expired->iaid_ = iaid;
+ expired->duid_ = duid;
+ expired->preferred_lft_ = subnet->getPreferred();
+ expired->valid_lft_ = subnet->getValid();
+ expired->t1_ = subnet->getT1();
+ expired->t2_ = subnet->getT2();
+ expired->cltt_ = time(NULL);
+ expired->subnet_id_ = subnet->getID();
+ expired->fixed_ = false;
+ expired->hostname_ = std::string("");
+ expired->fqdn_fwd_ = false;
+ expired->fqdn_rev_ = false;
+
+ /// @todo: log here that the lease was reused (there's ticket #2524 for
+ /// logging in libdhcpsrv)
+
+ if (!fake_allocation) {
+ // for REQUEST we do update the lease
+ LeaseMgrFactory::instance().updateLease6(expired);
+ }
+
+ // We do nothing for SOLICIT. We'll just update database when
+ // the client gets back to us with REQUEST message.
+
+ // it's not really expired at this stage anymore - let's return it as
+ // an updated lease
+ return (expired);
+}
+
Lease6Ptr AllocEngine::createLease(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h
index 940b1f4..eab6e12 100644
--- a/src/lib/dhcpsrv/alloc_engine.h
+++ b/src/lib/dhcpsrv/alloc_engine.h
@@ -216,6 +216,24 @@ private:
uint32_t iaid, const isc::asiolink::IOAddress& addr,
bool fake_allocation = false);
+ /// @brief reuses expired lease
+ ///
+ /// Updates existing expired lease with new information. Lease database
+ /// is updated if this is real (i.e. REQUEST, fake_allocation = false), not
+ /// dummy allocation request (i.e. SOLICIT, fake_allocation = true).
+ ///
+ /// @param expired old, expired 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 fake_allocation is this real i.e. REQUEST (false) or just picking
+ /// an address for SOLICIT that is not really allocated (true)
+ /// @return refreshed lease
+ /// @throw BadValue if trying to recycle lease that is still valid
+ Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet,
+ const DuidPtr& duid, uint32_t iaid,
+ bool fake_allocation = false);
+
/// @brief a pointer to currently used allocator
boost::shared_ptr<Allocator> allocator_;
diff --git a/src/lib/dhcpsrv/lease_mgr.cc b/src/lib/dhcpsrv/lease_mgr.cc
index f7b6373..b3a605d 100644
--- a/src/lib/dhcpsrv/lease_mgr.cc
+++ b/src/lib/dhcpsrv/lease_mgr.cc
@@ -46,6 +46,14 @@ Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr,
cltt_ = time(NULL);
}
+bool Lease6::expired() const {
+
+ // Let's use int64 to avoid problems with negative/large uint32 values
+ int64_t expire_time = cltt_ + valid_lft_;
+ return (expire_time < time(NULL));
+}
+
+
std::string LeaseMgr::getParameter(const std::string& name) const {
ParameterMap::const_iterator param = parameters_.find(name);
if (param == parameters_.end()) {
diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h
index 7865e11..3fe11e6 100644
--- a/src/lib/dhcpsrv/lease_mgr.h
+++ b/src/lib/dhcpsrv/lease_mgr.h
@@ -379,6 +379,10 @@ struct Lease6 {
/// @return String form of the lease
std::string toText();
+ /// @brief returns true if the lease is expired
+ /// @return true if the lease is expired
+ bool expired() const;
+
/// @brief Compare two leases for equality
///
/// @param other lease6 object with which to compare
diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc
index b71b166..79cf1c7 100644
--- a/src/lib/dhcpsrv/memfile_lease_mgr.cc
+++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc
@@ -20,9 +20,8 @@ using namespace isc::dhcp;
Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
: LeaseMgr(parameters) {
- std::cout << "Warning: Using memfile database backend. It is usable for" << std::endl;
- std::cout << "Warning: limited testing only. File support not implemented yet." << std::endl;
- std::cout << "Warning: Leases will be lost after restart." << std::endl;
+ std::cout << "Warning: Using memfile database backend. It is usable for limited"
+ << " testing only. Leases will be lost after restart." << std::endl;
}
Memfile_LeaseMgr::~Memfile_LeaseMgr() {
diff --git a/src/lib/dhcpsrv/tests/Makefile.am b/src/lib/dhcpsrv/tests/Makefile.am
index 8de5fda..11e1d75 100644
--- a/src/lib/dhcpsrv/tests/Makefile.am
+++ b/src/lib/dhcpsrv/tests/Makefile.am
@@ -40,6 +40,7 @@ libdhcpsrv_unittests_SOURCES += pool_unittest.cc
libdhcpsrv_unittests_SOURCES += schema_copy.h
libdhcpsrv_unittests_SOURCES += subnet_unittest.cc
libdhcpsrv_unittests_SOURCES += triplet_unittest.cc
+libdhcpsrv_unittests_SOURCES += test_utils.cc test_utils.h
libdhcpsrv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
if HAVE_MYSQL
diff --git a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
index dcfb68b..95eabb2 100644
--- a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
+++ b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
@@ -22,6 +22,8 @@
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/memfile_lease_mgr.h>
+#include <dhcpsrv/tests/test_utils.h>
+
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
@@ -29,11 +31,13 @@
#include <iostream>
#include <sstream>
#include <map>
+#include <time.h>
using namespace std;
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::dhcp::test;
namespace {
@@ -107,26 +111,6 @@ TEST_F(AllocEngineTest, constructor) {
ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
}
-/// @todo: This method is taken from mysql_lease_mgr_utilities.cc from ticket
-/// #2342. Get rid of one instance once the code is merged
-void
-detailCompareLease6(const Lease6Ptr& first, const Lease6Ptr& second) {
- EXPECT_EQ(first->type_, second->type_);
-
- // Compare address strings - odd things happen when they are different
- // as the EXPECT_EQ appears to call the operator uint32_t() function,
- // which causes an exception to be thrown for IPv6 addresses.
- EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
- EXPECT_EQ(first->prefixlen_, second->prefixlen_);
- EXPECT_EQ(first->iaid_, second->iaid_);
- EXPECT_TRUE(*first->duid_ == *second->duid_);
- EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
- EXPECT_EQ(first->valid_lft_, second->valid_lft_);
- EXPECT_EQ(first->cltt_, second->cltt_);
- EXPECT_EQ(first->subnet_id_, second->subnet_id_);
-}
-
-
// This test checks if the simple allocation can succeed
TEST_F(AllocEngineTest, simpleAlloc) {
boost::scoped_ptr<AllocEngine> engine;
@@ -147,7 +131,7 @@ TEST_F(AllocEngineTest, simpleAlloc) {
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
- detailCompareLease6(lease, from_mgr);
+ detailCompareLease(lease, from_mgr);
}
// This test checks if the fake allocation (for SOLICIT) can succeed
@@ -195,7 +179,7 @@ TEST_F(AllocEngineTest, allocWithValidHint) {
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
- detailCompareLease6(lease, from_mgr);
+ detailCompareLease(lease, from_mgr);
}
// This test checks if the allocation with a hint that is in range,
@@ -234,7 +218,7 @@ TEST_F(AllocEngineTest, allocWithUsedHint) {
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
- detailCompareLease6(lease, from_mgr);
+ detailCompareLease(lease, from_mgr);
}
// This test checks if the allocation with a hint that is out the blue
@@ -264,7 +248,7 @@ TEST_F(AllocEngineTest, allocBogusHint) {
ASSERT_TRUE(from_mgr);
// Now check that the lease in LeaseMgr has the same parameters
- detailCompareLease6(lease, from_mgr);
+ detailCompareLease(lease, from_mgr);
}
// This test verifies that the allocator picks addresses that belong to the
@@ -337,4 +321,156 @@ TEST_F(AllocEngineTest, IterativeAllocator_manyPools) {
delete alloc;
}
+// This test checks if really small pools are working
+TEST_F(AllocEngineTest, smallPool) {
+ boost::scoped_ptr<AllocEngine> engine;
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ IOAddress addr("2001:db8:1::ad");
+ CfgMgr& cfg_mgr = CfgMgr::instance();
+ cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
+
+ // Create configuration similar to other tests, but with a single address pool
+ subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+ pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
+ subnet_->addPool6(pool_);
+ cfg_mgr.addSubnet6(subnet_);
+
+ Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
+ false);
+
+ // Check that we got that single lease
+ ASSERT_TRUE(lease);
+
+ EXPECT_EQ("2001:db8:1::ad", lease->addr_.toText());
+
+ // do all checks on the lease
+ checkLease6(lease);
+
+ // Check that the lease is indeed in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->addr_);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease(lease, from_mgr);
+}
+
+// This test checks if all addresses in a pool are currently used, the attempt
+// to find out a new lease fails.
+TEST_F(AllocEngineTest, outOfAddresses) {
+ boost::scoped_ptr<AllocEngine> engine;
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ IOAddress addr("2001:db8:1::ad");
+ CfgMgr& cfg_mgr = CfgMgr::instance();
+ cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
+
+ // Create configuration similar to other tests, but with a single address pool
+ subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+ pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
+ subnet_->addPool6(pool_);
+ cfg_mgr.addSubnet6(subnet_);
+
+ // Just a different duid
+ DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
+ const uint32_t other_iaid = 3568;
+ Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
+ 501, 502, 503, 504, subnet_->getID(), 0));
+ lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
+ ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+ // There is just a single address in the pool and allocated it to someone
+ // else, so the allocation should fail
+
+ EXPECT_THROW(engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),false),
+ AllocFailed);
+}
+
+// This test checks if an expired lease can be reused in SOLICIT (fake allocation)
+TEST_F(AllocEngineTest, solicitReuseExpiredLease) {
+ boost::scoped_ptr<AllocEngine> engine;
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ IOAddress addr("2001:db8:1::ad");
+ CfgMgr& cfg_mgr = CfgMgr::instance();
+ cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
+
+ // Create configuration similar to other tests, but with a single address pool
+ subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+ pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
+ subnet_->addPool6(pool_);
+ cfg_mgr.addSubnet6(subnet_);
+
+ // Just a different duid
+ DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
+ const uint32_t other_iaid = 3568;
+ Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
+ 501, 502, 503, 504, subnet_->getID(), 0));
+ lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
+ lease->valid_lft_ = 495; // Lease was valid for 495 seconds
+ ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+ // CASE 1: Asking for any address
+ lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
+ true);
+ // Check that we got that single lease
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(addr.toText(), lease->addr_.toText());
+
+ // Do all checks on the lease (if subnet-id, preferred/valid times are ok etc.)
+ checkLease6(lease);
+
+ // CASE 2: Asking specifically for this address
+ lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress(addr.toText()),
+ true);
+ // Check that we got that single lease
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(addr.toText(), lease->addr_.toText());
+}
+
+// This test checks if an expired lease can be reused in REQUEST (actual allocation)
+TEST_F(AllocEngineTest, requestReuseExpiredLease) {
+ boost::scoped_ptr<AllocEngine> engine;
+ ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
+ ASSERT_TRUE(engine);
+
+ IOAddress addr("2001:db8:1::ad");
+ CfgMgr& cfg_mgr = CfgMgr::instance();
+ cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
+
+ // Create configuration similar to other tests, but with a single address pool
+ subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+ pool_ = Pool6Ptr(new Pool6(Pool6::TYPE_IA, addr, addr)); // just a single address
+ subnet_->addPool6(pool_);
+ cfg_mgr.addSubnet6(subnet_);
+
+ // Let's create an expired lease
+ DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
+ const uint32_t other_iaid = 3568;
+ const SubnetID other_subnetid = 999;
+ Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, other_duid, other_iaid,
+ 501, 502, 503, 504, other_subnetid, 0));
+ lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
+ lease->valid_lft_ = 495; // Lease was valid for 495 seconds
+ ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
+
+ // A client comes along, asking specifically for this address
+ lease = engine->allocateAddress6(subnet_, duid_, iaid_,
+ IOAddress(addr.toText()), false);
+
+ // Check that he got that single lease
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(addr.toText(), lease->addr_.toText());
+
+ // Check that the lease is indeed updated in LeaseMgr
+ Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(addr);
+ ASSERT_TRUE(from_mgr);
+
+ // Now check that the lease in LeaseMgr has the same parameters
+ detailCompareLease(lease, from_mgr);
+}
+
}; // end of anonymous namespace
diff --git a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
index a812811..38c9555 100644
--- a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
@@ -258,7 +258,7 @@ TEST(Lease4, Lease4Constructor) {
// ...and a time
const time_t current_time = time(NULL);
- // Other random constants.
+ // Other random constants.
const uint32_t SUBNET_ID = 42;
const uint32_t VALID_LIFETIME = 500;
@@ -605,4 +605,29 @@ TEST(Lease6, OperatorEquals) {
EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
EXPECT_FALSE(lease1 != lease2); // ... leases equal
}
+
+// Checks if lease expiration is calculated properly
+TEST(Lease6, Lease6Expired) {
+ const IOAddress addr("2001:db8:1::456");
+ const uint8_t duid_array[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+ const DuidPtr duid(new DUID(duid_array, sizeof(duid_array)));
+ const uint32_t iaid = 7; // just a number
+ const SubnetID subnet_id = 8; // just another number
+ Lease6 lease(Lease6::LEASE_IA_NA, addr, duid, iaid, 100, 200, 50, 80,
+ subnet_id);
+
+ // case 1: a second before expiration
+ lease.cltt_ = time(NULL) - 100;
+ lease.valid_lft_ = 101;
+ EXPECT_FALSE(lease.expired());
+
+ // case 2: the lease will expire after this second is concluded
+ lease.cltt_ = time(NULL) - 101;
+ EXPECT_FALSE(lease.expired());
+
+ // case 3: the lease is expired
+ lease.cltt_ = time(NULL) - 102;
+ EXPECT_TRUE(lease.expired());
+}
+
}; // end of anonymous namespace
diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
index 746ef00..89cacef 100644
--- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/mysql_lease_mgr.h>
+#include <dhcpsrv/tests/test_utils.h>
#include <gtest/gtest.h>
@@ -29,6 +30,7 @@
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::dhcp::test;
using namespace std;
namespace {
@@ -537,48 +539,6 @@ public:
vector<IOAddress> ioaddress6_; ///< IOAddress forms of IPv6 addresses
};
-///@{
-/// @brief Test Utilities
-///
-/// The follow are a set of functions used during the tests.
-
-/// @brief Compare two Lease4 structures for equality
-void
-detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
- // Compare address strings. Comparison of address objects is not used, as
- // odd things happen when they are different: the EXPECT_EQ macro appears to
- // call the operator uint32_t() function, which causes an exception to be
- // thrown for IPv6 addresses.
- EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
- EXPECT_TRUE(first->hwaddr_ == second->hwaddr_);
- EXPECT_TRUE(*first->client_id_ == *second->client_id_);
- EXPECT_EQ(first->valid_lft_, second->valid_lft_);
- EXPECT_EQ(first->cltt_, second->cltt_);
- EXPECT_EQ(first->subnet_id_, second->subnet_id_);
-}
-
-/// @brief Compare two Lease6 structures for equality
-void
-detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
- EXPECT_EQ(first->type_, second->type_);
-
- // Compare address strings. Comparison of address objects is not used, as
- // odd things happen when they are different: the EXPECT_EQ macro appears to
- // call the operator uint32_t() function, which causes an exception to be
- // thrown for IPv6 addresses.
- EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
- EXPECT_EQ(first->prefixlen_, second->prefixlen_);
- EXPECT_EQ(first->iaid_, second->iaid_);
- EXPECT_TRUE(*first->duid_ == *second->duid_);
- EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
- EXPECT_EQ(first->valid_lft_, second->valid_lft_);
- EXPECT_EQ(first->cltt_, second->cltt_);
- EXPECT_EQ(first->subnet_id_, second->subnet_id_);
-}
-
-///@}
-
-
/// @brief Check that database can be opened
///
/// This test checks if the MySqlLeaseMgr can be instantiated. This happens
diff --git a/src/lib/dhcpsrv/tests/test_utils.cc b/src/lib/dhcpsrv/tests/test_utils.cc
new file mode 100644
index 0000000..3c69dbe
--- /dev/null
+++ b/src/lib/dhcpsrv/tests/test_utils.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "test_utils.h"
+#include <gtest/gtest.h>
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+void
+detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
+ // Compare address strings. Comparison of address objects is not used, as
+ // odd things happen when they are different: the EXPECT_EQ macro appears to
+ // call the operator uint32_t() function, which causes an exception to be
+ // thrown for IPv6 addresses.
+ EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
+ EXPECT_TRUE(first->hwaddr_ == second->hwaddr_);
+ EXPECT_TRUE(*first->client_id_ == *second->client_id_);
+ EXPECT_EQ(first->valid_lft_, second->valid_lft_);
+ EXPECT_EQ(first->cltt_, second->cltt_);
+ EXPECT_EQ(first->subnet_id_, second->subnet_id_);
+}
+
+void
+detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
+ EXPECT_EQ(first->type_, second->type_);
+
+ // Compare address strings. Comparison of address objects is not used, as
+ // odd things happen when they are different: the EXPECT_EQ macro appears to
+ // call the operator uint32_t() function, which causes an exception to be
+ // thrown for IPv6 addresses.
+ EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
+ EXPECT_EQ(first->prefixlen_, second->prefixlen_);
+ EXPECT_EQ(first->iaid_, second->iaid_);
+ ASSERT_TRUE(first->duid_);
+ ASSERT_TRUE(second->duid_);
+ EXPECT_TRUE(*first->duid_ == *second->duid_);
+ EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
+ EXPECT_EQ(first->valid_lft_, second->valid_lft_);
+ EXPECT_EQ(first->cltt_, second->cltt_);
+ EXPECT_EQ(first->subnet_id_, second->subnet_id_);
+}
+
+};
+};
+};
diff --git a/src/lib/dhcpsrv/tests/test_utils.h b/src/lib/dhcpsrv/tests/test_utils.h
new file mode 100644
index 0000000..46df9fc
--- /dev/null
+++ b/src/lib/dhcpsrv/tests/test_utils.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef LIBDHCPSRV_TEST_UTILS_H
+#define LIBDHCPSRV_TEST_UTILS_H
+
+#include <dhcpsrv/lease_mgr.h>
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+// @brief performs details comparison between two IPv6 leases
+//
+// @param first first lease to compare
+// @param second second lease to compare
+//
+// This method is intended to be run from gtest tests as it
+// uses gtest macros and possibly reports gtest failures.
+void
+detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second);
+
+// @brief performs details comparison between two IPv4 leases
+//
+// @param first first lease to compare
+// @param second second lease to compare
+//
+// This method is intended to be run from gtest tests as it
+// uses gtest macros and possibly reports gtest failures.
+void
+detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second);
+
+
+};
+};
+};
+
+#endif
More information about the bind10-changes
mailing list