+1800. [bug] razvan
+ Fixed lease update when using HA and lease_cmds hooks with
+ database backend. Previously, HA updates were rejected because
+ the database backend rejects operations on the lease if the old
+ expiration time is different than what it is already stored, to
+ act as a protection mechanism for parallel updates from several
+ threads or processes.
+
1799. [bug] tmark
kea-dhcp4 now correctly updates DNS when a client
returns for lease after the lease has expired. Prior
Removed "Multithreading is experimental" warning log message
from kea-dhcp4 and kea-dhcp6 servers.
(Gitlab #1435,#1431)
+ (Gitlab #1434,#1488)
Kea 1.8.0 (stable) released on Aug 26, 2020
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease4Ptr lease(new Lease4());
- lease->addr_ = addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease4Ptr lease(new Lease4());
- lease->addr_ = c.addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(c.addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease4Ptr lease(new Lease4());
- lease->addr_ = c.addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(c.addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease4Ptr lease(new Lease4());
- lease->addr_ = c.addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(c.addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease4Ptr lease(new Lease4());
- lease->addr_ = c.addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(c.addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
sort(expected_argument_names.begin(), expected_argument_names.end());
EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
- Lease4Ptr lease(new Lease4());
- lease->addr_ = addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Pkt passed to a callout must be configured to copy retrieved options.
EXPECT_EQ(temp_valid, l->valid_lft_);
EXPECT_EQ(temp_timestamp, l->cltt_);
- Lease4Ptr lease(new Lease4());
- lease->addr_ = addr;
+ Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Check if the callout handle state was reset after the callout.
// check that the lease is really in the database
Lease6Ptr l = checkLease(duid_, reply->getOption(D6O_IA_NA), addr);
EXPECT_TRUE(l);
- Lease6Ptr lease(new Lease6());
- lease->addr_ = addr->getAddress();
- LeaseMgrFactory::instance().deleteLease(lease);
+ Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr->getAddress());
+ EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// This test verifies that incoming REQUEST can be handled properly, that a
// check that the lease is really in the database
Lease6Ptr l = checkPdLease(duid_, reply->getOption(D6O_IA_PD), prf);
EXPECT_TRUE(l);
- Lease6Ptr lease(new Lease6());
- lease->addr_ = prf->getAddress();
+ Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD,
+ prf->getAddress());
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease6Ptr lease(new Lease6());
- lease->addr_ = renew_addr;
+ Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(type,
+ IOAddress(renew_addr));
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
EXPECT_EQ(1, stat->getInteger().first);
// Finally, let's cleanup the database
- lease.reset(new Lease6());
- lease->addr_ = addr;
+ lease = LeaseMgrFactory::instance().getLease6(type, addr);
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
}
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- Lease6Ptr deleted_lease(new Lease6());
- deleted_lease->addr_ = addr_opt->getAddress();
+ Lease6Ptr deleted_lease =
+ LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr_opt->getAddress());
EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(deleted_lease));
// Check if the callout handle state was reset after the callout.
// Equality or difference by 1 between cltt and expected is ok.
EXPECT_GE(1, abs(cltt - expected));
- lease.reset(new Lease6());
- lease->addr_ = addr_opt->getAddress();
- EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
+ Lease6Ptr deleted_lease =
+ LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr_opt->getAddress());
+ EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(deleted_lease));
// Check if the callout handle state was reset after the callout.
checkCalloutHandleReset(req);
Lease6 lease_client = client.getLease(0);
// The lease has been acquired. Now, let's explicitly remove it from the
// lease database.
- Lease6Ptr lease(new Lease6());
- lease->addr_ = lease_client.addr_;
- LeaseMgrFactory::instance().deleteLease(lease);
+ Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ lease_client.addr_);
+ EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Send Rebind.
ASSERT_NO_THROW(client.doRebind());
Lease6 lease_client = client.getLease(0);
// The lease has been acquired. Now, let's explicitly remove it from the
// lease database.
- Lease6Ptr lease(new Lease6());
- lease->addr_ = lease_client.addr_;
- LeaseMgrFactory::instance().deleteLease(lease);
+ Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ lease_client.addr_);
+ EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Send Rebind.
ASSERT_NO_THROW(client.doRebind());
} else if (existing_lease->cltt_ < lease->cltt_) {
// If the existing lease is older than the fetched lease, update
// the lease in our local database.
+ // Update lease current expiration time with value received from the
+ // database. Some database backends reject operations on the lease if
+ // the current expiration time value does not match what is stored.
+ Lease::syncCurrentExpirationTime(*existing_lease, *lease);
LeaseMgrFactory::instance().updateLease4(lease);
} else {
} else if (existing_lease->cltt_ < lease->cltt_) {
// If the existing lease is older than the fetched lease, update
// the lease in our local database.
+ // Update lease current expiration time with value received from the
+ // database. Some database backends reject operations on the lease if
+ // the current expiration time value does not match what is stored.
+ Lease::syncCurrentExpirationTime(*existing_lease, *lease);
LeaseMgrFactory::instance().updateLease6(lease);
} else {
LeaseCmdsImpl::updateStatsOnAdd(lease);
return (true);
}
- LeaseMgrFactory::instance().updateLease4(lease);
+ if (existing) {
+ // Update lease current expiration time with value received from the
+ // database. Some database backends reject operations on the lease if
+ // the current expiration time value does not match what is stored.
+ Lease::syncCurrentExpirationTime(*existing, *lease);
+ }
+ try {
+ LeaseMgrFactory::instance().updateLease4(lease);
+ } catch (const NoSuchLease&) {
+ isc_throw(InvalidOperation, "failed to update the lease with address "
+ << lease->addr_ << " either because the lease has been "
+ "deleted or it has changed in the database, in both cases a "
+ "retry might succeed");
+ }
+
LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
return (false);
}
LeaseCmdsImpl::updateStatsOnAdd(lease);
return (true);
}
- LeaseMgrFactory::instance().updateLease6(lease);
+ if (existing) {
+ // Update lease current expiration time with value received from the
+ // database. Some database backends reject operations on the lease if
+ // the current expiration time value does not match what is stored.
+ Lease::syncCurrentExpirationTime(*existing, *lease);
+ }
+ try {
+ LeaseMgrFactory::instance().updateLease6(lease);
+ } catch (const NoSuchLease&) {
+ isc_throw(InvalidOperation, "failed to update the lease with address "
+ << lease->addr_ << " either because the lease has been "
+ "deleted or it has changed in the database, in both cases a "
+ "retry might succeed");
+ }
+
LeaseCmdsImpl::updateStatsOnUpdate(existing, lease);
return (false);
}
// expiration time is cast properly.
lease->valid_lft_ = HIGH_VALID_LIFETIME; // Very high valid lifetime
lease->cltt_ = DEC_2030_TIME; // December 11th 2030
+ lease->updateCurrentExpirationTime();
if (declined) {
lease->state_ = Lease::STATE_DECLINED;
}
// expiration time is cast properly.
lease->valid_lft_ = HIGH_VALID_LIFETIME; // Very high valid lifetime
lease->cltt_ = DEC_2030_TIME; // December 11th 2030
+ lease->updateCurrentExpirationTime();
if (declined) {
lease->state_ = Lease::STATE_DECLINED;
}
" \"hostname\": \"newhostname.example.org\""
" }\n"
"}";
- string exp_rsp = "failed to update the lease with address 192.0.2.1 - no such lease";
+ string exp_rsp = "failed to update the lease with address 192.0.2.1 "
+ "either because the lease has been deleted or it has changed in the "
+ "database, in both cases a retry might succeed";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
}
" \"force-create\": false"
" }\n"
"}";
- string exp_rsp = "failed to update the lease with address 192.0.2.1 - no such lease";
+ string exp_rsp = "failed to update the lease with address 192.0.2.1 "
+ "either because the lease has been deleted or it has changed in the "
+ "database, in both cases a retry might succeed";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
checkLease4Stats(44, 0, 0);
" \"hostname\": \"newhostname.example.org\""
" }\n"
"}";
- string exp_rsp = "failed to update the lease with address 2001:db8:1::1 - no such lease";
+ string exp_rsp = "failed to update the lease with address 2001:db8:1::1 "
+ "either because the lease has been deleted or it has changed in the "
+ "database, in both cases a retry might succeed";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
checkLease6Stats(66, 0, 0, 0);
" \"force-create\": false"
" }\n"
"}";
- string exp_rsp = "failed to update the lease with address 2001:db8:1::1 - no such lease";
+ string exp_rsp = "failed to update the lease with address 2001:db8:1::1 "
+ "either because the lease has been deleted or it has changed in the "
+ "database, in both cases a retry might succeed";
testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
checkLease6Stats(66, 0, 0, 0);
///
/// @param connection already open Cassandra connection.
CqlLeaseExchange(const CqlConnection &connection)
- : connection_(connection), valid_lifetime_(0), expire_(0), old_expire_(0),
- subnet_id_(0), fqdn_fwd_(cass_false), fqdn_rev_(cass_false),
- state_(0), user_context_(NULL_USER_CONTEXT) {
+ : connection_(connection), valid_lifetime_(0), expire_(0),
+ current_expire_(0), subnet_id_(0), fqdn_fwd_(cass_false),
+ fqdn_rev_(cass_false), state_(0), user_context_(NULL_USER_CONTEXT) {
}
/// @brief Create BIND array to receive C++ data.
cass_int64_t expire_;
/// @brief Expiration time of lease before update
- cass_int64_t old_expire_;
+ cass_int64_t current_expire_;
/// @brief Subnet identifier
cass_int32_t subnet_id_;
data.add(&user_context_);
data.add(&address_);
- CqlExchange::convertToDatabaseTime(lease_->old_cltt_, lease_->old_valid_lft_,
- old_expire_);
- data.add(&old_expire_);
+ CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
+ lease_->current_valid_lft_,
+ current_expire_);
+ data.add(¤t_expire_);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
"CqlLease4Exchange::createBindUpdate(): "
data.clear();
data.add(&address_);
- CqlExchange::convertToDatabaseTime(lease_->old_cltt_, lease_->old_valid_lft_,
- old_expire_);
- data.add(&old_expire_);
+ CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
+ lease_->current_valid_lft_,
+ current_expire_);
+ data.add(¤t_expire_);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
"CqlLease4Exchange::createBindForDelete(): "
data.add(&user_context_);
data.add(&address_);
- CqlExchange::convertToDatabaseTime(lease_->old_cltt_, lease_->old_valid_lft_,
- old_expire_);
- data.add(&old_expire_);
+ CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
+ lease_->current_valid_lft_,
+ current_expire_);
+ data.add(¤t_expire_);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
"CqlLease6Exchange::createBindForUpdate(): "
data.clear();
data.add(&address_);
- CqlExchange::convertToDatabaseTime(lease_->old_cltt_, lease_->old_valid_lft_,
- old_expire_);
- data.add(&old_expire_);
+ CqlExchange::convertToDatabaseTime(lease_->current_cltt_,
+ lease_->current_valid_lft_,
+ current_expire_);
+ data.add(¤t_expire_);
} catch (const Exception &ex) {
isc_throw(DbOperationError,
"CqlLease6Exchange::createBindForDelete(): "
time_t cltt = 0;
CqlExchange::convertFromDatabaseTime(expire_, valid_lifetime_, cltt);
+ // Update cltt_ and current_cltt_ explicitly.
result->cltt_ = cltt;
- result->old_cltt_ = cltt;
+ result->current_cltt_ = cltt;
result->state_ = state_;
return false;
}
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return true;
}
return false;
}
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return true;
}
isc_throw(NoSuchLease, exception.what());
}
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
void
isc_throw(NoSuchLease, exception.what());
}
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
bool
/// exist.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses IF expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease4(const Lease4Ptr& lease4) override;
/// @brief Updates IPv6 lease.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses IF expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease6(const Lease6Ptr& lease6) override;
/// @brief Deletes an IPv4 lease.
/// @param lease IPv4 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses IF expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
bool deleteLease(const Lease4Ptr& lease) override final;
/// @brief Deletes an IPv6 lease.
/// @param lease IPv6 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses IF expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
bool deleteLease(const Lease6Ptr& lease) override final;
/// @brief Deletes all expired and reclaimed DHCPv4 leases.
uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
const bool fqdn_fwd, const bool fqdn_rev,
const std::string& hostname, const HWAddrPtr& hwaddr)
- : addr_(addr), valid_lft_(valid_lft), old_valid_lft_(valid_lft),
- cltt_(cltt), old_cltt_(cltt), subnet_id_(subnet_id),
+ : addr_(addr), valid_lft_(valid_lft), current_valid_lft_(valid_lft),
+ cltt_(cltt), current_cltt_(cltt), subnet_id_(subnet_id),
hostname_(boost::algorithm::to_lower_copy(hostname)), fqdn_fwd_(fqdn_fwd),
fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) {
}
}
lease->setContext(ctx);
}
+
+ lease->updateCurrentExpirationTime();
+}
+
+void
+Lease::updateCurrentExpirationTime() {
+ Lease::syncCurrentExpirationTime(*this, *this);
+}
+
+void
+Lease::syncCurrentExpirationTime(const Lease& from, Lease& to) {
+ to.current_cltt_ = from.cltt_;
+ to.current_valid_lft_ = from.valid_lft_;
}
Lease4::Lease4(const Lease4& other)
if (this != &other) {
addr_ = other.addr_;
valid_lft_ = other.valid_lft_;
- old_valid_lft_ = other.old_valid_lft_;
+ current_valid_lft_ = other.current_valid_lft_;
cltt_ = other.cltt_;
- old_cltt_ = other.old_cltt_;
+ current_cltt_ = other.current_cltt_;
subnet_id_ = other.subnet_id_;
hostname_ = other.hostname_;
fqdn_fwd_ = other.fqdn_fwd_;
}
cltt_ = time(NULL);
- old_cltt_ = cltt_;
+ current_cltt_ = cltt_;
}
Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
}
cltt_ = time(NULL);
- old_cltt_ = cltt_;
+ current_cltt_ = cltt_;
}
Lease6::Lease6()
addr_ == other.addr_ &&
subnet_id_ == other.subnet_id_ &&
valid_lft_ == other.valid_lft_ &&
- old_valid_lft_ == other.old_valid_lft_ &&
+ current_valid_lft_ == other.current_valid_lft_ &&
cltt_ == other.cltt_ &&
- old_cltt_ == other.old_cltt_ &&
+ current_cltt_ == other.current_cltt_ &&
hostname_ == other.hostname_ &&
fqdn_fwd_ == other.fqdn_fwd_ &&
fqdn_rev_ == other.fqdn_rev_ &&
iaid_ == other.iaid_ &&
preferred_lft_ == other.preferred_lft_ &&
valid_lft_ == other.valid_lft_ &&
- old_valid_lft_ == other.old_valid_lft_ &&
+ current_valid_lft_ == other.current_valid_lft_ &&
cltt_ == other.cltt_ &&
- old_cltt_ == other.old_cltt_ &&
+ current_cltt_ == other.current_cltt_ &&
subnet_id_ == other.subnet_id_ &&
hostname_ == other.hostname_ &&
fqdn_fwd_ == other.fqdn_fwd_ &&
/// @param fqdn_rev If true, reverse DNS update is performed for a lease.
/// @param hostname FQDN of the client which gets the lease.
/// @param hwaddr Hardware/MAC address
+ ///
+ /// @note When creating a new Lease object, current_cltt_ matches cltt_ and
+ /// current_valid_lft_ matches valid_lft_. Any update operation that changes
+ /// cltt_ or valid_lft_ in the database must also update the current_cltt_
+ /// and current_valid_lft_ after the database response so that additional
+ /// operations can be performed on the same object. Failing to do so will
+ /// result in the new actions to be rejected by the database.
Lease(const isc::asiolink::IOAddress& addr,
uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
const bool fqdn_fwd, const bool fqdn_rev,
/// Expressed as number of seconds since cltt.
uint32_t valid_lft_;
- /// @brief Old valid lifetime
+ /// @brief Current valid lifetime
///
/// Expressed as number of seconds since cltt before update.
- uint32_t old_valid_lft_;
+ uint32_t current_valid_lft_;
/// @brief Client last transmission time
///
/// client was received.
time_t cltt_;
- /// @brief Old client last transmission time
+ /// @brief Current client last transmission time
///
/// Specifies a timestamp giving the time when the last transmission from a
/// client was received before update.
- time_t old_cltt_;
+ time_t current_cltt_;
/// @brief Subnet identifier
///
/// Avoid a clang spurious error
using isc::data::CfgToElement::toElement;
+ /// Sync lease current expiration time with new value from another lease,
+ /// so that additional operations can be done without performing extra read
+ /// from the database.
+ ///
+ /// @note The lease current expiration time is represented by the
+ /// @ref current_cltt_ and @ref current_valid_lft_ and the new value by
+ /// @ref cltt_ and @ref valid_lft_
+ ///
+ /// @param from The lease with latest value of expiration time.
+ /// @param [out] to The lease that needs to be updated.
+ static void syncCurrentExpirationTime(const Lease& from, Lease& to);
+
+ /// Update lease current expiration time with new value,
+ /// so that additional operations can be done without performing extra read
+ /// from the database.
+ ///
+ /// @note The lease current expiration time is represented by the
+ /// @ref current_cltt_ and @ref current_valid_lft_ and the new value by
+ /// @ref cltt_ and @ref valid_lft_
+ void updateCurrentExpirationTime();
+
protected:
/// @brief Sets common (for v4 and v6) properties of the lease object.
}
storage4_.insert(lease);
+
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
+
return (true);
}
}
storage6_.insert(lease);
+
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
+
return (true);
}
// Obtain 'by address' index.
Lease4StorageAddressIndex& index = storage4_.get<AddressIndexTag>();
+ bool persist = persistLeases(V4);
+
// Lease must exist if it is to be updated.
Lease4StorageAddressIndex::const_iterator lease_it = index.find(lease->addr_);
if (lease_it == index.end()) {
isc_throw(NoSuchLease, "failed to update the lease with address "
<< lease->addr_ << " - no such lease");
+ } else if ((!persist) && (((*lease_it)->cltt_ != lease->current_cltt_) ||
+ ((*lease_it)->valid_lft_ != lease->current_valid_lft_))) {
+ // For test purpose only: check that the lease has not changed in
+ // the database.
+ isc_throw(NoSuchLease, "failed to update the lease with address "
+ << lease->addr_ << " - lease has changed in database");
}
// Try to write a lease to disk first. If this fails, the lease will
// not be inserted to the memory and the disk and in-memory data will
// remain consistent.
- if (persistLeases(V4)) {
+ if (persist) {
lease_file4_->append(*lease);
}
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
+
// Use replace() to re-index leases.
index.replace(lease_it, Lease4Ptr(new Lease4(*lease)));
}
// Obtain 'by address' index.
Lease6StorageAddressIndex& index = storage6_.get<AddressIndexTag>();
+ bool persist = persistLeases(V6);
+
// Lease must exist if it is to be updated.
Lease6StorageAddressIndex::const_iterator lease_it = index.find(lease->addr_);
if (lease_it == index.end()) {
isc_throw(NoSuchLease, "failed to update the lease with address "
<< lease->addr_ << " - no such lease");
+ } else if ((!persist) && (((*lease_it)->cltt_ != lease->current_cltt_) ||
+ ((*lease_it)->valid_lft_ != lease->current_valid_lft_))) {
+ // For test purpose only: check that the lease has not changed in
+ // the database.
+ isc_throw(NoSuchLease, "failed to update the lease with address "
+ << lease->addr_ << " - lease has changed in database");
}
// Try to write a lease to disk first. If this fails, the lease will
// not be inserted to the memory and the disk and in-memory data will
// remain consistent.
- if (persistLeases(V6)) {
+ if (persist) {
lease_file6_->append(*lease);
}
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
+
// Use replace() to re-index leases.
index.replace(lease_it, Lease6Ptr(new Lease6(*lease)));
}
// removed.
lease_copy.valid_lft_ = 0;
lease_file4_->append(lease_copy);
+ } else {
+ // For test purpose only: check that the lease has not changed in
+ // the database.
+ if (((*l)->cltt_ != lease->current_cltt_) ||
+ ((*l)->valid_lft_ != lease->current_valid_lft_)) {
+ return false;
+ }
}
storage4_.erase(l);
return (true);
lease_copy.valid_lft_ = 0;
lease_copy.preferred_lft_ = 0;
lease_file6_->append(lease_copy);
+ } else {
+ // For test purpose only: check that the lease has not changed in
+ // the database.
+ if (((*l)->cltt_ != lease->current_cltt_) ||
+ ((*l)->valid_lft_ != lease->current_valid_lft_)) {
+ return false;
+ }
}
storage6_.erase(l);
return (true);
///
/// @param lease4 The lease to be updated.
///
- /// If no such lease is present, an exception will be thrown.
+ /// @throw NoSuchLease if there is no such lease to be updated.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the update
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and UPDATE with different expiration time.
virtual void updateLease4(const Lease4Ptr& lease4);
/// @brief Updates IPv6 lease.
///
/// @param lease6 The lease to be updated.
///
- /// If no such lease is present, an exception will be thrown.
+ /// @throw NoSuchLease if there is no such lease to be updated.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the update
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and UPDATE with different expiration time.
virtual void updateLease6(const Lease6Ptr& lease6);
/// @brief Deletes an IPv4 lease.
/// @param lease IPv4 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the deletion
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and DELETE with different expiration time.
virtual bool deleteLease(const Lease4Ptr& lease);
/// @brief Deletes an IPv6 lease.
/// @param lease IPv6 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the deletion
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and DELETE with different expiration time.
virtual bool deleteLease(const Lease6Ptr& lease);
/// @brief Deletes all expired-reclaimed DHCPv4 leases.
/// @brief Updates IPv4 lease.
///
/// @param lease4 The lease to be updated.
+ ///
+ /// @throw NoSuchLease if there is no such lease to be updated.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the update
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and UPDATE with different expiration time.
void updateLease4Internal(const Lease4Ptr& lease4);
/// @brief Updates IPv6 lease.
///
/// @param lease6 The lease to be updated.
+ ///
+ /// @throw NoSuchLease if there is no such lease to be updated.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the update
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and UPDATE with different expiration time.
void updateLease6Internal(const Lease6Ptr& lease6);
/// @brief Deletes an IPv4 lease.
/// @param lease IPv4 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the deletion
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and DELETE with different expiration time.
bool deleteLeaseInternal(const Lease4Ptr& addr);
/// @brief Deletes an IPv6 lease.
/// @param lease IPv6 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note For test purposes only, when persistence is disabled, the deletion
+ /// of the lease is performed only if the value matches the one received on
+ /// the SELECT query, effectively enforcing no update on the lease between
+ /// SELECT and DELETE with different expiration time.
bool deleteLeaseInternal(const Lease6Ptr& addr);
/// @brief Removes specified IPv4 leases.
valid_lft = 0;
}
MySqlConnection::convertFromDatabaseTime(expire_, valid_lft, cltt);
+ // Update cltt_ and current_cltt_ explicitly.
result->cltt_ = cltt;
- result->old_cltt_ = cltt;
+ result->current_cltt_ = cltt;
// Set state.
result->state_ = state_;
// ... and drop to common code.
auto result = addLeaseCommon(ctx, INSERT_LEASE4, bind);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return (result);
}
// ... and drop to common code.
auto result = addLeaseCommon(ctx, INSERT_LEASE6, bind);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return (result);
}
bind.push_back(inbind[0]);
MYSQL_TIME expire;
- MySqlConnection::convertToDatabaseTime(lease->old_cltt_, lease->old_valid_lft_,
+ MySqlConnection::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_,
expire);
inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
inbind[1].buffer = reinterpret_cast<char*>(&expire);
// Drop to common update code
updateLeaseCommon(ctx, stindex, &bind[0], lease);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
void
bind.push_back(inbind[0]);
MYSQL_TIME expire;
- MySqlConnection::convertToDatabaseTime(lease->old_cltt_, lease->old_valid_lft_,
+ MySqlConnection::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_,
expire);
inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
inbind[1].buffer = reinterpret_cast<char*>(&expire);
// Drop to common update code
updateLeaseCommon(ctx, stindex, &bind[0], lease);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
// Delete lease methods. Similar to other groups of methods, these comprise
inbind[0].is_unsigned = MLM_TRUE;
MYSQL_TIME expire;
- MySqlConnection::convertToDatabaseTime(lease->old_cltt_, lease->old_valid_lft_,
+ MySqlConnection::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_,
expire);
inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
inbind[1].buffer = reinterpret_cast<char*>(&expire);
inbind[0].length = &addr6_length;
MYSQL_TIME expire;
- MySqlConnection::convertToDatabaseTime(lease->old_cltt_, lease->old_valid_lft_,
+ MySqlConnection::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_,
expire);
inbind[1].buffer_type = MYSQL_TYPE_TIMESTAMP;
inbind[1].buffer = reinterpret_cast<char*>(&expire);
/// exist.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses WHERE expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease4(const Lease4Ptr& lease4);
/// @brief Updates IPv6 lease.
/// exist.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses WHERE expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease6(const Lease6Ptr& lease6);
/// @brief Deletes an IPv4 lease.
/// @param lease IPv4 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses WHERE expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
virtual bool deleteLease(const Lease4Ptr& lease);
/// @brief Deletes an IPv6 lease.
/// @param lease IPv6 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses WHERE expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
virtual bool deleteLease(const Lease6Ptr& lease);
/// @brief Deletes all expired-reclaimed DHCPv4 leases.
subnet_id_, fqdn_fwd_,
fqdn_rev_, hostname_,
hwaddr, prefix_len_));
+ // Update cltt_ and current_cltt_ explicitly.
result->cltt_ = cltt_;
- result->old_cltt_ = cltt_;
+ result->current_cltt_ = cltt_;
result->state_ = state;
ctx->exchange4_->createBindForSend(lease, bind_array);
auto result = addLeaseCommon(ctx, INSERT_LEASE4, bind_array);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return (result);
}
auto result = addLeaseCommon(ctx, INSERT_LEASE6, bind_array);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time (allows update between the creation
+ // of the Lease up to the point of insertion in the database).
+ lease->updateCurrentExpirationTime();
return (result);
}
std::string addr4_str = boost::lexical_cast<std::string>(lease->addr_.toUint32());
bind_array.add(addr4_str);
- std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->old_cltt_,
- lease->old_valid_lft_);
+ std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_);
bind_array.add(expire_str);
// Drop to common update code
updateLeaseCommon(ctx, stindex, bind_array, lease);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
void
std::string addr_str = lease->addr_.toText();
bind_array.add(addr_str);
- std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->old_cltt_,
- lease->old_valid_lft_);
+ std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_);
bind_array.add(expire_str);
// Drop to common update code
updateLeaseCommon(ctx, stindex, bind_array, lease);
- lease->old_cltt_ = lease->cltt_;
- lease->old_valid_lft_ = lease->valid_lft_;
+ // Update lease current expiration time.
+ lease->updateCurrentExpirationTime();
}
uint64_t
std::string addr4_str = boost::lexical_cast<std::string>(addr.toUint32());
bind_array.add(addr4_str);
- std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->old_cltt_,
- lease->old_valid_lft_);
+ std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_);
bind_array.add(expire_str);
auto affected_rows = deleteLeaseCommon(DELETE_LEASE4, bind_array);
std::string addr6_str = addr.toText();
bind_array.add(addr6_str);
- std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->old_cltt_,
- lease->old_valid_lft_);
+ std::string expire_str = PgSqlLeaseExchange::convertToDatabaseTime(lease->current_cltt_,
+ lease->current_valid_lft_);
bind_array.add(expire_str);
auto affected_rows = deleteLeaseCommon(DELETE_LEASE6, bind_array);
/// exist.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses WHERE expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease4(const Lease4Ptr& lease4);
/// @brief Updates IPv6 lease.
/// exist.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The UPDATE query uses WHERE expire = ? to update the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and UPDATE with
+ /// different expiration time.
virtual void updateLease6(const Lease6Ptr& lease6);
/// @brief Deletes an IPv4 lease.
/// @param lease IPv4 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses WHERE expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
virtual bool deleteLease(const Lease4Ptr& lease);
/// @brief Deletes an IPv6 lease.
/// @param lease IPv6 lease being deleted.
///
/// @return true if deletion was successful, false if no such lease exists.
+ ///
+ /// @note The current_cltt_ and current_valid_lft_ are used to maximize the
+ /// chance that only one thread or process performs an update or delete
+ /// operation on the lease by matching these values with the expiration time
+ /// data in the database.
+ /// @note The DELETE query uses WHERE expire = ? to delete the lease only if
+ /// the value matches the one received on the SELECT query, effectively
+ /// enforcing no update on the lease between SELECT and DELETE with
+ /// different expiration time.
virtual bool deleteLease(const Lease6Ptr& lease);
/// @brief Deletes all expired-reclaimed DHCPv4 leases.
EXPECT_TRUE(subnet1_->inPool(Lease::TYPE_V4, lease->addr_));
// Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease);
+ ASSERT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Apply restrictions on the subnet1. This should be only assigned
// to clients belonging to cable-modem class.
EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
// Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease);
+ ASSERT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Assign cable-modem class and try again. This time, we should
// offer an address from the subnet1.
EXPECT_TRUE(subnet1_->inPool(Lease::TYPE_V4, lease->addr_));
// Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease);
+ ASSERT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Apply restrictions on the pool1. This should be only assigned
// to clients belonging to cable-modem class.
EXPECT_TRUE(subnet2_->inPool(Lease::TYPE_V4, lease->addr_));
// Remove the lease so as we can start over.
- LeaseMgrFactory::instance().deleteLease(lease);
+ ASSERT_TRUE(LeaseMgrFactory::instance().deleteLease(lease));
// Assign cable-modem class and try again. This time, we should
// offer an address from the pool1.
// 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);
// 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);
// If an existing lease was specified, we need to add it to the
// database. Let's wipe any leases for that address (if any). We
// ignore any errors (previous lease may not exist)
- LeaseMgrFactory::instance().deleteLease(existing_lease);
+ (void) LeaseMgrFactory::instance().deleteLease(existing_lease);
// Let's add it.
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(existing_lease));
// If an existing lease was specified, we need to add it to the
// database. Let's wipe any leases for that address (if any). We
// ignore any errors (previous lease may not exist)
- LeaseMgrFactory::instance().deleteLease(existing_lease);
+ (void) LeaseMgrFactory::instance().deleteLease(existing_lease);
// Let's add it.
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(existing_lease));
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x08), HTYPE_ETHER));
lease->client_id_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, 0x42)));
lease->valid_lft_ = 8677;
- lease->old_valid_lft_ = 8677;
lease->cltt_ = 168256;
- lease->old_cltt_ = 168256;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 23;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = false;
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53)));
lease->valid_lft_ = 3677;
- lease->old_valid_lft_ = 3677;
lease->cltt_ = 123456;
- lease->old_cltt_ = 123456;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 73;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x2a), HTYPE_ETHER));
lease->client_id_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, 0x64)));
lease->valid_lft_ = 5412;
- lease->old_valid_lft_ = 5412;
lease->cltt_ = 234567;
- lease->old_cltt_ = 234567;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 73; // Same as lease 1
lease->fqdn_rev_ = false;
lease->fqdn_fwd_ = false;
// However, this will lead to overflows.
// @TODO: test overflow conditions when code has been fixed.
lease->valid_lft_ = 7000;
- lease->old_valid_lft_ = 7000;
lease->cltt_ = 234567;
- lease->old_cltt_ = 234567;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 37;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7736;
- lease->old_valid_lft_ = 7736;
lease->cltt_ = 222456;
- lease->old_cltt_ = 222456;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 85;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7832;
- lease->old_valid_lft_ = 7832;
lease->cltt_ = 227476;
- lease->old_cltt_ = 227476;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 175;
lease->fqdn_rev_ = false;
lease->fqdn_fwd_ = false;
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 1832;
- lease->old_valid_lft_ = 1832;
lease->cltt_ = 627476;
- lease->old_cltt_ = 627476;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 112;
lease->fqdn_rev_ = false;
lease->fqdn_fwd_ = true;
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x77)));
lease->valid_lft_ = 7975;
- lease->old_valid_lft_ = 7975;
lease->cltt_ = 213876;
- lease->old_cltt_ = 213876;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 19;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
lease->preferred_lft_ = 900;
lease->valid_lft_ = 8677;
- lease->old_valid_lft_ = 8677;
lease->cltt_ = 168256;
- lease->old_cltt_ = 168256;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 23;
lease->fqdn_fwd_ = true;
lease->fqdn_rev_ = true;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
lease->preferred_lft_ = 3600;
lease->valid_lft_ = 3677;
- lease->old_valid_lft_ = 3677;
lease->cltt_ = 123456;
- lease->old_cltt_ = 123456;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 73;
lease->fqdn_fwd_ = false;
lease->fqdn_rev_ = true;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
lease->preferred_lft_ = 1800;
lease->valid_lft_ = 5412;
- lease->old_valid_lft_ = 5412;
lease->cltt_ = 234567;
- lease->old_cltt_ = 234567;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 73; // Same as lease 1
lease->fqdn_fwd_ = false;
lease->fqdn_rev_ = false;
// @TODO: test overflow conditions when code has been fixed.
lease->preferred_lft_ = 7200;
lease->valid_lft_ = 7000;
- lease->old_valid_lft_ = 7000;
lease->cltt_ = 234567;
- lease->old_cltt_ = 234567;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 37;
lease->fqdn_fwd_ = true;
lease->fqdn_rev_ = false;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
lease->preferred_lft_ = 4800;
lease->valid_lft_ = 7736;
- lease->old_valid_lft_ = 7736;
lease->cltt_ = 222456;
- lease->old_cltt_ = 222456;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 671;
lease->fqdn_fwd_ = true;
lease->fqdn_rev_ = true;
// Same as lease 4
lease->preferred_lft_ = 5400;
lease->valid_lft_ = 7832;
- lease->old_valid_lft_ = 7832;
lease->cltt_ = 227476;
- lease->old_cltt_ = 227476;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 175;
lease->fqdn_fwd_ = false;
lease->fqdn_rev_ = true;
// Same as lease 4
lease->preferred_lft_ = 5400;
lease->valid_lft_ = 1832;
- lease->old_valid_lft_ = 1832;
lease->cltt_ = 627476;
- lease->old_cltt_ = 627476;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 112;
lease->fqdn_fwd_ = false;
lease->fqdn_rev_ = true;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
lease->preferred_lft_ = 5600;
lease->valid_lft_ = 7975;
- lease->old_valid_lft_ = 7975;
lease->cltt_ = 213876;
- lease->old_cltt_ = 213876;
+ lease->updateCurrentExpirationTime();
lease->subnet_id_ = 19;
lease->fqdn_fwd_ = false;
lease->fqdn_rev_ = true;
ASSERT_EQ(1, returned.size());
detailCompareLease(leases[1], *returned.begin());
- (void) lmptr_->deleteLease(leases[1]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[1]));
}
// Database should not let us add one that is too big
leases[1]->subnet_id_);
ASSERT_TRUE(returned);
detailCompareLease(leases[1], returned);
- (void) lmptr_->deleteLease(leases[1]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[1]));
}
// Database should not let us add one that is too big
Lease4Collection returned = lmptr_->getLease4(*leases[1]->client_id_);
ASSERT_EQ(returned.size(), 1u);
detailCompareLease(leases[1], *returned.begin());
- (void) lmptr_->deleteLease(leases[1]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[1]));
}
// Don't bother to check client IDs longer than the maximum -
leases[1]->iaid_);
ASSERT_EQ(1, returned.size());
detailCompareLease(leases[1], *returned.begin());
- (void) lmptr_->deleteLease(leases[1]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[1]));
}
// Don't bother to check DUIDs longer than the maximum - these cannot be
EXPECT_TRUE(returned3.empty());
//clean up
- (void) lmptr_->deleteLease(lease1);
- (void) lmptr_->deleteLease(lease2);
- (void) lmptr_->deleteLease(lease3);
+ ASSERT_TRUE(lmptr_->deleteLease(lease1));
+ ASSERT_TRUE(lmptr_->deleteLease(lease2));
+ ASSERT_TRUE(lmptr_->deleteLease(lease3));
//now verify we return empty for a lease that has not been stored
returned3 = lmptr_->getLeases6(*duid4);
leases[1]->subnet_id_);
ASSERT_TRUE(returned);
detailCompareLease(leases[1], returned);
- (void) lmptr_->deleteLease(leases[1]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[1]));
}
// Don't bother to check DUIDs longer than the maximum - these cannot be
EXPECT_THROW(lmptr_->updateLease4(leases[1]), isc::db::DbOperationError);
// Try updating a lease not in the database.
- lmptr_->deleteLease(leases[2]);
+ ASSERT_TRUE(lmptr_->deleteLease(leases[2]));
EXPECT_THROW(lmptr_->updateLease4(leases[2]), isc::dhcp::NoSuchLease);
}
ASSERT_TRUE(lease->client_id_);
EXPECT_EQ("17:34:e2:ff:09:92:54", lease->client_id_->toText());
EXPECT_EQ(12345678, lease->cltt_);
+ EXPECT_EQ(lease->cltt_, lease->current_cltt_);
EXPECT_EQ(3600, lease->valid_lft_);
+ EXPECT_EQ(lease->valid_lft_, lease->current_valid_lft_);
EXPECT_TRUE(lease->fqdn_fwd_);
EXPECT_TRUE(lease->fqdn_rev_);
EXPECT_EQ("urania.example.org", lease->hostname_);
ASSERT_TRUE(lease->hwaddr_);
EXPECT_EQ("hwtype=1 08:00:2b:02:3f:4e", lease->hwaddr_->toText());
EXPECT_EQ(12345678, lease->cltt_);
+ EXPECT_EQ(lease->cltt_, lease->current_cltt_);
EXPECT_EQ(800, lease->valid_lft_);
+ EXPECT_EQ(lease->valid_lft_, lease->current_valid_lft_);
EXPECT_FALSE(lease->fqdn_fwd_);
EXPECT_FALSE(lease->fqdn_rev_);
EXPECT_EQ("urania.example.org", lease->hostname_);
ASSERT_TRUE(lease->hwaddr_);
EXPECT_EQ("hwtype=1 08:00:2b:02:3f:4e", lease->hwaddr_->toText());
EXPECT_EQ(12345678, lease->cltt_);
+ EXPECT_EQ(lease->cltt_, lease->current_cltt_);
EXPECT_EQ(600, lease->valid_lft_);
+ EXPECT_EQ(lease->valid_lft_, lease->current_valid_lft_);
EXPECT_FALSE(lease->fqdn_fwd_);
EXPECT_FALSE(lease->fqdn_rev_);
EXPECT_EQ("urania.example.org", lease->hostname_);