From 86590870d3b74eb33ea4d56d1acce2c457787b15 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 16 Jul 2025 15:22:47 -0700 Subject: [PATCH] [mle] introduce `GenerateRandomDelay()` helper (#11729) This commit introduces `GenerateRandomDelay()`, to simplify the logic for generating a random delay up to a given max delay. This is then used through `Mle` class. --- src/core/thread/mle.cpp | 18 ++++++++++++------ src/core/thread/mle.hpp | 1 + src/core/thread/mle_ftd.cpp | 22 ++++++++-------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index a798bb98a..50ba28953 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -705,7 +705,7 @@ uint32_t Mle::GetAttachStartDelay(void) const if (mAttachCounter == 0) { - delay = 1 + Random::NonCrypto::GetUint32InRange(0, kParentRequestRouterTimeout); + delay = GenerateRandomDelay(kParentRequestRouterTimeout); ExitNow(); } #if OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE @@ -819,6 +819,13 @@ void Mle::SetStateChild(uint16_t aRloc16) mPreviousParentRloc = mParent.GetRloc16(); } +uint32_t Mle::GenerateRandomDelay(uint32_t aMaxDelay) const +{ + // Generates a random delay within `[1, aMaxDelay]` (inclusive). + + return 1 + Random::NonCrypto::GetUint32InRange(0, aMaxDelay); +} + void Mle::SetTimeout(uint32_t aTimeout, TimeoutAction aAction) { // Determine `kMinTimeout` based on other parameters. `kMaxTimeout` @@ -1605,7 +1612,7 @@ uint32_t Mle::Reattach(void) IgnoreError(Get().ApplyConfiguration()); mReattachState = kReattachPending; SetAttachState(kAttachStateStart); - delay = 1 + Random::NonCrypto::GetUint32InRange(0, kAttachStartJitter); + delay = GenerateRandomDelay(kAttachStartJitter); ExitNow(); } @@ -2678,7 +2685,6 @@ void Mle::HandleAdvertisement(RxInfo &aRxInfo) Error error = kErrorNone; uint16_t sourceAddress; LeaderData leaderData; - uint32_t delay; VerifyOrExit(IsAttached()); @@ -2727,8 +2733,8 @@ void Mle::HandleAdvertisement(RxInfo &aRxInfo) if (mRetrieveNewNetworkData || IsNetworkDataNewer(leaderData)) { - delay = 1 + Random::NonCrypto::GetUint16InRange(0, kMleMaxResponseDelay); - mDelayedSender.ScheduleDataRequest(aRxInfo.mMessageInfo.GetPeerAddr(), delay); + mDelayedSender.ScheduleDataRequest(aRxInfo.mMessageInfo.GetPeerAddr(), + GenerateRandomDelay(kMleMaxResponseDelay)); } aRxInfo.mClass = RxInfo::kPeerMessage; @@ -2909,7 +2915,7 @@ exit: if (aRxInfo.mMessageInfo.GetSockAddr().IsMulticast()) { - delay = 1 + Random::NonCrypto::GetUint16InRange(0, kMleMaxResponseDelay); + delay = GenerateRandomDelay(kMleMaxResponseDelay); } else { diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 89bf41cfc..003c62748 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -2001,6 +2001,7 @@ private: void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId); void SetLeaderData(const LeaderData &aLeaderData); void SetTimeout(uint32_t aTimeout, TimeoutAction aAction); + uint32_t GenerateRandomDelay(uint32_t aMaxDelay) const; void InformPreviousChannel(void); void ScheduleMessageTransmissionTimer(void); void HandleAttachTimer(void); diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index 8dec57a3a..d59da1876 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -493,8 +493,7 @@ void Mle::ScheduleUnicastAdvertisementTo(const Router &aRouter) Ip6::Address destination; destination.SetToLinkLocalAddress(aRouter.GetExtAddress()); - mDelayedSender.ScheduleAdvertisement(destination, - Random::NonCrypto::GetUint32InRange(0, kMaxUnicastAdvertisementDelay)); + mDelayedSender.ScheduleAdvertisement(destination, GenerateRandomDelay(kMaxUnicastAdvertisementDelay)); } void Mle::SendAdvertisement(const Ip6::Address &aDestination) @@ -726,7 +725,7 @@ void Mle::HandleLinkRequest(RxInfo &aRxInfo) if (aRxInfo.mMessageInfo.GetSockAddr().IsMulticast()) { - mDelayedSender.ScheduleLinkAccept(info, 1 + Random::NonCrypto::GetUint16InRange(0, kMaxLinkAcceptDelay)); + mDelayedSender.ScheduleLinkAccept(info, GenerateRandomDelay(kMaxLinkAcceptDelay)); } else { @@ -1309,7 +1308,7 @@ Error Mle::HandleAdvertisementOnFtd(RxInfo &aRxInfo, uint16_t aSourceAddress, co InitNeighbor(*router, aRxInfo); router->SetState(Neighbor::kStateLinkRequest); router->ClearLinkAcceptTimeout(); - delay = Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter); + delay = GenerateRandomDelay(kMaxLinkRequestDelayOnRouter); mDelayedSender.ScheduleLinkRequest(*router, delay); ExitNow(error = kErrorNoRoute); } @@ -1466,9 +1465,8 @@ void Mle::HandleParentRequest(RxInfo &aRxInfo) aRxInfo.mClass = RxInfo::kPeerMessage; ProcessKeySequence(aRxInfo); - delay = 1 + Random::NonCrypto::GetUint16InRange(0, !ScanMaskTlv::IsEndDeviceFlagSet(scanMask) - ? kParentResponseMaxDelayRouters - : kParentResponseMaxDelayAll); + delay = GenerateRandomDelay(!ScanMaskTlv::IsEndDeviceFlagSet(scanMask) ? kParentResponseMaxDelayRouters + : kParentResponseMaxDelayAll); mDelayedSender.ScheduleParentResponse(info, delay); exit: @@ -1704,8 +1702,7 @@ void Mle::HandleTimeTick(void) if (router.HasRemainingLinkRequestAttempts()) { router.DecrementLinkRequestAttempts(); - mDelayedSender.ScheduleLinkRequest( - router, Random::NonCrypto::GetUint32InRange(0, kMaxLinkRequestDelayOnRouter)); + mDelayedSender.ScheduleLinkRequest(router, GenerateRandomDelay(kMaxLinkRequestDelayOnRouter)); } } } @@ -2613,8 +2610,6 @@ exit: void Mle::HandleNetworkDataUpdateRouter(void) { - uint32_t delay; - VerifyOrExit(IsRouterOrLeader()); if (IsLeader()) @@ -2623,8 +2618,7 @@ void Mle::HandleNetworkDataUpdateRouter(void) } else { - delay = 1 + Random::NonCrypto::GetUint16InRange(0, kUnsolicitedDataResponseJitter); - mDelayedSender.ScheduleMulticastDataResponse(delay); + mDelayedSender.ScheduleMulticastDataResponse(GenerateRandomDelay(kUnsolicitedDataResponseJitter)); } SynchronizeChildNetworkData(); @@ -2766,7 +2760,7 @@ void Mle::HandleDiscoveryRequest(RxInfo &aRxInfo) #endif mDelayedSender.ScheduleDiscoveryResponse(aRxInfo.mMessageInfo.GetPeerAddr(), responseInfo, - 1 + Random::NonCrypto::GetUint16InRange(0, kDiscoveryMaxJitter)); + GenerateRandomDelay(kDiscoveryMaxJitter)); exit: LogProcessError(kTypeDiscoveryRequest, error);