[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 <[email protected]>
This commit is contained in:
sarveshkumarv3
2024-02-16 10:11:12 -08:00
committed by GitHub
co-authored by Abtin Keshavarzian
parent 49c59ec519
commit 5a4fe05cb6
2 changed files with 19 additions and 2 deletions
+1
View File
@@ -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);
+18 -2
View File
@@ -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()));
}