]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[897-add-infinite-valid-lifetime-for-bootp] Reported previous changes
authorFrancis Dupont <fdupont@isc.org>
Sun, 22 Sep 2019 17:23:40 +0000 (19:23 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 5 Nov 2019 10:24:45 +0000 (11:24 +0100)
16 files changed:
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp6/dhcp6_srv.cc
src/lib/cql/cql_exchange.cc
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/csv_lease_file4.cc
src/lib/dhcpsrv/csv_lease_file6.cc
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/lease.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h
src/lib/dhcpsrv/tests/lease_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc

index 1b4b155561d14d32cae10713275cc01dd46a37db..3edfd8231d5b848513ceb613732f86ea1cb7a958 100644 (file)
@@ -2182,11 +2182,16 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
             LOG_INFO(lease4_logger, DHCP4_LEASE_ADVERT)
                 .arg(query->getLabel())
                 .arg(lease->addr_.toText());
-        } else {
+        } else if (lease->valid_lft_ != Lease::INFINITY_LFT) {
             LOG_INFO(lease4_logger, DHCP4_LEASE_ALLOC)
                 .arg(query->getLabel())
                 .arg(lease->addr_.toText())
                 .arg(lease->valid_lft_);
+        } else {
+            LOG_INFO(lease4_logger, DHCP4_LEASE_ALLOC)
+                .arg(query->getLabel())
+                .arg(lease->addr_.toText())
+                .arg("infinity");
         }
 
         // We're logging this here, because this is the place where we know
index d1e02821ae738324a58f9d574acafac0b0405d89..d61922493eb3c8196c91a4044c2ba54acfed6a12 100644 (file)
@@ -1900,12 +1900,18 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
                 .arg(query->getLabel())
                 .arg(lease->addr_.toText())
                 .arg(ia->getIAID());
-        } else {
+        } else if (lease->valid_lft_ != Lease::INFINITY_LFT) {
             LOG_INFO(lease6_logger, DHCP6_LEASE_ALLOC)
                 .arg(query->getLabel())
                 .arg(lease->addr_.toText())
                 .arg(ia->getIAID())
                 .arg(lease->valid_lft_);
+        } else {
+            LOG_INFO(lease6_logger, DHCP6_LEASE_ALLOC)
+                .arg(query->getLabel())
+                .arg(lease->addr_.toText())
+                .arg(ia->getIAID())
+                .arg("infinity");
         }
         LOG_DEBUG(lease6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_LEASE_DATA)
             .arg(query->getLabel())
@@ -2022,13 +2028,20 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& /*answer*/,
                     .arg((*l)->addr_.toText())
                     .arg(static_cast<int>((*l)->prefixlen_))
                     .arg(ia->getIAID());
-            } else {
+            } else if ((*l)->valid_lft_ != Lease::INFINITY_LFT) {
                 LOG_INFO(lease6_logger, DHCP6_PD_LEASE_ALLOC)
                     .arg(query->getLabel())
                     .arg((*l)->addr_.toText())
                     .arg(static_cast<int>((*l)->prefixlen_))
                     .arg(ia->getIAID())
                     .arg((*l)->valid_lft_);
+            } else {
+                LOG_INFO(lease6_logger, DHCP6_PD_LEASE_ALLOC)
+                    .arg(query->getLabel())
+                    .arg((*l)->addr_.toText())
+                    .arg(static_cast<int>((*l)->prefixlen_))
+                    .arg(ia->getIAID())
+                    .arg("infinity");
             }
 
             boost::shared_ptr<Option6IAPrefix>
index 61d0bb707ad8d3a1d191514a0f6f9700603438f2..d28183496e5a0e99f3efd7f10ccce0c42f194b7c 100644 (file)
@@ -742,17 +742,10 @@ void
 CqlExchange::convertToDatabaseTime(const time_t& cltt,
                                    const uint32_t& valid_lifetime,
                                    cass_int64_t& expire) {
-    // Calculate expire time. Store it in the 64-bit value so as we can
-    // detect overflows.
+    // Calculate expire time.
     cass_int64_t expire_time = static_cast<cass_int64_t>(cltt) +
             static_cast<cass_int64_t>(valid_lifetime);
 
-    if (expire_time > DatabaseConnection::MAX_DB_TIME) {
-        isc_throw(BadValue,
-                  "CqlExchange(): convertToDatabaseTime(): time value "
-                      << expire_time << " is too large");
-    }
-
     expire = expire_time;
 }
 
