Commit 1d64829a authored by Marcin Siodelski's avatar Marcin Siodelski

[master] Merge branch 'trac3913'

parents 2f46ef54 65b25d4e
......@@ -422,7 +422,7 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
if (!leases.empty()) {
// Return old leases so the server can see what has changed.
return (updateFqdnData(ctx, leases));
return (updateLeaseData(ctx, leases));
}
// If leases are empty at this stage, it means that we used to have
......@@ -719,7 +719,7 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
uint8_t prefix_len = resv->second.getPrefixLen();
// Check if already have this lease on the existing_leases list.
for (Lease6Collection::const_iterator l = existing_leases.begin();
for (Lease6Collection::iterator l = existing_leases.begin();
l != existing_leases.end(); ++l) {
// Ok, we already have a lease for this reservation and it's usable
......@@ -729,6 +729,13 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
.arg(ctx.query_->getLabel())
.arg((*l)->typeToText((*l)->type_))
.arg((*l)->addr_.toText());
// If this is a real allocation, we may need to extend the lease
// lifetime.
if (!ctx.fake_allocation_ && conditionalExtendLifetime(**l)) {
LeaseMgrFactory::instance().updateLease6(*l);
}
return;
}
}
......@@ -1186,12 +1193,14 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
lease->valid_lft_ = ctx.subnet_->getValid();
lease->t1_ = ctx.subnet_->getT1();
lease->t2_ = ctx.subnet_->getT2();
lease->cltt_ = time(NULL);
lease->hostname_ = ctx.hostname_;
lease->fqdn_fwd_ = ctx.fwd_dns_update_;
lease->fqdn_rev_ = ctx.rev_dns_update_;
lease->hwaddr_ = ctx.hwaddr_;
// Extend lease lifetime if it is time to extend it.
conditionalExtendLifetime(*lease);
LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA)
.arg(ctx.query_->getLabel())
......@@ -1246,7 +1255,7 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
}
Lease6Collection
AllocEngine::updateFqdnData(ClientContext6& ctx, const Lease6Collection& leases) {
AllocEngine::updateLeaseData(ClientContext6& ctx, const Lease6Collection& leases) {
Lease6Collection updated_leases;
for (Lease6Collection::const_iterator lease_it = leases.begin();
lease_it != leases.end(); ++lease_it) {
......@@ -1255,7 +1264,8 @@ AllocEngine::updateFqdnData(ClientContext6& ctx, const Lease6Collection& leases)
lease->fqdn_rev_ = ctx.rev_dns_update_;
lease->hostname_ = ctx.hostname_;
if (!ctx.fake_allocation_ &&
((lease->fqdn_fwd_ != (*lease_it)->fqdn_fwd_) ||
(conditionalExtendLifetime(*lease) ||
(lease->fqdn_fwd_ != (*lease_it)->fqdn_fwd_) ||
(lease->fqdn_rev_ != (*lease_it)->fqdn_rev_) ||
(lease->hostname_ != (*lease_it)->hostname_))) {
ctx.changed_leases_.push_back(*lease_it);
......@@ -2032,5 +2042,11 @@ AllocEngine::updateLease4Information(const Lease4Ptr& lease,
lease->hostname_ = ctx.hostname_;
}
bool
AllocEngine::conditionalExtendLifetime(Lease& lease) const {
lease.cltt_ = time(NULL);
return (true);
}
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -634,19 +634,26 @@ private:
ClientContext6& ctx,
uint8_t prefix_len);
/// @brief Updates FQDN data for a collection of leases.
/// @brief Updates FQDN and Client's Last Tranmission Time for a collection
/// of leases.
///
/// This method is executed when the server finds existing leases for a
/// client and updates some date for these leases if needed:
/// - client's last transmission time (cltt), if the lease to be returned
/// to the client should have its lifetime extended,
/// - FQDN data, when the client has negotiated new FQDN with the server.
///
/// @param ctx IPv6 client context (old versions of the leases that had
/// FQDN data changed will be stored in ctx.changed_leases_,
/// ctx.fwd_dns_update, ctx.rev_dns_update, ctx.hostname_
/// and ctx.fake_allocation_ will be used.
/// @param leases Collection of leases for which FQDN data should be
/// @param leases Collection of leases for which lease data should be
/// updated.
///
/// @return Collection of leases with updated FQDN data. Note that returned
/// @return Collection of leases with updated data. Note that returned
/// collection holds updated FQDN data even for fake allocation.
Lease6Collection updateFqdnData(ClientContext6& ctx,
const Lease6Collection& leases);
Lease6Collection updateLeaseData(ClientContext6& ctx,
const Lease6Collection& leases);
/// @brief Utility function that removes all leases with a specified address
/// @param container A collection of Lease6 pointers
......@@ -1084,6 +1091,28 @@ private:
/// client and its message.
void updateLease4Information(const Lease4Ptr& lease,
ClientContext4& ctx) const;
/// @brief Extends the lease lifetime.
///
/// This function is called to conditionally extend the lifetime of
/// the DHCPv4 or DHCPv6 lease. It is envisaged that this function will
/// make a decision if the lease lifetime should be extended, using
/// a preconfigured threshold, which would indicate how many percent
/// of the valid lifetime should have passed for the lease lifetime
/// to be extended. The lease lifetime would not be extended if
/// the threshold hasn't been reached.
///
/// @todo Currently this function always extends the lease lifetime.
/// In the future, it will take the threshold value into account,
/// once the threshold is configurable.
///
/// @param [in,out] lease A lease for which the lifetime should be
/// extended.
///
/// @return true if the lease lifetime has been extended, false
/// otherwise.
bool conditionalExtendLifetime(Lease& lease) const;
};
/// @brief A pointer to the @c AllocEngine object.
......
......@@ -601,6 +601,118 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
EXPECT_EQ(100, stat->getInteger().first);
}
// Checks if the lease lifetime is extended when the client sends the
// Request.
TEST_F(AllocEngine6Test, requestExtendLeaseLifetime) {
// Create a lease for the client.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::15"),
duid_, iaid_, 300, 400, 100, 200,
subnet_->getID(), HWAddrPtr(), 128));
// Allocated 200 seconds ago - half of the lifetime.
time_t lease_cltt = time(NULL) - 200;
lease->cltt_ = lease_cltt;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Client should receive a lease.
Lease6Ptr new_lease = simpleAlloc6Test(pool_, IOAddress("::"), false);
ASSERT_TRUE(new_lease);
// And the lease lifetime should be extended.
EXPECT_GT(new_lease->cltt_, lease_cltt)
<< "Lease lifetime was not extended, but it should";
}
// Checks if the lease lifetime is extended when the client sends the
// Request and the client has a reservation for the lease.
TEST_F(AllocEngine6Test, requestExtendLeaseLifetimeForReservation) {
// Create reservation for the client. This is in-pool reservation,
// as the pool is 2001:db8:1::10 - 2001:db8:1::20.
createHost6(true, IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::1c"), 128);
// Create a lease for the client.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1c"),
duid_, iaid_, 300, 400, 100, 200,
subnet_->getID(), HWAddrPtr(), 128));
// Allocated 200 seconds ago - half of the lifetime.
time_t lease_cltt = time(NULL) - 200;
lease->cltt_ = lease_cltt;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Client should receive a lease.
Lease6Ptr new_lease = simpleAlloc6Test(pool_, IOAddress("::"), false);
ASSERT_TRUE(new_lease);
// And the lease lifetime should be extended.
EXPECT_GT(new_lease->cltt_, lease_cltt)
<< "Lease lifetime was not extended, but it should";
}
// Checks if the lease lifetime is extended when the client sends the
// Renew.
TEST_F(AllocEngine6Test, renewExtendLeaseLifetime) {
// Create a lease for the client.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::15"),
duid_, iaid_, 300, 400, 100, 200,
subnet_->getID(), HWAddrPtr(), 128));
// Allocated 200 seconds ago - half of the lifetime.
time_t lease_cltt = time(NULL) - 200;
lease->cltt_ = lease_cltt;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100);
// This is what the client will send in his renew message.
AllocEngine::HintContainer hints;
hints.push_back(make_pair(IOAddress("2001:db8:1::15"), 128));
// Client should receive a lease.
Lease6Collection renewed = renewTest(engine, pool_, hints, true);
ASSERT_EQ(1, renewed.size());
// And the lease lifetime should be extended.
EXPECT_GT(renewed[0]->cltt_, lease_cltt)
<< "Lease lifetime was not extended, but it should";
}
// Checks if the lease lifetime is extended when the client sends the
// Renew and the client has a reservation for the lease.
TEST_F(AllocEngine6Test, renewExtendLeaseLifetimeForReservation) {
// Create reservation for the client. This is in-pool reservation,
// as the pool is 2001:db8:1::10 - 2001:db8:1::20.
createHost6(true, IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::15"), 128);
// Create a lease for the client.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::15"),
duid_, iaid_, 300, 400, 100, 200,
subnet_->getID(), HWAddrPtr(), 128));
// Allocated 200 seconds ago - half of the lifetime.
time_t lease_cltt = time(NULL) - 200;
lease->cltt_ = lease_cltt;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100);
// This is what the client will send in his renew message.
AllocEngine::HintContainer hints;
hints.push_back(make_pair(IOAddress("2001:db8:1::15"), 128));
// Client should receive a lease.
Lease6Collection renewed = renewTest(engine, pool_, hints, true);
ASSERT_EQ(1, renewed.size());
// And the lease lifetime should be extended.
EXPECT_GT(renewed[0]->cltt_, lease_cltt)
<< "Lease lifetime was not extended, but it should";
}
// --- v6 host reservation ---
// Checks that a client gets the address reserved (in-pool case)
......
......@@ -74,7 +74,7 @@ AllocEngine6Test::initSubnet(const asiolink::IOAddress& subnet,
const asiolink::IOAddress& pool_end) {
CfgMgr& cfg_mgr = CfgMgr::instance();
subnet_ = Subnet6Ptr(new Subnet6(subnet, 56, 1, 2, 3, 4));
subnet_ = Subnet6Ptr(new Subnet6(subnet, 56, 100, 200, 300, 400));
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, pool_start, pool_end));
subnet_->addPool(pool_);
......
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