]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1488] backport #1434 to 1.8.0
authorRazvan Becheriu <razvan@isc.org>
Thu, 5 Nov 2020 07:39:34 +0000 (09:39 +0200)
committerRazvan Becheriu <razvan@isc.org>
Thu, 5 Nov 2020 16:23:27 +0000 (18:23 +0200)
25 files changed:
ChangeLog
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/rebind_unittest.cc
src/hooks/dhcp/high_availability/ha_service.cc
src/hooks/dhcp/lease_cmds/lease_cmds.cc
src/hooks/dhcp/lease_cmds/tests/lease_cmds_unittest.cc
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/cql_lease_mgr.h
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/lease.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_utils.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/lease_unittest.cc

index ce5f2b557e8182c059b00d0c9e5fd345d52d3e89..3b48f1f05b2c1a4fe959ead4ddcd750ae480ce50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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
@@ -11,6 +19,7 @@
        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
 
index 9d889cc3c9aa816782e21ab1bbf9590df2b7f0a6..7c1cbab9580cf5bad7c4e3719e3f4aa606c85bf2 100644 (file)
@@ -1892,8 +1892,7 @@ TEST_F(Dhcpv4SrvTest, RenewBasic) {
     // 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));
 }
 
@@ -2016,8 +2015,7 @@ TEST_F(Dhcpv4SrvTest, RenewDefaultLifetime) {
     // 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));
 }
 
@@ -2063,8 +2061,7 @@ TEST_F(Dhcpv4SrvTest, RenewHintLifetime) {
     // 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));
 }
 
@@ -2110,8 +2107,7 @@ TEST_F(Dhcpv4SrvTest, RenewMinLifetime) {
     // 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));
 }
 
@@ -2156,8 +2152,7 @@ TEST_F(Dhcpv4SrvTest, RenewMaxLifetime) {
     // 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));
 }
 
index 6519d28b776cad1474ee8cd13bbc73abf1b14560..79c5cae8b8f09eb54de1d3e0929a5d1f3fd2ad58 100644 (file)
@@ -1844,8 +1844,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSimple) {
     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.
@@ -1916,8 +1915,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSkip) {
     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.
index a8053657072d13ebe8bf045e72cd8383f9feb7ee..8108b8c225ceb086b6c07b6124fd4c1a06c39b56 100644 (file)
@@ -1060,9 +1060,9 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
     // 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
@@ -1129,8 +1129,8 @@ TEST_F(Dhcpv6SrvTest, pdRequestBasic) {
     // 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));
 }
 
index b15deea1740bf6b48ab067e5ec98da95503d1a5d..e9591cecdb3e1eb2a1a343b65c8ed266035eff5d 100644 (file)
@@ -435,8 +435,8 @@ Dhcpv6SrvTest::testRenewBasic(Lease::Type type,
     // 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));
 }
 
@@ -759,8 +759,7 @@ Dhcpv6SrvTest::testReleaseReject(Lease::Type type, const IOAddress& addr) {
     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));
 }
 
index 50e95fd214da444a494e446f85a1e51459ba88c5..7f29e135d8b1356f45de7576059d01c3a7a83a77 100644 (file)
@@ -2888,8 +2888,9 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
     // 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.
@@ -4012,9 +4013,10 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
     // 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);
index 770673165b93d7b6af6b8ae27bd32fa50fc40e25..8fa183040d25fac3d4b1876dc3966df362452e35 100644 (file)
@@ -472,9 +472,9 @@ TEST_F(RebindTest, directClientLostLease) {
     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());
@@ -607,9 +607,9 @@ TEST_F(RebindTest, relayedClientLostLease) {
     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());
index 159a2cb377dca01023a869b68d2ca98c92787f03..03ad2c85972d1b7bac9adead6e05473d09cc2db9 100644 (file)
@@ -1694,6 +1694,10 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
                                 } 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 {
@@ -1723,6 +1727,10 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
                                 } 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 {
index 80c0859560a470df9ced419a36b0d08a0adec396..d11788c0ed631078d6d1f75fadfecd6dcedc2ff4 100644 (file)
@@ -654,7 +654,21 @@ LeaseCmdsImpl::addOrUpdate4(Lease4Ptr lease, bool force_create) {
         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);
 }