@@ -760,11 +753,7 @@ void
 CqlExchange::convertFromDatabaseTime(const cass_int64_t& expire,
                                      const cass_int64_t& valid_lifetime,
                                      time_t& cltt) {
-    /// @todo: Although 2037 is still far away, there are people who use infinite
-    /// lifetimes. Cassandra doesn't have to support it right now, but at least
-    /// we should be able to detect a problem.
-
-    // Convert to local time
+    // Convert to local time.
     cltt = static_cast<time_t>(expire - valid_lifetime);
 }
 
index 55913f554d95e86dcd2e79b865f07a70ff21d4a1..2803e56f8755a6292a714c7eb49edc299b599a65 100644 (file)
@@ -305,6 +305,7 @@ StatementMap CqlLease4Exchange::tagged_statements_{
       "FROM lease4 "
       "WHERE state = ? "
       "AND expire < ? "
+      "AND valid_lifetime < 4294967295 "
       "LIMIT ? "
       "ALLOW FILTERING "}},
 
@@ -1019,6 +1020,7 @@ StatementMap CqlLease6Exchange::tagged_statements_ = {
       "FROM lease6 "
       "WHERE state = ? "
       "AND expire < ? "
+      "AND valid_lifetime < 4294967295 "
       "LIMIT ? "
       "ALLOW FILTERING "}},
 
index a696377c99e5eeba67e500a8420ec60f609ae986..fc3cf1886a11a84f69ae7a067636da828074fc74 100644 (file)
@@ -60,7 +60,7 @@ CSVLeaseFile4::append(const Lease4& lease) {
     }
 
     row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
-    row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_ + lease.valid_lft_));
+    row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_) + lease.valid_lft_);
     row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
     row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
     row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
index a1119a6177422cde20e2d06d041c9f2e69413a50..c73b7d9aa6e021ed921d0a7fef982f910e735c57 100644 (file)
@@ -46,7 +46,7 @@ CSVLeaseFile6::append(const Lease6& lease) {
     row.writeAt(getColumnIndex("address"), lease.addr_.toText());
     row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
     row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
-    row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_ + lease.valid_lft_));
+    row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_) + lease.valid_lft_);
     row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
     row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_);
     row.writeAt(getColumnIndex("lease_type"), lease.type_);
