From: Francis Dupont Date: Tue, 7 Jul 2026 18:32:54 +0000 (+0200) Subject: [#4547] Checkpoint X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a5bac1e111148b2fe46b8965e520c2a5fe609aa1;p=thirdparty%2Fkea.git [#4547] Checkpoint --- diff --git a/src/bin/dhcp4/dhcp4_messages.cc b/src/bin/dhcp4/dhcp4_messages.cc index 54cf029d2e..cfffda7254 100644 --- a/src/bin/dhcp4/dhcp4_messages.cc +++ b/src/bin/dhcp4/dhcp4_messages.cc @@ -151,6 +151,7 @@ extern const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_FAIL = "DHCP4_RECL extern const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_SKIPPED = "DHCP4_RECLAIM_EXPIRED_LEASES_SKIPPED"; extern const isc::log::MessageID DHCP4_RECOVERED_STASHED_RELAY_AGENT_INFO = "DHCP4_RECOVERED_STASHED_RELAY_AGENT_INFO"; extern const isc::log::MessageID DHCP4_RELEASE = "DHCP4_RELEASE"; +extern const isc::log::MessageID DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE = "DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE"; extern const isc::log::MessageID DHCP4_RELEASE_DELETED = "DHCP4_RELEASE_DELETED"; extern const isc::log::MessageID DHCP4_RELEASE_EXCEPTION = "DHCP4_RELEASE_EXCEPTION"; extern const isc::log::MessageID DHCP4_RELEASE_EXPIRED = "DHCP4_RELEASE_EXPIRED"; @@ -339,6 +340,7 @@ const char* values[] = { "DHCP4_RECLAIM_EXPIRED_LEASES_SKIPPED", "dhcp6 service is currently disabled. Try again in %1 seconds.", "DHCP4_RECOVERED_STASHED_RELAY_AGENT_INFO", "recovered for query %1 relay agent option from lease %2: %3", "DHCP4_RELEASE", "%1: address %2 was released properly.", + "DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE", "%1: client is trying to release the lease %2 which is already in the RELEASED state", "DHCP4_RELEASE_DELETED", "%1: address %2 was deleted on release.", "DHCP4_RELEASE_EXCEPTION", "%1: while trying to release address %2 an exception occurred: %3", "DHCP4_RELEASE_EXPIRED", "%1: address %2 expired on release.", diff --git a/src/bin/dhcp4/dhcp4_messages.h b/src/bin/dhcp4/dhcp4_messages.h index d9142d7a9d..9e1d9c2293 100644 --- a/src/bin/dhcp4/dhcp4_messages.h +++ b/src/bin/dhcp4/dhcp4_messages.h @@ -152,6 +152,7 @@ extern const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_FAIL; extern const isc::log::MessageID DHCP4_RECLAIM_EXPIRED_LEASES_SKIPPED; extern const isc::log::MessageID DHCP4_RECOVERED_STASHED_RELAY_AGENT_INFO; extern const isc::log::MessageID DHCP4_RELEASE; +extern const isc::log::MessageID DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE; extern const isc::log::MessageID DHCP4_RELEASE_DELETED; extern const isc::log::MessageID DHCP4_RELEASE_EXCEPTION; extern const isc::log::MessageID DHCP4_RELEASE_EXPIRED; diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes index 11d5f91781..7dd7f3c6e0 100644 --- a/src/bin/dhcp4/dhcp4_messages.mes +++ b/src/bin/dhcp4/dhcp4_messages.mes @@ -980,6 +980,14 @@ is a normal operation during client shutdown. The first argument includes the client and transaction identification information. The second argument includes the released IPv4 address. +% DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE %1: client is trying to release the lease %2 which is already in the RELEASED state +Logged at debug log level 50. +This debug message is issued when a client is trying to release the +lease which is already in the RELEASED state i.e. kept for the client +by the lease affinity feature. The first argument includes the client +and the transaction identification information. The second argument +specifies the leased address. + % DHCP4_RELEASE_DELETED %1: address %2 was deleted on release. This informational message indicates that an address was deleted on release. It is a normal operation during client shutdown. The first argument includes the diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 4c1dab0ce3..e0849df7bb 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -4174,6 +4174,14 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release, AllocEngine::ClientContext4Ptr& cont return; } + if (lease->state_ == Lease4::STATE_RELEASED) { + LOG_DEBUG(lease4_logger, DBG_DHCP4_DETAIL, + DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE) + .arg(release->getLabel()) + .arg(release->getCiaddr().toText()); + return; + } + bool skip = false; // Execute all callouts registered for lease4_release diff --git a/src/bin/dhcp4/tests/release_unittest.cc b/src/bin/dhcp4/tests/release_unittest.cc index c56487876b..251a977679 100644 --- a/src/bin/dhcp4/tests/release_unittest.cc +++ b/src/bin/dhcp4/tests/release_unittest.cc @@ -512,4 +512,51 @@ TEST_F(ReleaseTest, releaseAndReclaim) { ASSERT_EQ(count, after); } +// This test checks that to release a second time just logs when lease +// affinity is enabled. Specialized from acquireAndRelease code. +TEST_F(ReleaseTest, releaseAlreadyReleased) { + CfgMgr::instance().clear(); + Dhcp4Client client(srv_, Dhcp4Client::SELECTING); + configure(RELEASE_CONFIGS[0], *client.getServer(), true, true, true, false, + LEASE_AFFINITY_ENABLED); + // Explicitly set the client id. + client.includeClientId("12:14"); + // Explicitly set the HW address. + client.setHWAddress("01:02:03:04:05:06"); + // Perform 4-way exchange to obtain a new lease. + acquireLease(client); + + std::stringstream name; + + // Let's get the subnet-id and generate statistics name out of it + const Subnet4Collection* subnets = + CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll(); + ASSERT_EQ(1U, subnets->size()); + name << "subnet[" << (*subnets->begin())->getID() << "].assigned-addresses"; + + ObservationPtr assigned_cnt = StatsMgr::instance().getObservation(name.str()); + ASSERT_TRUE(assigned_cnt); + uint64_t before = assigned_cnt->getInteger().first; + + // Remember the acquired address. + IOAddress leased_address = client.config_.lease_.addr_; + + // Send the release. + ASSERT_NO_THROW(client.doRelease()); + + // Restore the lease and send the release a second time. + client.createLease(leased_address, 0); + ASSERT_NO_THROW(client.doRelease()); + + assigned_cnt = StatsMgr::instance().getObservation(name.str()); + ASSERT_TRUE(assigned_cnt); + uint64_t after = assigned_cnt->getInteger().first; + + // assigned stat is decremented once. + EXPECT_EQ(before, after + 1); + + // The alredy in RELEASED state is logged. + EXPECT_EQ(1U, countFile("DHCP4_RELEASE_ALREADY_IN_RELEASED_STATE")); +} + } // end of anonymous namespace