From 7aadbb7b9a02742e370563e39bef129b1df079b5 Mon Sep 17 00:00:00 2001 From: Simon Lin Date: Fri, 10 Sep 2021 12:49:07 +0800 Subject: [PATCH] [mle] send Delayed Data Request with latest Active/Pending Timestamp (#6995) This commit fixes a potential bug that delayed Data Requests may use wrong Active and Pending Timestamps because the Active & Pending Timestamps may change while a Data Request is being delayed. --- src/core/thread/mle.cpp | 29 ++++++++++++++++++++++------- src/core/thread/mle.hpp | 17 +++++++++++------ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 915169794..24773514f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1959,10 +1959,20 @@ void Mle::HandleDelayedResponseTimer(void) } else { + Error error = kErrorNone; + mDelayedResponses.Dequeue(*message); metadata.RemoveFrom(*message); - if (SendMessage(*message, metadata.mDestination) == kErrorNone) + if (metadata.mAppendTimestamps) + { + error = AppendActiveTimestamp(*message); + error = (error == kErrorNone) ? AppendPendingTimestamp(*message) : error; + } + + error = (error == kErrorNone) ? SendMessage(*message, metadata.mDestination) : error; + + if (error == kErrorNone) { Log(kMessageSend, kTypeGenericDelayed, metadata.mDestination); @@ -2153,8 +2163,6 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination, VerifyOrExit((message = NewMleMessage()) != nullptr, error = kErrorNoBufs); SuccessOrExit(error = AppendHeader(*message, kCommandDataRequest)); SuccessOrExit(error = AppendTlvRequest(*message, aTlvs, aTlvsLength)); - SuccessOrExit(error = AppendActiveTimestamp(*message)); - SuccessOrExit(error = AppendPendingTimestamp(*message)); if (aExtraTlvs != nullptr && aExtraTlvsLength > 0) { @@ -2163,11 +2171,14 @@ Error Mle::SendDataRequest(const Ip6::Address &aDestination, if (aDelay) { - SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay)); + SuccessOrExit(error = AddDelayedResponse(*message, aDestination, aDelay, /* aAppendTimestamps */ true)); Log(kMessageDelay, kTypeDataRequest, aDestination); } else { + SuccessOrExit(error = AppendActiveTimestamp(*message)); + SuccessOrExit(error = AppendPendingTimestamp(*message)); + SuccessOrExit(error = SendMessage(*message, aDestination)); Log(kMessageSend, kTypeDataRequest, aDestination); @@ -2651,13 +2662,17 @@ exit: return error; } -Error Mle::AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay) +Error Mle::AddDelayedResponse(Message & aMessage, + const Ip6::Address &aDestination, + uint16_t aDelay, + bool aAppendTimestamps) { Error error = kErrorNone; DelayedResponseMetadata metadata; - metadata.mSendTime = TimerMilli::GetNow() + aDelay; - metadata.mDestination = aDestination; + metadata.mSendTime = TimerMilli::GetNow() + aDelay; + metadata.mDestination = aDestination; + metadata.mAppendTimestamps = aAppendTimestamps; SuccessOrExit(error = metadata.AppendTo(aMessage)); mDelayedResponses.Enqueue(aMessage); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index b54bc7c97..436d42a4e 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1442,15 +1442,19 @@ protected: /** * This method adds a message to the message queue. The queued message will be transmitted after given delay. * - * @param[in] aMessage The message to transmit after given delay. - * @param[in] aDestination The IPv6 address of the recipient of the message. - * @param[in] aDelay The delay in milliseconds before transmission of the message. + * @param[in] aMessage The message to transmit after given delay. + * @param[in] aDestination The IPv6 address of the recipient of the message. + * @param[in] aDelay The delay in milliseconds before transmission of the message. + * @param[in] aAppendTimestamps Whether or not to append Active and Pending Timestamps before sending. * * @retval kErrorNone Successfully queued the message to transmit after the delay. * @retval kErrorNoBufs Insufficient buffers to queue the message. * */ - Error AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay); + Error AddDelayedResponse(Message & aMessage, + const Ip6::Address &aDestination, + uint16_t aDelay, + bool aAppendTimestamps = false); #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1) /** @@ -1667,8 +1671,9 @@ private: void ReadFrom(const Message &aMessage); void RemoveFrom(Message &aMessage) const; - Ip6::Address mDestination; // IPv6 address of the message destination. - TimeMilli mSendTime; // Time when the message shall be sent. + Ip6::Address mDestination; // IPv6 address of the message destination. + TimeMilli mSendTime; // Time when the message shall be sent. + bool mAppendTimestamps : 1; // Append Active Timestamp and Pending Timestamp before sending. }; OT_TOOL_PACKED_BEGIN