aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsarveshkumarv3 <86755931+sarveshkumarv3@users.noreply.github.com>2024-02-16 10:11:12 -0800
committerGitHub <noreply@github.com>2024-02-16 10:11:12 -0800
commit5a4fe05cb6f134a5bec6f7036afdb5c50a8b44f9 (patch)
tree14e2de4b82b06166bd3bf1a06608d1b537353805
parent49c59ec519cc8b49dd58978d1bc80b7ae7ba88d0 (diff)
downloadopenthread-5a4fe05cb6f134a5bec6f7036afdb5c50a8b44f9.tar.gz
[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 <abtink@google.com>
-rw-r--r--src/core/thread/child_table.cpp1
-rw-r--r--src/core/thread/mle_router.cpp20
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<IndirectSender>().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()));
}