From 786edd667a66a12ef97006e7985cca6a4fc74cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Thu, 22 Sep 2016 18:36:39 +0200 Subject: [PATCH] Check only one response in Link Accept handler (#653) * Compare Response TLV in Link Accept with appropriate Challenge value. * Invalidate Challenge value from multicast Link Request after timeout. --- src/core/thread/mle_constants.hpp | 1 + src/core/thread/mle_router.cpp | 29 +++++++++++++++++++++++++---- src/core/thread/mle_router.hpp | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/core/thread/mle_constants.hpp b/src/core/thread/mle_constants.hpp index a1d350663..7e7e5d984 100644 --- a/src/core/thread/mle_constants.hpp +++ b/src/core/thread/mle_constants.hpp @@ -58,6 +58,7 @@ enum kUdpPort = 19788, ///< MLE UDP Port kParentRequestRouterTimeout = 1000, ///< Router Request timeout kParentRequestChildTimeout = 2000, ///< End Device Request timeout + kMaxResponseDelay = 1000, ///< Maximum delay before responding to a multicast request }; enum diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 39853e3f0..4fb4c1fd5 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -57,6 +57,7 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif): mAddressRelease(OPENTHREAD_URI_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this), mCoapServer(aThreadNetif.GetCoapServer()) { + mChallengeTimeout = 0; mNextChildId = kMaxChildId; mRouterIdSequence = 0; memset(mChildren, 0, sizeof(mChildren)); @@ -533,6 +534,8 @@ ThreadError MleRouter::SendLinkRequest(Neighbor *aNeighbor) mChallenge[i] = static_cast(otPlatRandomGet()); } + mChallengeTimeout = (((2 * kMaxResponseDelay) + kStateUpdatePeriod - 1) / kStateUpdatePeriod); + SuccessOrExit(error = AppendChallenge(*message, mChallenge, sizeof(mChallenge))); destination.mFields.m8[0] = 0xff; destination.mFields.m8[1] = 0x02; @@ -545,7 +548,8 @@ ThreadError MleRouter::SendLinkRequest(Neighbor *aNeighbor) aNeighbor->mPending.mChallenge[i] = static_cast(otPlatRandomGet()); } - SuccessOrExit(error = AppendChallenge(*message, mChallenge, sizeof(mChallenge))); + SuccessOrExit(error = AppendChallenge(*message, aNeighbor->mPending.mChallenge, + sizeof(aNeighbor->mPending.mChallenge))); destination.mFields.m16[0] = HostSwap16(0xfe80); destination.SetIid(aNeighbor->mMacAddr); } @@ -835,9 +839,21 @@ ThreadError MleRouter::HandleLinkAccept(const Message &aMessage, const Ip6::Mess } // verify response - VerifyOrExit(memcmp(mChallenge, response.GetResponse(), sizeof(mChallenge)) == 0 || - memcmp(neighbor->mPending.mChallenge, response.GetResponse(), sizeof(neighbor->mPending.mChallenge)) == 0, - error = kThreadError_Error); + switch (neighbor->mState) + { + case Neighbor::kStateLinkRequest: + VerifyOrExit(memcmp(neighbor->mPending.mChallenge, response.GetResponse(), sizeof(neighbor->mPending.mChallenge)) == 0, + error = kThreadError_Error); + break; + + case Neighbor::kStateInvalid: + VerifyOrExit((mChallengeTimeout > 0) && (memcmp(mChallenge, response.GetResponse(), sizeof(mChallenge)) == 0), + error = kThreadError_Error); + break; + + default: + ExitNow(error = kThreadError_InvalidState); + } switch (mDeviceState) { @@ -1620,6 +1636,11 @@ void MleRouter::HandleStateUpdateTimer(void *aContext) void MleRouter::HandleStateUpdateTimer(void) { + if (mChallengeTimeout > 0) + { + mChallengeTimeout--; + } + switch (GetDeviceState()) { case kDeviceStateDisabled: diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 8e7217606..f7cb3c176 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -577,6 +577,7 @@ private: uint8_t mMaxChildrenAllowed; Child mChildren[kMaxChildren]; + uint8_t mChallengeTimeout; uint8_t mChallenge[8]; uint16_t mNextChildId; uint8_t mNetworkIdTimeout;