[srp-server] introduce "fast start mode" feature (#11305)

This commit adds "Fast Start Mode" feature for SRP server. This
feature is designed for scenarios where a device, often a mobile
device, needs to act as a provisional SRP server (e.g., functioning
as a temporary Border Router). The SRP server function is enabled
only if no other Border Routers are already providing the SRP
service within the Thread network. A common use case is a mobile
device joining a Thread network where it may be the first, or only,
BR. Importantly, Fast Start Mode allows the device to quickly start
its SRP server functionality upon joining the network, allowing other
Thread devices to quickly connect and register their services without
the typical delays associated with standard Border Router
initialization and SRP server startup (using NetData Publisher).
This commit is contained in:
Abtin Keshavarzian
2025-02-28 13:49:30 -08:00
committed by GitHub
parent 31f2897951
commit babbccd4c6
15 changed files with 428 additions and 8 deletions
+113 -7
View File
@@ -185,7 +185,7 @@ void AdvanceTime(uint32_t aDuration)
sNow = time;
}
void InitTest(void)
void InitTest(bool aStartThread = true)
{
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Initialize OT instance.
@@ -208,15 +208,18 @@ void InitTest(void)
otDatasetConvertToTlvs(&dataset, &datasetTlvs);
SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
SuccessOrQuit(otIp6SetEnabled(sInstance, true));
SuccessOrQuit(otThreadSetEnabled(sInstance, true));
if (aStartThread)
{
SuccessOrQuit(otIp6SetEnabled(sInstance, true));
SuccessOrQuit(otThreadSetEnabled(sInstance, true));
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ensure device starts as leader.
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ensure device starts as leader.
AdvanceTime(10000);
AdvanceTime(10000);
VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
}
}
void FinalizeTest(void)
@@ -1275,6 +1278,106 @@ void TestSrpServerAddressModeForceAdd(void)
Log("End of TestSrpServerAddressModeForceAdd");
}
#if OPENTHREAD_CONFIG_SRP_SERVER_FAST_START_MODE_ENABLE
void TestSrpServerFastStartMode(void)
{
Srp::Server *srpServer;
otExternalRouteConfig route;
Ip6::Address address;
Log("--------------------------------------------------------------------------------------------");
Log("TestSrpServerFastStartMode");
InitTest(/* aStartThread */ false);
srpServer = &sInstance->Get<Srp::Server>();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Configure SRP server to use the "Fast Start Mode"/
SuccessOrQuit(srpServer->EnableFastStartMode());
VerifyOrQuit(srpServer->IsFastStartModeEnabled());
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Bring the IPv6 interface up and start Thread operation.
SuccessOrQuit(otIp6SetEnabled(sInstance, true));
SuccessOrQuit(otThreadSetEnabled(sInstance, true));
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Ensure that as soon as device attaches, the SRP server is started.
while (otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_DETACHED)
{
AdvanceTime(100);
}
VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicastForceAdd);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Add new entries in Network Data to trigger an "NetDataChanged" event
// and ensure that the SRP server continues to run.
AdvanceTime(10 * 1000);
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
ClearAllBytes(route);
route.mStable = true;
SuccessOrQuit(otBorderRouterAddRoute(sInstance, &route));
SuccessOrQuit(otBorderRouterRegister(sInstance));
AdvanceTime(1 * 1000);
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Publish an "DNS/SRP" entry in Network Data and ensure that this is
// correctly detected by the "Fast Start Mode" and triggers SRP server to be
// disabled.
SuccessOrQuit(address.FromString("fd00::1"));
otNetDataPublishDnsSrpServiceUnicast(sInstance, &address, /* aPort */ 1234, 0);
AdvanceTime(10 * 1000);
VerifyOrQuit(otNetDataIsDnsSrpServiceAdded(sInstance));
VerifyOrQuit(srpServer->IsFastStartModeEnabled());
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
// Ensure the original AddressMode is restored on SRP server
VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Unpublish the "DNS/SRP" entry in Network Data and check that
// the "Fast Start Mode" causes the SRP server to start again.
otNetDataUnpublishDnsSrpService(sInstance);
AdvanceTime(25 * 1000);
VerifyOrQuit(!otNetDataIsDnsSrpServiceAdded(sInstance));
VerifyOrQuit(srpServer->IsFastStartModeEnabled());
VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Finalize OT instance and validate all heap allocations are freed.
Log("Finalizing OT instance");
FinalizeTest();
Log("End of TestSrpServerFastStartMode");
}
#endif // OPENTHREAD_CONFIG_SRP_SERVER_FAST_START_MODE_ENABLE
#endif // ENABLE_SRP_TEST
} // namespace ot
@@ -1292,6 +1395,9 @@ int main(void)
ot::TestSrpClientDelayedResponse();
#endif
ot::TestSrpServerAddressModeForceAdd();
#if OPENTHREAD_CONFIG_SRP_SERVER_FAST_START_MODE_ENABLE
ot::TestSrpServerFastStartMode();
#endif
printf("All tests passed\n");
#else