@@ -672,7 +686,21 @@ LeaseCmdsImpl::addOrUpdate6(Lease6Ptr lease, bool force_create) {
         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);
 }
index 2cd36c87cc99b0aa4dcdc1cee7b774feb14a0255..214eef12fd1a8d981f9f06c0189d936d68c7cfa5 100644 (file)
@@ -417,6 +417,7 @@ public:
         // 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;
         }
@@ -457,6 +458,7 @@ public:
         // 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;
         }
@@ -3646,7 +3648,9 @@ TEST_F(LeaseCmdsTest, Lease4UpdateNoLease) {
         "        \"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);
 }
 
@@ -3918,7 +3922,9 @@ TEST_F(LeaseCmdsTest, Lease4UpdateDoNotForceCreate) {
         "        \"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);
@@ -4367,7 +4373,9 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
         "        \"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);
@@ -4490,7 +4498,9 @@ TEST_F(LeaseCmdsTest, Lease6UpdateDoNotForceCreate) {
         "        \"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);
index d85587f4941c363aef9cb0651f3233262c4905a9..e0cf89b223a853acb08ab4632e554cae3aef6253 100644 (file)
@@ -52,9 +52,9 @@ public:
     ///
     /// @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.
@@ -91,7 +91,7 @@ protected:
     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_;
@@ -633,9 +633,10 @@ CqlLease4Exchange::createBindForUpdate(const Lease4Ptr &lease, AnyArray &data,
         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(&current_expire_);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
                   "CqlLease4Exchange::createBindUpdate(): "
@@ -664,9 +665,10 @@ CqlLease4Exchange::createBindForDelete(const Lease4Ptr &lease, AnyArray &data,
         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(&current_expire_);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
                   "CqlLease4Exchange::createBindForDelete(): "
@@ -1424,9 +1426,10 @@ CqlLease6Exchange::createBindForUpdate(const Lease6Ptr &lease, AnyArray &data,
         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(&current_expire_);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
                   "CqlLease6Exchange::createBindForUpdate(): "
@@ -1461,9 +1464,10 @@ CqlLease6Exchange::createBindForDelete(const Lease6Ptr &lease, AnyArray &data,
         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(&current_expire_);
     } catch (const Exception &ex) {
         isc_throw(DbOperationError,
                   "CqlLease6Exchange::createBindForDelete(): "
@@ -1596,8 +1600,9 @@ CqlLease6Exchange::retrieve() {
 
         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_;
 
@@ -2145,8 +2150,9 @@ CqlLeaseMgr::addLease(const Lease4Ptr &lease) {
         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;
 }
@@ -2168,8 +2174,9 @@ CqlLeaseMgr::addLease(const Lease6Ptr &lease) {
         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;
 }
@@ -2618,8 +2625,8 @@ CqlLeaseMgr::updateLease4(const Lease4Ptr &lease) {
         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
@@ -2637,8 +2644,8 @@ CqlLeaseMgr::updateLease6(const Lease6Ptr &lease) {
         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
index b01d040035638f4b89f631c9e220efa8faabc8d1..b0db0b33994feafc081cd27093d2a2c91e481382 100644 (file)
@@ -410,6 +410,15 @@ public:
     ///        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.
@@ -423,6 +432,15 @@ public:
 
     /// @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.
@@ -430,6 +448,15 @@ public:
     /// @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.
@@ -437,6 +464,15 @@ public:
     /// @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.
index c9c8ba969940af3195d503e75cc235c8fef1253b..38495bfae2b9566e785f5fac76a0479f6e0b5fb0 100644 (file)
@@ -40,8 +40,8 @@ Lease::Lease(const isc::asiolink::IOAddress& addr,
              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) {
 }
@@ -274,6 +274,19 @@ Lease::fromElementCommon(const LeasePtr& lease, const data::ConstElementPtr& ele
         }
         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)
@@ -377,9 +390,9 @@ Lease4::operator=(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_;
@@ -480,7 +493,7 @@ Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
     }
 
     cltt_ = time(NULL);
-    old_cltt_ = cltt_;
+    current_cltt_ = cltt_;
 }
 
 Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
@@ -497,7 +510,7 @@ Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
     }
 
     cltt_ = time(NULL);
-    old_cltt_ = cltt_;
+    current_cltt_ = cltt_;
 }
 
 Lease6::Lease6()
@@ -586,9 +599,9 @@ Lease4::operator==(const Lease4& other) const {
             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_ &&
@@ -606,9 +619,9 @@ Lease6::operator==(const Lease6& other) const {
             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_ &&
index a9e27fd023e645834a40c8ec79f12132d9314461..5dbee9823acc7bc502364c2eca36ce43a56add7f 100644 (file)
@@ -97,6 +97,13 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement {
     /// @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,
@@ -116,10 +123,10 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement {
     /// 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
     ///
@@ -127,11 +134,11 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement {
     /// 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
     ///
@@ -230,6 +237,27 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement {
     /// 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.
index 801d4fe82fe92df9ecd49b70610b0a79148012cb..349e3bfcbdc9606c3fbe5b1b0b04efc555246367 100644 (file)
@@ -704,6 +704,11 @@ Memfile_LeaseMgr::addLeaseInternal(const Lease4Ptr& lease) {
     }
 
     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);
 }
 
@@ -735,6 +740,11 @@ Memfile_LeaseMgr::addLeaseInternal(const Lease6Ptr& lease) {
     }
 
     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);
 }
 
@@ -1409,20 +1419,31 @@ Memfile_LeaseMgr::updateLease4Internal(const Lease4Ptr& lease) {
     // 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)));
 }
@@ -1445,20 +1466,31 @@ Memfile_LeaseMgr::updateLease6Internal(const Lease6Ptr& 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)));
 }
@@ -1492,6 +1524,13 @@ Memfile_LeaseMgr::deleteLeaseInternal(const Lease4Ptr& 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);
@@ -1527,6 +1566,13 @@ Memfile_LeaseMgr::deleteLeaseInternal(const Lease6Ptr& lease) {
             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);
index aa996ca782154f0949bfcd5798aac5e62ecba160..5975e5ff5309d1141c850afa907915b5da83dc54 100644 (file)
@@ -403,7 +403,16 @@ public:
     ///
     /// @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.
@@ -413,7 +422,16 @@ public:
     ///
     /// @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.
@@ -421,6 +439,15 @@ public:
     /// @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.
@@ -428,6 +455,15 @@ public:
     /// @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.
@@ -660,11 +696,33 @@ private:
     /// @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.
@@ -672,6 +730,15 @@ private:
     /// @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.
@@ -679,6 +746,15 @@ private:
     /// @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.
index 6d358963451b1a026ae6fcd79598a24e08937634..2e9a6a714b25515bb04dd62346ba9246e383d384 100644 (file)
@@ -1425,8 +1425,9 @@ public:
             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_;
@@ -1871,8 +1872,9 @@ MySqlLeaseMgr::addLease(const Lease4Ptr& lease) {
     // ... 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);
 }
@@ -1893,8 +1895,9 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
     // ... 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);
 }
@@ -2758,7 +2761,8 @@ MySqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
     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);
@@ -2769,8 +2773,8 @@ MySqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
     // 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
@@ -2805,7 +2809,8 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     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);
@@ -2816,8 +2821,8 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     // 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
@@ -2863,7 +2868,8 @@ MySqlLeaseMgr::deleteLease(const Lease4Ptr& lease) {
     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);
@@ -2909,7 +2915,8 @@ MySqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
     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);
index 29471bb0d5ebc02bc3e7877e5f44e5b0e9bd4466..64af58ad6c04152fa001249c38afa7b2148558ba 100644 (file)
@@ -453,6 +453,15 @@ public:
     ///        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.
@@ -466,6 +475,15 @@ public:
     ///        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.
@@ -473,6 +491,15 @@ public:
     /// @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.
@@ -480,6 +507,15 @@ public:
     /// @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.
index fd6ab7765deee51b6fd46672721f0936e60aa312..8d9ebcb6346cdf43ae73125886ac0d803813265a 100644 (file)
@@ -911,8 +911,9 @@ public:
                                                         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;
 
@@ -1306,8 +1307,9 @@ PgSqlLeaseMgr::addLease(const Lease4Ptr& lease) {
     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);
 }
