diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 54133ae99..89a242a08 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -3294,7 +3294,14 @@ void Mle::DelayedSender::ScheduleDiscoveryResponse(const Ip6::Address & const DiscoveryResponseInfo &aInfo, uint32_t aDelay) { + RemoveMatchingSchedules(kTypeDiscoveryResponse, aDestination); + + VerifyOrExit(CountMatchingSchedules(kTypeDiscoveryResponse) < kMaxScheduledDiscoveryResponse); + AddSchedule(kTypeDiscoveryResponse, aDestination, aDelay, &aInfo, sizeof(aInfo)); + +exit: + return; } #endif // OPENTHREAD_FTD @@ -3490,6 +3497,24 @@ void Mle::DelayedSender::RemoveMatchingSchedules(MessageType aMessageType, const } } +uint32_t Mle::DelayedSender::CountMatchingSchedules(MessageType aMessageType) const +{ + uint32_t count = 0; + Ip6::Address unspecifiedAddr; + + unspecifiedAddr.Clear(); + + for (const Schedule &schedule : mSchedules) + { + if (Match(schedule, aMessageType, unspecifiedAddr)) + { + count++; + } + } + + return count; +} + #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) void Mle::DelayedSender::LogRemove(const Schedule &aSchedule) { diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 0340ba3fb..088cd2c1c 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1347,6 +1347,7 @@ private: static constexpr uint8_t kRouterDowngradeThreshold = 23; static constexpr uint8_t kRouterUpgradeThreshold = 16; static constexpr uint16_t kDiscoveryMaxJitter = 250; // Max jitter delay Discovery Responses (in msec). + static constexpr uint32_t kMaxScheduledDiscoveryResponse = 16; // Rate-limit Discovery response. static constexpr uint16_t kUnsolicitedDataResponseJitter = 500; // Max delay for unsol Data Response (in msec). static constexpr uint8_t kLeaderDowngradeExtraDelay = 10; // Extra delay to downgrade leader (in sec). static constexpr uint8_t kDefaultLeaderWeight = 64; @@ -1776,15 +1777,16 @@ private: MessageType mMessageType; }; - void AddSchedule(MessageType aMessageType, - const Ip6::Address &aDestination, - uint32_t aDelay, - const void *aInfo, - uint16_t aInfoSize); - void Execute(const Schedule &aSchedule); - bool HasMatchingSchedule(MessageType aMessageType, const Ip6::Address &aDestination) const; - void RemoveMatchingSchedules(MessageType aMessageType, const Ip6::Address &aDestination); - void LogRemove(const Schedule &aSchedule); + void AddSchedule(MessageType aMessageType, + const Ip6::Address &aDestination, + uint32_t aDelay, + const void *aInfo, + uint16_t aInfoSize); + void Execute(const Schedule &aSchedule); + bool HasMatchingSchedule(MessageType aMessageType, const Ip6::Address &aDestination) const; + void RemoveMatchingSchedules(MessageType aMessageType, const Ip6::Address &aDestination); + uint32_t CountMatchingSchedules(MessageType aMessageType) const; + void LogRemove(const Schedule &aSchedule); static bool Match(const Schedule &aSchedule, MessageType aMessageType, const Ip6::Address &aDestination);