From 260f44f2d355acf9fa8228086a051f430654246b Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Mon, 8 Jun 2026 13:00:02 -0700 Subject: [PATCH] [mesh-forwarder] evict insecure reassembly messages first (#13211) Enhance `MeshForwarder::EvictMessage` to prioritize evicting messages from `mReassemblyList` that were received without link security when reclaiming message buffers (reason `kEvictReasonNoMessageBuffer`). This helps protect secure messages in the send queue from being evicted due to buffer exhaustion, by prioritizing the dropping of insecure, potentially incomplete, reassembled fragments. Both FTD and MTD implementations of `EvictMessage` are updated. --- src/core/thread/mesh_forwarder.cpp | 21 +++++++++++++++++++++ src/core/thread/mesh_forwarder.hpp | 1 + src/core/thread/mesh_forwarder_ftd.cpp | 3 +++ src/core/thread/mesh_forwarder_mtd.cpp | 5 +++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 364b155a0..e2624fe71 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1201,6 +1201,27 @@ void MeshForwarder::ClearReassemblyList(void) } } +Error MeshForwarder::RemoveUnsecureReassemblyMessage(EvictReason aEvictReason) +{ + Error error = kErrorNotFound; + + VerifyOrExit(aEvictReason == kEvictReasonNoMessageBuffer); + + for (Message &message : mReassemblyList) + { + if (!message.IsLinkSecurityEnabled()) + { + LogMessage(kMessageReassemblyDrop, message, kErrorNoBufs); + mCounters.UpdateOnDrop(message); + mReassemblyList.DequeueAndFree(message); + ExitNow(error = kErrorNone); + } + } + +exit: + return error; +} + void MeshForwarder::HandleTimeTick(void) { bool continueRxingTicks = false; diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 70db267ac..c89107865 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -453,6 +453,7 @@ private: Message::Priority aPriority); Error HandleDatagram(Message &aMessage, const Mac::Address &aMacSource); void ClearReassemblyList(void); + Error RemoveUnsecureReassemblyMessage(EvictReason aEvictReason); void HandleDiscoverComplete(void); void HandleReceivedFrame(Mac::RxFrame &aFrame); diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index c2c273717..f69096f47 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -180,6 +180,9 @@ Error MeshForwarder::EvictMessage(Message::Priority aPriority, EvictReason aEvic Error error = kErrorNotFound; Message *evict = nullptr; + error = RemoveUnsecureReassemblyMessage(aEvictReason); + VerifyOrExit(error == kErrorNotFound); + #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE error = RemoveAgedMessages(); VerifyOrExit(error == kErrorNotFound); diff --git a/src/core/thread/mesh_forwarder_mtd.cpp b/src/core/thread/mesh_forwarder_mtd.cpp index df47e56a7..7fdbbbe55 100644 --- a/src/core/thread/mesh_forwarder_mtd.cpp +++ b/src/core/thread/mesh_forwarder_mtd.cpp @@ -56,11 +56,12 @@ void MeshForwarder::SendMessage(OwnedPtr aMessagePtr) Error MeshForwarder::EvictMessage(Message::Priority aPriority, EvictReason aEvictReason) { - OT_UNUSED_VARIABLE(aEvictReason); - Error error = kErrorNotFound; Message *message; + error = RemoveUnsecureReassemblyMessage(aEvictReason); + VerifyOrExit(error == kErrorNotFound); + #if OPENTHREAD_CONFIG_DELAY_AWARE_QUEUE_MANAGEMENT_ENABLE error = RemoveAgedMessages(); VerifyOrExit(error == kErrorNotFound);