@@ -1327,8 +1329,9 @@ PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
 
     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);
 }
@@ -1982,15 +1985,15 @@ PgSqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
     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
@@ -2013,15 +2016,15 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     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
@@ -2055,8 +2058,8 @@ PgSqlLeaseMgr::deleteLease(const Lease4Ptr& lease) {
     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);
@@ -2090,8 +2093,8 @@ PgSqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
     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);
index 6339592b09a1ad7903bcca4d703ac5698693be5b..e221854e9faa3b3ef24021871f8b091cad24593f 100644 (file)
@@ -428,6 +428,15 @@ public:
     ///        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.
@@ -441,6 +450,15 @@ public:
     ///        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.
@@ -448,6 +466,15 @@ public:
     /// @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.
@@ -455,6 +482,15 @@ public:
     /// @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.
index 64c8f0a0afa857d76108e1b52d76ac807e96106e..29a0017ef073f3955db68afdadf2224aab463924 100644 (file)
@@ -1459,7 +1459,7 @@ TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkClassification) {
     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.
@@ -1475,7 +1475,7 @@ TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkClassification) {
     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.
@@ -1512,7 +1512,7 @@ TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkPoolClassification) {
     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.
@@ -1528,7 +1528,7 @@ TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkPoolClassification) {
     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.
index 34c316a50fef44f39f4ee2e18fa36089887d0022..a2113f405807959695362cd29b8eb981844b4c55 100644 (file)
@@ -3610,6 +3610,7 @@ TEST_F(AllocEngine6Test, globalHostReservedAddress) {
     // 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);
@@ -3674,6 +3675,7 @@ TEST_F(AllocEngine6Test, globalHostReservedPrefix) {
     // 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);
index c9446c3fa4b02b9a05592e19e88fb7a3649b8d16..9de1ea699043788f0736a3f2252012dae593df09 100644 (file)
@@ -94,7 +94,7 @@ AllocEngine4Test::testReuseLease4(const AllocEnginePtr& engine,
         // 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));
@@ -550,7 +550,7 @@ AllocEngine6Test::testReuseLease6(const AllocEnginePtr& engine,
         // 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));
index 10ac3f21fa807099f4b655ffbcf2c5fdc1627c0a..9d7a3f4d843f1926b9d44c6982d56ca4e811d804 100644 (file)
@@ -92,9 +92,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -105,9 +104,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -117,9 +115,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -136,9 +133,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         //  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;
@@ -150,9 +146,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -165,9 +160,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -180,9 +174,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -193,9 +186,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         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;
@@ -226,9 +218,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         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;
@@ -241,9 +232,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         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;
@@ -256,9 +246,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         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;
@@ -280,9 +269,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         // @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;
@@ -296,9 +284,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         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;
@@ -313,9 +300,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         // 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;
@@ -331,9 +317,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         // 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;
@@ -347,9 +332,8 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         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;
@@ -1103,7 +1087,7 @@ GenericLeaseMgrTest::testGetLease4HWAddrSize() {
 
         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
@@ -1180,7 +1164,7 @@ GenericLeaseMgrTest::testGetLease4HWAddrSubnetIdSize() {
                                                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
@@ -1260,7 +1244,7 @@ GenericLeaseMgrTest::testGetLease4ClientIdSize() {
         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 -
@@ -1587,7 +1571,7 @@ GenericLeaseMgrTest::testGetLeases6DuidSize() {
                                                        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
@@ -1797,9 +1781,9 @@ GenericLeaseMgrTest::testGetLeases6Duid() {
     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);
@@ -1830,7 +1814,7 @@ GenericLeaseMgrTest::testGetLease6DuidIaidSubnetIdSize() {
                                                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
@@ -1890,7 +1874,7 @@ GenericLeaseMgrTest::testUpdateLease4() {
     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);
 }
 
index 4b490ec96d099dc2ac1f9ee62ad9d9086c5b83e4..92e1d21a4f45f51222b078ec86ba6cc91ee98315 100644 (file)
@@ -577,7 +577,9 @@ TEST_F(Lease4Test, fromElement) {
     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_);
@@ -1249,7 +1251,9 @@ TEST(Lease6Test, fromElementNA) {
     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_);
@@ -1295,7 +1299,9 @@ TEST(Lease6Test, fromElementPD) {
     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_);