From 5a4fe05cb6f134a5bec6f7036afdb5c50a8b44f9 Mon Sep 17 00:00:00 2001 From: sarveshkumarv3 <86755931+sarveshkumarv3@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:11:12 -0800 Subject: [PATCH] [mle] generate challenge for "Child Update Request" early (#9850) This commit updates how random challenge is generated for "Child Update Request" message sent by a parent during child restoration (after parent reset/re-attach). A random challenge is now generated and saved in the `Child` entry when it is first initialized in `kRestoredState`. The `SendChildUpdateRequest()` will use the saved challenge rather than generating a new one. This change prevents overwriting the saved challenge when the child is also detached and happens to send a "Parent Request" in the window where the parent transitions to the router/leader role and before the parent sends the "Child Update Request". It ensures that the same random challenge is included in both "Parent Response" and "Child Update Response," guaranteeing proper acceptance of the child's "Child ID request". Co-authored-by: Abtin Keshavarzian --- src/core/thread/child_table.cpp | 1 + src/core/thread/mle_router.cpp | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/core/thread/child_table.cpp b/src/core/thread/child_table.cpp index cd9cb6549..7fb557dbd 100644 --- a/src/core/thread/child_table.cpp +++ b/src/core/thread/child_table.cpp @@ -245,6 +245,7 @@ void ChildTable::Restore(void) child->SetTimeout(childInfo.GetTimeout()); child->SetDeviceMode(Mle::DeviceMode(childInfo.GetMode())); child->SetState(Neighbor::kStateRestored); + child->GenerateChallenge(); child->SetLastHeard(TimerMilli::GetNow()); child->SetVersion(childInfo.GetVersion()); Get().SetChildUseShortAddress(*child, true); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index b97a7ec33..76b8dc370 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1727,7 +1727,6 @@ void MleRouter::SendParentResponse(Child *aChild, const RxChallenge &aChallenge, SuccessOrExit(error = message->AppendCslClockAccuracyTlv()); } #endif - aChild->GenerateChallenge(); SuccessOrExit(error = message->AppendChallengeTlv(aChild->GetChallenge())); SuccessOrExit(error = message->AppendLinkMarginTlv(aChild->GetLinkInfo().GetLinkMargin())); @@ -2962,7 +2961,24 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild) if (!aChild.IsStateValid()) { SuccessOrExit(error = message->AppendTlvRequestTlv(kTlvs)); - aChild.GenerateChallenge(); + + if (!aChild.IsStateRestored()) + { + // A random challenge is generated and saved when `aChild` + // is first initialized in `kStateRestored`. We will use + // the saved challenge here. This prevents overwriting + // the saved challenge when the child is also detached + // and happens to send a "Parent Request" in the window + // where the parent transitions to the router/leader role + // and before the parent sends the "Child Update Request". + // This ensures that the same random challenge is + // included in both "Parent Response" and "Child Update + // Response," guaranteeing proper acceptance of the + // child's "Child ID request". + + aChild.GenerateChallenge(); + } + SuccessOrExit(error = message->AppendChallengeTlv(aChild.GetChallenge())); }