index d504a95eeffaee331b91c054ef6b56e3028db57a..61b440e40c80831cb15077f67ca3da3115f8999d 100644 (file)
@@ -93,7 +93,7 @@ Lease::basicStatesToText(const uint32_t state) {
 
 bool
 Lease::expired() const {
-    return (getExpirationTime() < time(NULL));
+    return ((valid_lft_ != INFINITY_LFT) && (getExpirationTime() < time(NULL)));
 }
 
 bool
@@ -528,9 +528,13 @@ Lease6::toText() const {
            << "Address:       " << addr_ << "\n"
            << "Prefix length: " << static_cast<int>(prefixlen_) << "\n"
            << "IAID:          " << iaid_ << "\n"
-           << "Pref life:     " << preferred_lft_ << "\n"
-           << "Valid life:    " << valid_lft_ << "\n"
-           << "Cltt:          " << cltt_ << "\n"
+           << "Pref life:     " << preferred_lft_ << "\n";
+    if (valid_lft_ != INFINITY_LFT) {
+        stream << "Valid life:    " << valid_lft_ << "\n";
+    } else {
+        stream << "Valid life:    " << "infinity" << "\n";
+    }
+    stream << "Cltt:          " << cltt_ << "\n"
            << "DUID:          " << (duid_?duid_->toText():"(none)") << "\n"
            << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)") << "\n"
            << "Subnet ID:     " << subnet_id_ << "\n"
@@ -547,9 +551,13 @@ std::string
 Lease4::toText() const {
     ostringstream stream;
 
-    stream << "Address:       " << addr_ << "\n"
-           << "Valid life:    " << valid_lft_ << "\n"
-           << "Cltt:          " << cltt_ << "\n"
+    stream << "Address:       " << addr_ << "\n";
+    if (valid_lft_ != INFINITY_LFT) {
+        stream << "Valid life:    " << valid_lft_ << "\n";
+    } else {
+        stream << "Valid life:    " << "infinity" << "\n";
+    }
+    stream << "Cltt:          " << cltt_ << "\n"
            << "Hardware addr: " << (hwaddr_ ? hwaddr_->toText(false) : "(none)") << "\n"
            << "Client id:     " << (client_id_ ? client_id_->toText() : "(none)") << "\n"
            << "Subnet ID:     " << subnet_id_ << "\n"
index 1e3086354b228084e52e213772d5fcaaeae5b197..4c82d0a5b9a7ed637f5a0f584b284e7e91e56aea 100644 (file)
@@ -34,6 +34,9 @@ typedef boost::shared_ptr<Lease> LeasePtr;
 /// leases.
 struct Lease : public isc::data::UserContext, public isc::data::CfgToElement {
 
+    /// @brief Infinity (means static, i.e. never expire)
+    static const uint32_t INFINITY_LFT = 0xffffffff;
+
     /// @brief Type of lease or pool
     typedef enum {
         TYPE_NA = 0, ///< the lease contains non-temporary IPv6 address
index 599045c86096ac6abf6f5e16a587ec0da7def1f8..6308965d3f29683a0cba4b200d84ba65e7f7dcc5 100644 (file)
@@ -172,7 +172,8 @@ tagged_statements = { {
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "state, user_context "
                             "FROM lease4 "
-                            "WHERE state != ? AND expire < ? "
+                            "WHERE state != ? AND expire < ?"
+                            " AND valid_lifetime != 4294967295 "
                             "ORDER BY expire ASC "
                             "LIMIT ?"},
     {MySqlLeaseMgr::GET_LEASE6,
@@ -257,7 +258,8 @@ tagged_statements = { {
                         "hwaddr, hwtype, hwaddr_source, "
                         "state, user_context "
                             "FROM lease6 "
-                            "WHERE state != ? AND expire < ? "
+                            "WHERE state != ? AND expire < ?"
+                            " AND valid_lifetime != 4294967295 "
                             "ORDER BY expire ASC "
                             "LIMIT ?"},
     {MySqlLeaseMgr::INSERT_LEASE4,
@@ -555,7 +557,12 @@ public:
             // expiry time (expire).  The relationship is given by:
             //
             // expire = cltt_ + valid_lft_
-            MySqlConnection::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
+            // Avoid overflow
+            uint32_t valid_lft = lease_->valid_lft_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            MySqlConnection::convertToDatabaseTime(lease_->cltt_, valid_lft,
                                                    expire_);
             bind_[4].buffer_type = MYSQL_TYPE_TIMESTAMP;
             bind_[4].buffer = reinterpret_cast<char*>(&expire_);
@@ -760,7 +767,12 @@ public:
         // Convert times received from the database to times for the lease
         // structure
         time_t cltt = 0;
-        MySqlConnection::convertFromDatabaseTime(expire_, valid_lifetime_, cltt);
+        // Recover from overflow
+        uint32_t valid_lft = valid_lifetime_;
+        if (valid_lft == Lease::INFINITY_LFT) {
+            valid_lft = 0;
+        }
+        MySqlConnection::convertFromDatabaseTime(expire_, valid_lft, cltt);
 
         if (client_id_null_ == MLM_TRUE) {
             // There's no client-id, so we pass client-id_length_ set to 0
@@ -987,7 +999,12 @@ public:
             /// expiry time (expire).  The relationship is given by:
             //
             // expire = cltt_ + valid_lft_
-            MySqlConnection::convertToDatabaseTime(lease_->cltt_, lease_->valid_lft_,
+            // Avoid overflow
+            uint32_t valid_lft = lease_->valid_lft_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            MySqlConnection::convertToDatabaseTime(lease_->cltt_, valid_lft,
                                                    expire_);
             bind_[3].buffer_type = MYSQL_TYPE_TIMESTAMP;
             bind_[3].buffer = reinterpret_cast<char*>(&expire_);
@@ -1400,7 +1417,12 @@ public:
                                     subnet_id_, fqdn_fwd_, fqdn_rev_,
                                     hostname, hwaddr, prefixlen_));
         time_t cltt = 0;
-        MySqlConnection::convertFromDatabaseTime(expire_, valid_lifetime_, cltt);
+        // Recover from overflow
+        uint32_t valid_lft = valid_lifetime_;
+        if (valid_lft == Lease::INFINITY_LFT) {
+            valid_lft = 0;
+        }
+        MySqlConnection::convertFromDatabaseTime(expire_, valid_lft, cltt);
         result->cltt_ = cltt;
 
         // Set state.
index 1ade37364974a196e1c400e8a6e0592f1b6b69ff..205858e00927aab6625ffd94f064dd074ef12d3b 100644 (file)
@@ -155,7 +155,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context "
       "FROM lease4 "
-      "WHERE state != $1 AND expire < $2 "
+      "WHERE state != $1 AND expire < $2 AND valid_lifetime != 4294967295 "
       "ORDER BY expire "
       "LIMIT $3"},
 
@@ -259,7 +259,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context "
       "FROM lease6 "
-      "WHERE state != $1 AND expire < $2 "
+      "WHERE state != $1 AND expire < $2 AND valid_lifetime != 4294967295 "
       "ORDER BY expire "
       "LIMIT $3"},
 
@@ -490,7 +490,12 @@ public:
             valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
             bind_array.add(valid_lifetime_str_);
 
-            expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
+            // Avoid overflow
+            uint32_t valid_lft = lease_->valid_lft_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            expire_str_ = convertToDatabaseTime(lease->cltt_, valid_lft);
             bind_array.add(expire_str_);
 
             subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
@@ -545,7 +550,12 @@ public:
 
             getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
 
-            cltt_ = expire_ - valid_lifetime_;
+            // Recover from overflow
+            uint32_t valid_lft = valid_lifetime_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            cltt_ = expire_ - valid_lft;
 
             getColumnValue(r, row, FQDN_FWD_COL, fqdn_fwd_);
 
@@ -721,7 +731,12 @@ public:
             valid_lifetime_str_ = boost::lexical_cast<std::string>(lease->valid_lft_);
             bind_array.add(valid_lifetime_str_);
 
-            expire_str_ = convertToDatabaseTime(lease->cltt_, lease_->valid_lft_);
+            // Avoid overflow
+            uint32_t valid_lft = lease_->valid_lft_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            expire_str_ = convertToDatabaseTime(lease->cltt_, valid_lft);
             bind_array.add(expire_str_);
 
             subnet_id_str_ = boost::lexical_cast<std::string>(lease->subnet_id_);
@@ -827,7 +842,12 @@ public:
             expire_ = convertFromDatabaseTime(getRawColumnValue(r, row,
                                                                 EXPIRE_COL));
 
-            cltt_ = expire_ - valid_lifetime_;
+            // Recover from overflow
+            uint32_t valid_lft = valid_lifetime_;
+            if (valid_lft == Lease::INFINITY_LFT) {
+                valid_lft = 0;
+            }
+            cltt_ = expire_ - valid_lft;
 
             getColumnValue(r, row , SUBNET_ID_COL, subnet_id_);
 
index d07f33562969b83880089192305a518a097650f5..272064768cd67382ad91eb960b9428344fddd699 100644 (file)
@@ -503,9 +503,9 @@ TEST_F(CqlLeaseMgrTest, basicLease4) {
     testBasicLease4();
 }
 
-/// @brief Check that Lease4 code safely handles invalid dates.
-TEST_F(CqlLeaseMgrTest, maxDate4) {
-    testMaxDate4();
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(CqlLeaseMgrTest, infiniteLifeTime4) {
+    testInfiniteLifeTime4();
 }
 
 /// @brief Lease4 update tests
@@ -625,6 +625,12 @@ TEST_F(CqlLeaseMgrTest, getExpiredLeases4) {
     testCqlGetExpiredLeases4();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv4
+/// leases will never expire.
+TEST_F(CqlLeaseMgrTest, staticLeases4) {
+    testStaticLeases4();
+}
+
 /// @brief Check that expired reclaimed DHCPv4 leases are removed.
 TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
     testDeleteExpiredReclaimedLeases4();
@@ -648,9 +654,9 @@ TEST_F(CqlLeaseMgrTest, basicLease6) {
     testBasicLease6();
 }
 
-/// @brief Check that Lease6 code safely handles invalid dates.
-TEST_F(CqlLeaseMgrTest, maxDate6) {
-    testMaxDate6();
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(CqlLeaseMgrTest, infiniteLifeTime6) {
+    testInfiniteLifeTime6();
 }
 
 /// @brief Verify that too long hostname for Lease6 is not accepted.
@@ -774,6 +780,12 @@ TEST_F(CqlLeaseMgrTest, getExpiredLeases6) {
     testCqlGetExpiredLeases6();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv6
+/// leases will never expire.
+TEST_F(CqlLeaseMgrTest, staticLeases6) {
+    testStaticLeases6();
+}
+
 /// @brief Check that expired reclaimed DHCPv6 leases are removed.
 TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases6) {
     testDeleteExpiredReclaimedLeases6();
index c140d8c90ffdeca480b2dc36a46508bc9bd97ac5..c60b0b6ac2de3f6b382d3f6136d58598dcfe4313 100644 (file)
@@ -127,7 +127,7 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         // The times used in the next tests are deliberately restricted - we
         // should be able to cope with valid lifetimes up to 0xffffffff.
         //  However, this will lead to overflows.
-        // @TODO: test overflow conditions when code has been fixed
+        // @TODO: test overflow conditions as now the code was fixed.
         lease->valid_lft_ = 7000;
         lease->cltt_ = 234567;
         lease->subnet_id_ = 37;
@@ -254,7 +254,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         // The times used in the next tests are deliberately restricted - we
         // should be able to cope with valid lifetimes up to 0xffffffff.
         //  However, this will lead to overflows.
-        // @TODO: test overflow conditions when code has been fixed
+        // @TODO: test overflow conditions as now the code was fixed.
         lease->preferred_lft_ = 7200;
         lease->valid_lft_ = 7000;
         lease->cltt_ = 234567;
@@ -712,6 +712,23 @@ GenericLeaseMgrTest::testMaxDate4() {
     detailCompareLease(leases[1], l_returned);
 }
 
+void
+GenericLeaseMgrTest::testInfiniteLifeTime4() {
+    // Get the leases to be used for the test.
+    vector<Lease4Ptr> leases = createLeases4();
+    Lease4Ptr lease = leases[1];
+
+    // Set valid_lft_ to infinite, cllt_ to now.
+    lease->valid_lft_ = Lease::INFINITY_LFT;
+    lease->cltt_ = time(NULL);
+
+    // Insert should not throw.
+    EXPECT_TRUE(lmptr_->addLease(leases[1]));
+    Lease4Ptr l_returned = lmptr_->getLease4(ioaddress4_[1]);
+    ASSERT_TRUE(l_returned);
+    detailCompareLease(leases[1], l_returned);
+}
+
 void
 GenericLeaseMgrTest::testBasicLease4() {
     // Get the leases to be used for the test.
@@ -883,6 +900,23 @@ GenericLeaseMgrTest::testMaxDate6() {
     detailCompareLease(leases[1], l_returned);
 }
 
+void
+GenericLeaseMgrTest::testInfiniteLifeTime6() {
+    // Get the leases to be used for the test.
+    vector<Lease6Ptr> leases = createLeases6();
+    Lease6Ptr lease = leases[1];
+
+    // Set valid_lft_ to infinite, cllt_ to now.
+    lease->valid_lft_ = Lease::INFINITY_LFT;
+    lease->cltt_ = time(NULL);
+
+    // Insert should not throw.
+    EXPECT_TRUE(lmptr_->addLease(leases[1]));
+    Lease6Ptr l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]);
+    ASSERT_TRUE(l_returned);
+    detailCompareLease(leases[1], l_returned);
+}
+
 // Checks whether a MAC address can be stored and retrieved together with
 // a lease.
 void
@@ -2218,6 +2252,48 @@ GenericLeaseMgrTest::testGetExpiredLeases6() {
     }
 }
 
+void
+GenericLeaseMgrTest::testStaticLeases4() {
+    // Get the leases to be used for the test.
+    vector<Lease4Ptr> leases = createLeases4();
+    Lease4Ptr lease = leases[1];
+
+    // Set valid_lft_ to infinite. Leave the small cltt even it won't happen
+    // in the real world to catch more possible issues.
+    lease->valid_lft_ = Lease::INFINITY_LFT;
+
+    // Add it to the database.
+    ASSERT_TRUE(lmptr_->addLease(leases[1]));
+
+    // Retrieve at most 10 expired leases.
+    Lease4Collection expired_leases;
+    ASSERT_NO_THROW(lmptr_->getExpiredLeases4(expired_leases, 10));
+
+    // No lease should be returned.
+    EXPECT_EQ(0, expired_leases.size());
+}
+
+void
+GenericLeaseMgrTest::testStaticLeases6() {
+    // Get the leases to be used for the test.
+    vector<Lease6Ptr> leases = createLeases6();
+    Lease6Ptr lease = leases[1];
+
+    // Set valid_lft_ to infinite. Leave the small cltt even it won't happen
+    // in the real world to catch more possible issues.
+    lease->valid_lft_ = Lease::INFINITY_LFT;
+
+    // Add it to the database.
+    ASSERT_TRUE(lmptr_->addLease(leases[1]));
+
+    // Retrieve at most 10 expired leases.
+    Lease6Collection expired_leases;
+    ASSERT_NO_THROW(lmptr_->getExpiredLeases6(expired_leases, 10));
+
+    // No lease should be returned.
+    EXPECT_EQ(0, expired_leases.size());
+}
+
 void
 GenericLeaseMgrTest::testDeleteExpiredReclaimedLeases4() {
     // Get the leases to be used for the test.
index ebb3078f46321cf7793b7ba8b6c2b31576645105..1aa8051541652cb9c74cb8bdd6dbead80d50e683 100644 (file)
@@ -68,8 +68,7 @@ public:
     /// @param address Address to use for the initialization
     ///
     /// @return Lease6Ptr.  This will not point to anything if the
-    /// initialization
-    ///         failed (e.g. unknown address).
+    ///         initialization failed (e.g. unknown address).
     Lease6Ptr initializeLease6(std::string address);
 
     /// @brief Check Leases present and different
@@ -145,6 +144,9 @@ public:
     /// @brief checks that invalid dates are safely handled.
     void testMaxDate4();
 
+    /// @brief checks that infinite lifetimes do not overflow.
+    void testInfiniteLifeTime4();
+
     /// @brief Test lease retrieval using client id.
     void testGetLease4ClientId();
 
@@ -250,6 +252,9 @@ public:
     /// @brief Checks that invalid dates are safely handled.
     void testMaxDate6();
 
+    /// @brief checks that infinite lifetimes do not overflow.
+    void testInfiniteLifeTime6();
+
     /// @brief Checks that Lease6 can be stored with and without a hardware address.
     void testLease6MAC();
 
@@ -348,6 +353,14 @@ public:
     /// - reclaimed leases are not returned.
     void testGetExpiredLeases6();
 
+    /// @brief Checks that the static (i.e. with infinite valid lifetime)
+    /// DHCPv4 leases will never expire.
+    void testStaticLeases4();
+
+    /// @brief Checks that the static (i.e. with infinite valid lifetime)
+    /// DHCPv4 leases will never expire.
+    void testStaticLeases6();
+
     /// @brief Checks that declined IPv4 leases that have expired can be retrieved.
     ///
     /// This test checks that the following:
index 015f7becb945966d4d82d1c29fa59e9cfe30d605..0aa941174694c85b09a619541d9a6d3c308c36b9 100644 (file)
@@ -926,6 +926,11 @@ TEST(Lease6Test, Lease6Expired) {
     // Case 3: the lease is expired
     lease.cltt_ = time(NULL) - 102;
     EXPECT_TRUE(lease.expired());
+
+    // Case 4: the lease is static
+    lease.cltt_ = 1;
+    lease.valid_lft_ = Lease::INFINITY_LFT;
+    EXPECT_FALSE(lease.expired());
 }
 
 // Verify that the DUID can be returned as a vector object and if DUID is NULL
index e84d0f5aae4a025f5e70bc2c136d681a5de1dd05..fc38939bdeb5d20c7cdd34bf595cb02a0231aa1e 100644 (file)
@@ -277,6 +277,11 @@ TEST_F(MySqlLeaseMgrTest, maxDate4) {
     testMaxDate4();
 }
 
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(MySqlLeaseMgrTest, infiniteLifeTime4) {
+    testInfiniteLifeTime4();
+}
+
 /// @brief Lease4 update tests
 ///
 /// Checks that we are able to update a lease in the database.
@@ -414,6 +419,12 @@ TEST_F(MySqlLeaseMgrTest, getExpiredLeases4) {
     testGetExpiredLeases4();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv4
+/// leases will never expire.
+TEST_F(MySqlLeaseMgrTest, staticLeases4) {
+    testStaticLeases4();
+}
+
 /// @brief Check that expired reclaimed DHCPv4 leases are removed.
 TEST_F(MySqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
     testDeleteExpiredReclaimedLeases4();
@@ -442,6 +453,11 @@ TEST_F(MySqlLeaseMgrTest, maxDate6) {
     testMaxDate6();
 }
 
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(MySqlLeaseMgrTest, infiniteLifeTime6) {
+    testInfiniteLifeTime6();
+}
+
 /// @brief Verify that too long hostname for Lease6 is not accepted.
 ///
 /// Checks that the it is not possible to create a lease when the hostname
@@ -553,6 +569,12 @@ TEST_F(MySqlLeaseMgrTest, getExpiredLeases6) {
     testGetExpiredLeases6();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv6
+/// leases will never expire.
+TEST_F(MySqlLeaseMgrTest, staticLeases6) {
+    testStaticLeases6();
+}
+
 /// @brief Check that expired reclaimed DHCPv6 leases are removed.
 TEST_F(MySqlLeaseMgrTest, deleteExpiredReclaimedLeases6) {
     testDeleteExpiredReclaimedLeases6();
index 1856186cd7f62b29f77e10158717c8a7deed8c5b..35caf888a031f6ef86ca0edcf7973ebcdbde9051 100644 (file)
@@ -267,6 +267,11 @@ TEST_F(PgSqlLeaseMgrTest, maxDate4) {
     testMaxDate4();
 }
 
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(PgSqlLeaseMgrTest, infiniteLifeTime4) {
+    testInfiniteLifeTime4();
+}
+
 /// @brief Lease4 update tests
 ///
 /// Checks that we are able to update a lease in the database.
@@ -404,6 +409,12 @@ TEST_F(PgSqlLeaseMgrTest, getExpiredLeases4) {
     testGetExpiredLeases4();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv4
+/// leases will never expire.
+TEST_F(PgSqlLeaseMgrTest, staticLeases4) {
+    testStaticLeases4();
+}
+
 /// @brief Check that expired reclaimed DHCPv4 leases are removed.
 TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
     testDeleteExpiredReclaimedLeases4();
@@ -432,6 +443,11 @@ TEST_F(PgSqlLeaseMgrTest, maxDate6) {
     testMaxDate6();
 }
 
+/// @brief checks that infinite lifetimes do not overflow.
+TEST_F(PgSqlLeaseMgrTest, infiniteLifeTime6) {
+    testInfiniteLifeTime6();
+}
+
 /// @brief Verify that too long hostname for Lease6 is not accepted.
 ///
 /// Checks that the it is not possible to create a lease when the hostname
@@ -543,6 +559,12 @@ TEST_F(PgSqlLeaseMgrTest, getExpiredLeases6) {
     testGetExpiredLeases6();
 }
 
+/// @brief Checks that the static (i.e. with infinite valid lifetime) DHCPv6
+/// leases will never expire.
+TEST_F(PgSqlLeaseMgrTest, staticLeases6) {
+    testStaticLeases6();
+}
+
 /// @brief Check that expired reclaimed DHCPv6 leases are removed.
 TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases6) {
     testDeleteExpiredReclaimedLeases6();