From: Francis Dupont Date: Sun, 22 Sep 2019 17:23:40 +0000 (+0200) Subject: [897-add-infinite-valid-lifetime-for-bootp] Reported previous changes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3eff9d867a7f87950d8c46cc4c3d802cf1d19d39;p=thirdparty%2Fkea.git [897-add-infinite-valid-lifetime-for-bootp] Reported previous changes --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 1b4b155561..3edfd8231d 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -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 diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index d1e02821ae..d61922493e 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -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((*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((*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((*l)->prefixlen_)) + .arg(ia->getIAID()) + .arg("infinity"); } boost::shared_ptr diff --git a/src/lib/cql/cql_exchange.cc b/src/lib/cql/cql_exchange.cc index 61d0bb707a..d28183496e 100644 --- a/src/lib/cql/cql_exchange.cc +++ b/src/lib/cql/cql_exchange.cc @@ -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(cltt) + static_cast(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(expire - valid_lifetime); } diff --git a/src/lib/dhcpsrv/cql_lease_mgr.cc b/src/lib/dhcpsrv/cql_lease_mgr.cc index 55913f554d..2803e56f87 100644 --- a/src/lib/dhcpsrv/cql_lease_mgr.cc +++ b/src/lib/dhcpsrv/cql_lease_mgr.cc @@ -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 "}}, diff --git a/src/lib/dhcpsrv/csv_lease_file4.cc b/src/lib/dhcpsrv/csv_lease_file4.cc index a696377c99..fc3cf1886a 100644 --- a/src/lib/dhcpsrv/csv_lease_file4.cc +++ b/src/lib/dhcpsrv/csv_lease_file4.cc @@ -60,7 +60,7 @@ CSVLeaseFile4::append(const Lease4& lease) { } row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_); - row.writeAt(getColumnIndex("expire"), static_cast(lease.cltt_ + lease.valid_lft_)); + row.writeAt(getColumnIndex("expire"), static_cast(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_); diff --git a/src/lib/dhcpsrv/csv_lease_file6.cc b/src/lib/dhcpsrv/csv_lease_file6.cc index a1119a6177..c73b7d9aa6 100644 --- a/src/lib/dhcpsrv/csv_lease_file6.cc +++ b/src/lib/dhcpsrv/csv_lease_file6.cc @@ -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(lease.cltt_ + lease.valid_lft_)); + row.writeAt(getColumnIndex("expire"), static_cast(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_); diff --git a/src/lib/dhcpsrv/lease.cc b/src/lib/dhcpsrv/lease.cc index d504a95eef..61b440e40c 100644 --- a/src/lib/dhcpsrv/lease.cc +++ b/src/lib/dhcpsrv/lease.cc @@ -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(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" diff --git a/src/lib/dhcpsrv/lease.h b/src/lib/dhcpsrv/lease.h index 1e3086354b..4c82d0a5b9 100644 --- a/src/lib/dhcpsrv/lease.h +++ b/src/lib/dhcpsrv/lease.h @@ -34,6 +34,9 @@ typedef boost::shared_ptr 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 diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc index 599045c860..6308965d3f 100644 --- a/src/lib/dhcpsrv/mysql_lease_mgr.cc +++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc @@ -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(&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(&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. diff --git a/src/lib/dhcpsrv/pgsql_lease_mgr.cc b/src/lib/dhcpsrv/pgsql_lease_mgr.cc index 1ade373649..205858e009 100644 --- a/src/lib/dhcpsrv/pgsql_lease_mgr.cc +++ b/src/lib/dhcpsrv/pgsql_lease_mgr.cc @@ -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(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(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(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(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_); diff --git a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc index d07f335629..272064768c 100644 --- a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc @@ -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(); diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc index c140d8c90f..c60b0b6ac2 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc @@ -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 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 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 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 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. diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h index ebb3078f46..1aa8051541 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h @@ -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: diff --git a/src/lib/dhcpsrv/tests/lease_unittest.cc b/src/lib/dhcpsrv/tests/lease_unittest.cc index 015f7becb9..0aa9411746 100644 --- a/src/lib/dhcpsrv/tests/lease_unittest.cc +++ b/src/lib/dhcpsrv/tests/lease_unittest.cc @@ -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 diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc index e84d0f5aae..fc38939bde 100644 --- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc @@ -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(); diff --git a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc index 1856186cd7..35caf888a0 100644 --- a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc @@ -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();