2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

[#1418] Checkpoint: did v6 core code

This commit is contained in:
Francis Dupont
2020-11-12 23:52:23 +01:00
parent 1644513e8f
commit d1bc0c13ad
3 changed files with 114 additions and 43 deletions

View File

@@ -484,7 +484,7 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet,
AllocEngine::ClientContext6::IAContext::IAContext()
: iaid_(0), type_(Lease::TYPE_NA), hints_(), old_leases_(),
changed_leases_(), ia_rsp_() {
changed_leases_(), new_resources_(), ia_rsp_() {
}
void
@@ -516,6 +516,21 @@ IAContext::addHint(const Option6IAPrefixPtr& iaprefix) {
iaprefix->getPreferred(), iaprefix->getValid());
}
void
AllocEngine::ClientContext6::
IAContext::addNewResource(const asiolink::IOAddress& prefix,
const uint8_t prefix_len) {
static_cast<void>(new_resources_.insert(Resource(prefix, prefix_len)));
}
bool
AllocEngine::ClientContext6::
IAContext::isNewResource(const asiolink::IOAddress& prefix,
const uint8_t prefix_len) const {
return (static_cast<bool>(new_resources_.count(Resource(prefix,
prefix_len))));
}
void
AllocEngine::ClientContext6::
addAllocatedResource(const asiolink::IOAddress& prefix,
@@ -749,6 +764,8 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
// someone else.
allocateReservedLeases6(ctx, leases);
leases = updateLeaseData(ctx, leases);
// If not, we'll need to continue and will eventually fall into case 4:
// getting a regular lease. That could happen when we're processing
// request from client X, there's a reserved address A for X, but
@@ -1233,12 +1250,7 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx,
}
}
// If this is a real allocation, we may need to extend the lease
// lifetime.
if (!ctx.fake_allocation_) {
lease->cltt_ = time(NULL);
LeaseMgrFactory::instance().updateLease6(lease);
}
// Got a lease for a reservation in this IA.
return;
}
}
@@ -1390,14 +1402,8 @@ AllocEngine::allocateGlobalReservedLeases6(ClientContext6& ctx,
static_cast<bool>(fqdn));
}
// If this is a real allocation, we may need to extend the lease
// lifetime.
if (!ctx.fake_allocation_) {
lease->cltt_ = time(NULL);
LeaseMgrFactory::instance().updateLease6(lease);
}
return;
// Got a lease for a reservation in this IA.
return(true);
}
}
@@ -1816,7 +1822,7 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
if (!ctx.fake_allocation_) {
// Add(update) the extended information on the lease.
updateLease6ExtendedInfo(expired, ctx);
static_cast<void>(updateLease6ExtendedInfo(expired, ctx));
// for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease6(expired);
@@ -1925,7 +1931,7 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx,
if (!ctx.fake_allocation_) {
// Add(update) the extended information on the lease.
updateLease6ExtendedInfo(lease, ctx);
static_cast<void>(updateLease6ExtendedInfo(lease, ctx));
// That is a real (REQUEST) allocation
bool status = LeaseMgrFactory::instance().addLease(lease);
@@ -1951,6 +1957,9 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx,
static_cast<int64_t>(1));
}
// Record it so it won't be updated twice.
ctx.currentIA().addNewResource(addr, prefix_len);
return (lease);
} else {
// One of many failures with LeaseMgr (e.g. lost connection to the
@@ -2034,6 +2043,11 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
// Extend all existing leases that passed all checks.
for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
if (ctx.currentIA().isNewResource((*l)->addr_,
(*l)->prefixlen_)) {
// This lease was just created so is already extended.
continue;
}
LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL,
ALLOC_ENGINE_V6_EXTEND_LEASE)
.arg(ctx.query_->getLabel())
@@ -2123,6 +2137,8 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
// Keep the old data in case the callout tells us to skip update.
Lease6Ptr old_data(new Lease6(*lease));
bool changed = false;
lease->remaining_preferred_lft_ = lease->preferred_lft_;
if (!ctx.currentIA().hints_.empty() &&
ctx.currentIA().hints_[0].getPreferred()) {
uint32_t preferred = ctx.currentIA().hints_[0].getPreferred();
@@ -2130,6 +2146,9 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
} else {
lease->preferred_lft_ = ctx.subnet_->getPreferred();
}
if (lease->preferred_lft_ < lease->remaining_preferred_lft_) {
changed = true;
}
if (!ctx.currentIA().hints_.empty() &&
ctx.currentIA().hints_[0].getValid()) {
uint32_t valid = ctx.currentIA().hints_[0].getValid();
@@ -2137,13 +2156,29 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
} else {
lease->valid_lft_ = ctx.subnet_->getValid();
}
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_;
lease->state_ = Lease::STATE_DEFAULT;
if (lease->valid_lft_ < lease->current_valid_lft_) {
changed = true;
}
lease->cltt_ = time(NULL);
if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
(lease->fqdn_rev_ != ctx.rev_dns_update_) ||
(lease->hostname_ != ctx.hostname_)) {
changed = true;
lease->hostname_ = ctx.hostname_;
lease->fqdn_fwd_ = ctx.fwd_dns_update_;
lease->fqdn_rev_ = ctx.rev_dns_update_;
}
if ((!ctx.hwaddr_ && lease->hwaddr_) ||
(ctx.hwaddr_ &&
(!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
changed = true;
lease->hwaddr_ = ctx.hwaddr_;
}
if (lease->state_ != Lease::STATE_DEFAULT) {
changed = true;
lease->state_ = Lease::STATE_DEFAULT;
}
LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA)
.arg(ctx.query_->getLabel())
@@ -2207,14 +2242,26 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
update_stats = true;
}
changed = true;
}
// @todo should we call storeLease6ExtendedInfo() here ?
updateLease6ExtendedInfo(lease, ctx);
if (updateLease6ExtendedInfo(lease, ctx)) {
changed = true;
}
// Try to reuse the lease.
lease->remaining_valid_lft_ = 0;
if (!changed) {
setLeaseRemainingLife(lease, ctx);
}
// Now that the lease has been reclaimed, we can go ahead and update it
// in the lease database.
LeaseMgrFactory::instance().updateLease6(lease);
if (lease->remaining_valid_lft_ == 0) {
LeaseMgrFactory::instance().updateLease6(lease);
}
if (update_stats) {
StatsMgr::instance().addValue(
@@ -2253,6 +2300,12 @@ AllocEngine::updateLeaseData(ClientContext6& ctx, const Lease6Collection& leases
for (Lease6Collection::const_iterator lease_it = leases.begin();
lease_it != leases.end(); ++lease_it) {
Lease6Ptr lease(new Lease6(**lease_it));
if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
// This lease was just created so is already up to date.
updated_leases.push_back(lease);
continue;
}
lease->fqdn_fwd_ = ctx.fwd_dns_update_;
lease->fqdn_rev_ = ctx.rev_dns_update_;
lease->hostname_ = ctx.hostname_;
@@ -2271,9 +2324,19 @@ AllocEngine::updateLeaseData(ClientContext6& ctx, const Lease6Collection& leases
}
}
bool fqdn_changed = ((lease->type_ != Lease::TYPE_PD) &&
!(lease->hasIdenticalFqdn(**lease_it)));
lease->cltt_ = time(NULL);
ctx.currentIA().changed_leases_.push_back(*lease_it);
LeaseMgrFactory::instance().updateLease6(lease);
lease->remaining_valid_lft_ = 0;
if (!fqdn_changed) {
lease->remaining_preferred_lft_ = lease->preferred_lft_;
setLeaseRemainingLife(lease, ctx);
}
if (lease->remaining_valid_lft_ == 0) {
ctx.currentIA().changed_leases_.push_back(*lease_it);
LeaseMgrFactory::instance().updateLease6(lease);
}
if (update_stats) {
StatsMgr::instance().addValue(
@@ -3870,6 +3933,7 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
// Update the lease with the information from the context.
// If there was no significant changes, try reuse.
lease->remaining_valid_lft_ = 0;
if (!updateLease4Information(lease, ctx)) {
setLeaseRemainingLife(lease, ctx);
}
@@ -4235,8 +4299,8 @@ AllocEngine::updateLease4Information(const Lease4Ptr& lease,
if ((!ctx.hwaddr_ && lease->hwaddr_) ||
(ctx.hwaddr_ &&
(!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
changed = true;
lease->hwaddr_ = ctx.hwaddr_;
changed = true;
lease->hwaddr_ = ctx.hwaddr_;
}
if (ctx.subnet_->getMatchClientId() && ctx.clientid_) {
if (!lease->client_id_ || (*ctx.clientid_ != *lease->client_id_)) {

View File

@@ -558,6 +558,11 @@ public:
/// FQDN has changed.
Lease6Collection changed_leases_;
/// @brief Holds addresses and prefixes allocated for this IA.
///
/// This collection is used to update at most once new leases.
ResourceContainer new_resources_;
/// @brief A pointer to the IA_NA/IA_PD option to be sent in
/// response
Option6IAPtr ia_rsp_;
@@ -591,6 +596,20 @@ public:
///
/// @throw BadValue if iaprefix is null.
void addHint(const Option6IAPrefixPtr& iaprefix);
/// @brief Convenience method adding new prefix or address.
///
/// @param prefix Prefix or address
/// @param prefix_len Prefix length. Default is 128 for addresses.
void addNewResource(const asiolink::IOAddress& prefix,
const uint8_t prefix_len = 128);
/// @brief Checks if specified address or prefix was new.
///
/// @param prefix Prefix or address
/// @param prefix_len Prefix length. Default is 128 for addresses.
bool isNewResource(const asiolink::IOAddress& prefix,
const uint8_t prefix_len = 128) const;
};
/// @brief Container holding IA specific contexts.

View File

@@ -3606,14 +3606,8 @@ TEST_F(AllocEngine6Test, globalHostReservedAddress) {
EXPECT_EQ("3001::1", lease->addr_.toText());
// We're going to rollback the clock a little so we can verify a renewal.
// We verify the "time" change in case the lease returned to us
// by expectOneLease ever becomes a copy and not what is in the lease mgr.
--lease->cltt_;
lease->updateCurrentExpirationTime();
Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
lease->addr_);
ASSERT_TRUE(from_mgr);
EXPECT_EQ(from_mgr->cltt_, lease->cltt_);
EXPECT_NO_THROW(LeaseMgrFactory::instance().updateLease6(lease));
// This is what the client will send in his renew message.
AllocEngine::HintContainer hints;
@@ -3671,14 +3665,8 @@ TEST_F(AllocEngine6Test, globalHostReservedPrefix) {
EXPECT_EQ("3001::", lease->addr_.toText());
// We're going to rollback the clock a little so we can verify a renewal.
// We verify the "time" change in case the lease returned to us
// by expectOneLease ever becomes a copy and not what is in the lease mgr.
--lease->cltt_;
lease->updateCurrentExpirationTime();
Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
lease->addr_);
ASSERT_TRUE(from_mgr);
EXPECT_EQ(from_mgr->cltt_, lease->cltt_);
EXPECT_NO_THROW(LeaseMgrFactory::instance().updateLease6(lease));
// This is what the client will send in his renew message.
AllocEngine::HintContainer hints;