1 /*
2  *  Copyright (c) 2022, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <openthread/config.h>
30 
31 #include "test_platform.h"
32 #include "test_util.hpp"
33 
34 #include <openthread/dataset_ftd.h>
35 #include <openthread/srp_client.h>
36 #include <openthread/srp_server.h>
37 #include <openthread/thread.h>
38 
39 #include "common/arg_macros.hpp"
40 #include "common/array.hpp"
41 #include "common/string.hpp"
42 #include "common/time.hpp"
43 #include "instance/instance.hpp"
44 
45 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE && \
46     !OPENTHREAD_CONFIG_TIME_SYNC_ENABLE && !OPENTHREAD_PLATFORM_POSIX
47 #define ENABLE_SRP_TEST 1
48 #else
49 #define ENABLE_SRP_TEST 0
50 #endif
51 
52 namespace ot {
53 
54 #if ENABLE_SRP_TEST
55 
56 // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
57 #define Log(...)                                                                                          \
58     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 36000000), (sNow / 60000) % 60, \
59            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
60 
61 static constexpr uint16_t kMaxRaSize = 800;
62 
63 static Instance *sInstance;
64 
65 static uint32_t sNow = 0;
66 static uint32_t sAlarmTime;
67 static bool     sAlarmOn = false;
68 
69 static otRadioFrame sRadioTxFrame;
70 static uint8_t      sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
71 static bool         sRadioTxOngoing = false;
72 
73 //----------------------------------------------------------------------------------------------------------------------
74 // Function prototypes
75 
76 void ProcessRadioTxAndTasklets(void);
77 void AdvanceTime(uint32_t aDuration);
78 
79 //----------------------------------------------------------------------------------------------------------------------
80 // `otPlatRadio`
81 
82 extern "C" {
83 
otPlatRadioGetCaps(otInstance *)84 otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF; }
85 
otPlatRadioTransmit(otInstance *,otRadioFrame *)86 otError otPlatRadioTransmit(otInstance *, otRadioFrame *)
87 {
88     sRadioTxOngoing = true;
89 
90     return OT_ERROR_NONE;
91 }
92 
otPlatRadioGetTransmitBuffer(otInstance *)93 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return &sRadioTxFrame; }
94 
95 //----------------------------------------------------------------------------------------------------------------------
96 // `otPlatAlaram`
97 
otPlatAlarmMilliStop(otInstance *)98 void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
99 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)100 void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
101 {
102     sAlarmOn   = true;
103     sAlarmTime = aT0 + aDt;
104 }
105 
otPlatAlarmMilliGetNow(void)106 uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
107 
108 //----------------------------------------------------------------------------------------------------------------------
109 
110 Array<void *, 500> sHeapAllocatedPtrs;
111 
112 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
otPlatCAlloc(size_t aNum,size_t aSize)113 void *otPlatCAlloc(size_t aNum, size_t aSize)
114 {
115     void *ptr = calloc(aNum, aSize);
116 
117     SuccessOrQuit(sHeapAllocatedPtrs.PushBack(ptr));
118 
119     return ptr;
120 }
121 
otPlatFree(void * aPtr)122 void otPlatFree(void *aPtr)
123 {
124     if (aPtr != nullptr)
125     {
126         void **entry = sHeapAllocatedPtrs.Find(aPtr);
127 
128         VerifyOrQuit(entry != nullptr, "A heap allocated item is freed twice");
129         sHeapAllocatedPtrs.Remove(*entry);
130     }
131 
132     free(aPtr);
133 }
134 #endif
135 
136 #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)137 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
138 {
139     OT_UNUSED_VARIABLE(aLogLevel);
140     OT_UNUSED_VARIABLE(aLogRegion);
141 
142     va_list args;
143 
144     printf("   ");
145     va_start(args, aFormat);
146     vprintf(aFormat, args);
147     va_end(args);
148     printf("\n");
149 }
150 #endif
151 
152 } // extern "C"
153 
154 //---------------------------------------------------------------------------------------------------------------------
155 
ProcessRadioTxAndTasklets(void)156 void ProcessRadioTxAndTasklets(void)
157 {
158     do
159     {
160         if (sRadioTxOngoing)
161         {
162             sRadioTxOngoing = false;
163             otPlatRadioTxStarted(sInstance, &sRadioTxFrame);
164             otPlatRadioTxDone(sInstance, &sRadioTxFrame, nullptr, OT_ERROR_NONE);
165         }
166 
167         otTaskletsProcess(sInstance);
168     } while (otTaskletsArePending(sInstance));
169 }
170 
AdvanceTime(uint32_t aDuration)171 void AdvanceTime(uint32_t aDuration)
172 {
173     uint32_t time = sNow + aDuration;
174 
175     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
176 
177     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
178     {
179         ProcessRadioTxAndTasklets();
180         sNow = sAlarmTime;
181         otPlatAlarmMilliFired(sInstance);
182     }
183 
184     ProcessRadioTxAndTasklets();
185     sNow = time;
186 }
187 
InitTest(void)188 void InitTest(void)
189 {
190     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191     // Initialize OT instance.
192 
193     sNow      = 0;
194     sAlarmOn  = false;
195     sInstance = static_cast<Instance *>(testInitInstance());
196 
197     memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
198     sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
199     sRadioTxOngoing     = false;
200 
201     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202     // Initialize Border Router and start Thread operation.
203 
204     otOperationalDataset     dataset;
205     otOperationalDatasetTlvs datasetTlvs;
206 
207     SuccessOrQuit(otDatasetCreateNewNetwork(sInstance, &dataset));
208     SuccessOrQuit(otDatasetConvertToTlvs(&dataset, &datasetTlvs));
209     SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
210 
211     SuccessOrQuit(otIp6SetEnabled(sInstance, true));
212     SuccessOrQuit(otThreadSetEnabled(sInstance, true));
213 
214     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215     // Ensure device starts as leader.
216 
217     AdvanceTime(10000);
218 
219     VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
220 }
221 
FinalizeTest(void)222 void FinalizeTest(void)
223 {
224     SuccessOrQuit(otIp6SetEnabled(sInstance, false));
225     SuccessOrQuit(otThreadSetEnabled(sInstance, false));
226     SuccessOrQuit(otInstanceErasePersistentInfo(sInstance));
227     testFreeInstance(sInstance);
228 }
229 
230 //---------------------------------------------------------------------------------------------------------------------
231 
232 enum UpdateHandlerMode
233 {
234     kAccept, // Accept all updates.
235     kReject, // Reject all updates.
236     kIgnore  // Ignore all updates (do not call `otSrpServerHandleServiceUpdateResult()`).
237 };
238 
239 static UpdateHandlerMode    sUpdateHandlerMode       = kAccept;
240 static bool                 sProcessedUpdateCallback = false;
241 static otSrpServerLeaseInfo sUpdateHostLeaseInfo;
242 static uint32_t             sUpdateHostKeyLease;
243 
HandleSrpServerUpdate(otSrpServerServiceUpdateId aId,const otSrpServerHost * aHost,uint32_t aTimeout,void * aContext)244 void HandleSrpServerUpdate(otSrpServerServiceUpdateId aId,
245                            const otSrpServerHost     *aHost,
246                            uint32_t                   aTimeout,
247                            void                      *aContext)
248 {
249     Log("HandleSrpServerUpdate() called with %u, timeout:%u", aId, aTimeout);
250 
251     VerifyOrQuit(aHost != nullptr);
252     VerifyOrQuit(aContext == sInstance);
253 
254     sProcessedUpdateCallback = true;
255 
256     otSrpServerHostGetLeaseInfo(aHost, &sUpdateHostLeaseInfo);
257 
258     switch (sUpdateHandlerMode)
259     {
260     case kAccept:
261         otSrpServerHandleServiceUpdateResult(sInstance, aId, kErrorNone);
262         break;
263     case kReject:
264         otSrpServerHandleServiceUpdateResult(sInstance, aId, kErrorFailed);
265         break;
266     case kIgnore:
267         break;
268     }
269 }
270 
271 static bool  sProcessedClientCallback = false;
272 static Error sLastClientCallbackError = kErrorNone;
273 
HandleSrpClientCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices,void * aContext)274 void HandleSrpClientCallback(otError                    aError,
275                              const otSrpClientHostInfo *aHostInfo,
276                              const otSrpClientService  *aServices,
277                              const otSrpClientService  *aRemovedServices,
278                              void                      *aContext)
279 {
280     Log("HandleSrpClientCallback() called with error %s", ErrorToString(aError));
281 
282     VerifyOrQuit(aContext == sInstance);
283 
284     sProcessedClientCallback = true;
285     sLastClientCallbackError = aError;
286 
287     OT_UNUSED_VARIABLE(aHostInfo);
288     OT_UNUSED_VARIABLE(aServices);
289     OT_UNUSED_VARIABLE(aRemovedServices);
290 }
291 
292 static const char kHostName[] = "myhost";
293 
PrepareService1(Srp::Client::Service & aService)294 void PrepareService1(Srp::Client::Service &aService)
295 {
296     static const char          kServiceName[]   = "_srv._udp";
297     static const char          kInstanceLabel[] = "srv.instance";
298     static const char          kSub1[]          = "_sub1";
299     static const char          kSub2[]          = "_V1234567";
300     static const char          kSub3[]          = "_XYZWS";
301     static const char         *kSubLabels[]     = {kSub1, kSub2, kSub3, nullptr};
302     static const char          kTxtKey1[]       = "ABCD";
303     static const uint8_t       kTxtValue1[]     = {'a', '0'};
304     static const char          kTxtKey2[]       = "Z0";
305     static const uint8_t       kTxtValue2[]     = {'1', '2', '3'};
306     static const char          kTxtKey3[]       = "D";
307     static const uint8_t       kTxtValue3[]     = {0};
308     static const otDnsTxtEntry kTxtEntries[]    = {
309            {kTxtKey1, kTxtValue1, sizeof(kTxtValue1)},
310            {kTxtKey2, kTxtValue2, sizeof(kTxtValue2)},
311            {kTxtKey3, kTxtValue3, sizeof(kTxtValue3)},
312     };
313 
314     memset(&aService, 0, sizeof(aService));
315     aService.mName          = kServiceName;
316     aService.mInstanceName  = kInstanceLabel;
317     aService.mSubTypeLabels = kSubLabels;
318     aService.mTxtEntries    = kTxtEntries;
319     aService.mNumTxtEntries = 3;
320     aService.mPort          = 777;
321     aService.mWeight        = 1;
322     aService.mPriority      = 2;
323 }
324 
PrepareService2(Srp::Client::Service & aService)325 void PrepareService2(Srp::Client::Service &aService)
326 {
327     static const char  kService2Name[]   = "_00112233667882554._matter._udp";
328     static const char  kInstance2Label[] = "ABCDEFGHI";
329     static const char  kSub4[]           = "_44444444";
330     static const char *kSubLabels2[]     = {kSub4, nullptr};
331 
332     memset(&aService, 0, sizeof(aService));
333     aService.mName          = kService2Name;
334     aService.mInstanceName  = kInstance2Label;
335     aService.mSubTypeLabels = kSubLabels2;
336     aService.mTxtEntries    = nullptr;
337     aService.mNumTxtEntries = 0;
338     aService.mPort          = 555;
339     aService.mWeight        = 0;
340     aService.mPriority      = 3;
341 }
342 
ValidateHost(Srp::Server & aServer,const char * aHostName)343 void ValidateHost(Srp::Server &aServer, const char *aHostName)
344 {
345     // Validate that only a host with `aHostName` is
346     // registered on SRP server.
347 
348     const Srp::Server::Host *host;
349     const char              *name;
350 
351     Log("ValidateHost()");
352 
353     host = aServer.GetNextHost(nullptr);
354     VerifyOrQuit(host != nullptr);
355 
356     name = host->GetFullName();
357     Log("Hostname: %s", name);
358 
359     VerifyOrQuit(StringStartsWith(name, aHostName, kStringCaseInsensitiveMatch));
360     VerifyOrQuit(name[strlen(aHostName)] == '.');
361 
362     // Only one host on server
363     VerifyOrQuit(aServer.GetNextHost(host) == nullptr);
364 }
365 
366 //----------------------------------------------------------------------------------------------------------------------
367 
TestSrpServerBase(void)368 void TestSrpServerBase(void)
369 {
370     Srp::Server         *srpServer;
371     Srp::Client         *srpClient;
372     Srp::Client::Service service1;
373     Srp::Client::Service service2;
374     uint16_t             heapAllocations;
375 
376     Log("--------------------------------------------------------------------------------------------");
377     Log("TestSrpServerBase");
378 
379     InitTest();
380 
381     srpServer = &sInstance->Get<Srp::Server>();
382     srpClient = &sInstance->Get<Srp::Client>();
383 
384     heapAllocations = sHeapAllocatedPtrs.GetLength();
385 
386     PrepareService1(service1);
387     PrepareService2(service2);
388 
389     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
390     // Start SRP server.
391 
392     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
393     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
394 
395     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
396 
397     srpServer->SetServiceHandler(HandleSrpServerUpdate, sInstance);
398 
399     srpServer->SetEnabled(true);
400     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
401 
402     AdvanceTime(10000);
403     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
404 
405     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
406     // Start SRP client.
407 
408     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
409 
410     srpClient->EnableAutoStartMode(nullptr, nullptr);
411     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
412 
413     AdvanceTime(2000);
414     VerifyOrQuit(srpClient->IsRunning());
415 
416     SuccessOrQuit(srpClient->SetHostName(kHostName));
417     SuccessOrQuit(srpClient->EnableAutoHostAddress());
418 
419     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
420     // Register a service, validate that update handler is called.
421 
422     SuccessOrQuit(srpClient->AddService(service1));
423 
424     sUpdateHandlerMode       = kAccept;
425     sProcessedUpdateCallback = false;
426     sProcessedClientCallback = false;
427 
428     AdvanceTime(2 * 1000);
429 
430     VerifyOrQuit(sProcessedUpdateCallback);
431     VerifyOrQuit(sProcessedClientCallback);
432     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
433 
434     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
435     ValidateHost(*srpServer, kHostName);
436 
437     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
438     // Register a second service, validate that update handler is called.
439 
440     SuccessOrQuit(srpClient->AddService(service2));
441 
442     sProcessedUpdateCallback = false;
443     sProcessedClientCallback = false;
444 
445     AdvanceTime(2 * 1000);
446 
447     VerifyOrQuit(sProcessedUpdateCallback);
448     VerifyOrQuit(sProcessedClientCallback);
449     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
450 
451     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
452     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
453 
454     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
455     // Unregister first service, validate that update handler is called.
456 
457     SuccessOrQuit(srpClient->RemoveService(service1));
458 
459     sProcessedUpdateCallback = false;
460     sProcessedClientCallback = false;
461 
462     AdvanceTime(2 * 1000);
463 
464     VerifyOrQuit(sProcessedUpdateCallback);
465     VerifyOrQuit(sProcessedClientCallback);
466     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
467 
468     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
469     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
470 
471     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
472     // Disable SRP server, verify that all heap allocations by SRP server
473     // are freed.
474 
475     Log("Disabling SRP server");
476 
477     srpServer->SetEnabled(false);
478     AdvanceTime(100);
479 
480     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
481 
482     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
483     // Finalize OT instance and validate all heap allocations are freed.
484 
485     Log("Finalizing OT instance");
486     FinalizeTest();
487 
488     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
489 
490     Log("End of TestSrpServerBase");
491 }
492 
TestSrpServerReject(void)493 void TestSrpServerReject(void)
494 {
495     Srp::Server         *srpServer;
496     Srp::Client         *srpClient;
497     Srp::Client::Service service1;
498     Srp::Client::Service service2;
499     uint16_t             heapAllocations;
500 
501     Log("--------------------------------------------------------------------------------------------");
502     Log("TestSrpServerReject");
503 
504     InitTest();
505 
506     srpServer = &sInstance->Get<Srp::Server>();
507     srpClient = &sInstance->Get<Srp::Client>();
508 
509     heapAllocations = sHeapAllocatedPtrs.GetLength();
510 
511     PrepareService1(service1);
512     PrepareService2(service2);
513 
514     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
515     // Start SRP server.
516 
517     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
518     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
519 
520     srpServer->SetServiceHandler(HandleSrpServerUpdate, sInstance);
521 
522     srpServer->SetEnabled(true);
523     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
524 
525     AdvanceTime(10000);
526     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
527 
528     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
529     // Start SRP client.
530 
531     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
532 
533     srpClient->EnableAutoStartMode(nullptr, nullptr);
534     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
535 
536     AdvanceTime(2000);
537     VerifyOrQuit(srpClient->IsRunning());
538 
539     SuccessOrQuit(srpClient->SetHostName(kHostName));
540     SuccessOrQuit(srpClient->EnableAutoHostAddress());
541 
542     sUpdateHandlerMode = kReject;
543 
544     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
545     // Register a service, validate that update handler is called
546     // and rejected and no service is registered.
547 
548     SuccessOrQuit(srpClient->AddService(service1));
549 
550     sProcessedUpdateCallback = false;
551     sProcessedClientCallback = false;
552 
553     AdvanceTime(2 * 1000);
554 
555     VerifyOrQuit(sProcessedUpdateCallback);
556     VerifyOrQuit(sProcessedClientCallback);
557     VerifyOrQuit(sLastClientCallbackError != kErrorNone);
558 
559     VerifyOrQuit(service1.GetState() != Srp::Client::kRegistered);
560 
561     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
562 
563     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
564     // Register a second service, validate that update handler is
565     // again called and update is rejected.
566 
567     SuccessOrQuit(srpClient->AddService(service2));
568 
569     sProcessedUpdateCallback = false;
570     sProcessedClientCallback = false;
571 
572     AdvanceTime(2 * 1000);
573 
574     VerifyOrQuit(sProcessedUpdateCallback);
575     VerifyOrQuit(sProcessedClientCallback);
576     VerifyOrQuit(sLastClientCallbackError != kErrorNone);
577 
578     VerifyOrQuit(service1.GetState() != Srp::Client::kRegistered);
579     VerifyOrQuit(service2.GetState() != Srp::Client::kRegistered);
580 
581     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
582 
583     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
584     // Disable SRP server, verify that all heap allocations by SRP server
585     // are freed.
586 
587     Log("Disabling SRP server");
588 
589     srpServer->SetEnabled(false);
590     AdvanceTime(100);
591 
592     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
593 
594     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
595     // Finalize OT instance and validate all heap allocations are freed.
596 
597     Log("Finalizing OT instance");
598     FinalizeTest();
599 
600     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
601 
602     Log("End of TestSrpServerReject");
603 }
604 
TestSrpServerIgnore(void)605 void TestSrpServerIgnore(void)
606 {
607     Srp::Server         *srpServer;
608     Srp::Client         *srpClient;
609     Srp::Client::Service service1;
610     Srp::Client::Service service2;
611     uint16_t             heapAllocations;
612 
613     Log("--------------------------------------------------------------------------------------------");
614     Log("TestSrpServerIgnore");
615 
616     InitTest();
617 
618     srpServer = &sInstance->Get<Srp::Server>();
619     srpClient = &sInstance->Get<Srp::Client>();
620 
621     heapAllocations = sHeapAllocatedPtrs.GetLength();
622 
623     PrepareService1(service1);
624     PrepareService2(service2);
625 
626     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
627     // Start SRP server.
628 
629     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
630     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
631 
632     srpServer->SetServiceHandler(HandleSrpServerUpdate, sInstance);
633 
634     srpServer->SetEnabled(true);
635     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
636 
637     AdvanceTime(10000);
638     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
639 
640     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
641     // Start SRP client.
642 
643     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
644 
645     srpClient->EnableAutoStartMode(nullptr, nullptr);
646     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
647 
648     AdvanceTime(2000);
649     VerifyOrQuit(srpClient->IsRunning());
650 
651     SuccessOrQuit(srpClient->SetHostName(kHostName));
652     SuccessOrQuit(srpClient->EnableAutoHostAddress());
653 
654     sUpdateHandlerMode = kIgnore;
655 
656     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
657     // Register a service, validate that update handler is called
658     // and ignored the update and no service is registered.
659 
660     SuccessOrQuit(srpClient->AddService(service1));
661 
662     sProcessedUpdateCallback = false;
663     sProcessedClientCallback = false;
664 
665     AdvanceTime(2 * 1000);
666 
667     VerifyOrQuit(sProcessedUpdateCallback);
668     VerifyOrQuit(sProcessedClientCallback);
669     VerifyOrQuit(sLastClientCallbackError != kErrorNone);
670 
671     VerifyOrQuit(service1.GetState() != Srp::Client::kRegistered);
672 
673     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
674 
675     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
676     // Register a second service, validate that update handler is
677     // again called and update is still ignored.
678 
679     SuccessOrQuit(srpClient->AddService(service2));
680 
681     sProcessedUpdateCallback = false;
682     sProcessedClientCallback = false;
683 
684     AdvanceTime(2 * 1000);
685 
686     VerifyOrQuit(sProcessedUpdateCallback);
687     VerifyOrQuit(sProcessedClientCallback);
688     VerifyOrQuit(sLastClientCallbackError != kErrorNone);
689 
690     VerifyOrQuit(service1.GetState() != Srp::Client::kRegistered);
691     VerifyOrQuit(service2.GetState() != Srp::Client::kRegistered);
692 
693     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
694 
695     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
696     // Disable SRP server, verify that all heap allocations by SRP server
697     // are freed.
698 
699     Log("Disabling SRP server");
700 
701     srpServer->SetEnabled(false);
702     AdvanceTime(100);
703 
704     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
705 
706     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
707     // Finalize OT instance and validate all heap allocations are freed.
708 
709     Log("Finalizing OT instance");
710     FinalizeTest();
711 
712     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
713 
714     Log("End of TestSrpServerIgnore");
715 }
716 
TestSrpServerClientRemove(bool aShouldRemoveKeyLease)717 void TestSrpServerClientRemove(bool aShouldRemoveKeyLease)
718 {
719     Srp::Server         *srpServer;
720     Srp::Client         *srpClient;
721     Srp::Client::Service service1;
722     Srp::Client::Service service2;
723     uint16_t             heapAllocations;
724 
725     Log("--------------------------------------------------------------------------------------------");
726     Log("TestSrpServerClientRemove(aShouldRemoveKeyLease:%u)", aShouldRemoveKeyLease);
727 
728     InitTest();
729 
730     srpServer = &sInstance->Get<Srp::Server>();
731     srpClient = &sInstance->Get<Srp::Client>();
732 
733     heapAllocations = sHeapAllocatedPtrs.GetLength();
734 
735     PrepareService1(service1);
736     PrepareService2(service2);
737 
738     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
739     // Start SRP server.
740 
741     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
742     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
743 
744     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
745 
746     srpServer->SetServiceHandler(HandleSrpServerUpdate, sInstance);
747 
748     srpServer->SetEnabled(true);
749     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
750 
751     AdvanceTime(10000);
752     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
753 
754     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
755     // Start SRP client.
756 
757     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
758 
759     srpClient->EnableAutoStartMode(nullptr, nullptr);
760     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
761 
762     AdvanceTime(2000);
763     VerifyOrQuit(srpClient->IsRunning());
764 
765     SuccessOrQuit(srpClient->SetHostName(kHostName));
766     SuccessOrQuit(srpClient->EnableAutoHostAddress());
767 
768     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
769     // Register two services, validate that update handler is called.
770 
771     SuccessOrQuit(srpClient->AddService(service1));
772     SuccessOrQuit(srpClient->AddService(service2));
773 
774     sUpdateHandlerMode       = kAccept;
775     sProcessedUpdateCallback = false;
776     sProcessedClientCallback = false;
777 
778     AdvanceTime(2 * 1000);
779 
780     VerifyOrQuit(sProcessedUpdateCallback);
781     VerifyOrQuit(sProcessedClientCallback);
782     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
783 
784     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
785     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
786     ValidateHost(*srpServer, kHostName);
787 
788     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
789     // Remove two services and clear key-lease, validate that update handler is called.
790 
791     SuccessOrQuit(srpClient->RemoveHostAndServices(aShouldRemoveKeyLease));
792 
793     AdvanceTime(2 * 1000);
794 
795     VerifyOrQuit(sProcessedUpdateCallback);
796     VerifyOrQuit(sProcessedClientCallback);
797     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
798 
799     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
800     VerifyOrQuit(service2.GetState() == Srp::Client::kRemoved);
801 
802     if (aShouldRemoveKeyLease)
803     {
804         VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
805     }
806     else
807     {
808         ValidateHost(*srpServer, kHostName);
809     }
810 
811     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
812     // Disable SRP server, verify that all heap allocations by SRP server
813     // are freed.
814 
815     Log("Disabling SRP server");
816 
817     srpServer->SetEnabled(false);
818     AdvanceTime(100);
819 
820     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
821 
822     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
823     // Finalize OT instance and validate all heap allocations are freed.
824 
825     Log("Finalizing OT instance");
826     FinalizeTest();
827 
828     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
829 
830     Log("End of TestSrpServerClientRemove");
831 }
832 
833 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
TestUpdateLeaseShortVariant(void)834 void TestUpdateLeaseShortVariant(void)
835 {
836     // Test behavior of SRP client and server when short variant of
837     // Update Lease Option is used (which only include lease interval).
838     // This test uses `SetUseShortLeaseOption()` method of `Srp::Client`
839     // which changes the default behavior and is available under the
840     // `REFERENCE_DEVICE` config.
841 
842     Srp::Server                *srpServer;
843     Srp::Server::LeaseConfig    leaseConfig;
844     const Srp::Server::Service *service;
845     Srp::Client                *srpClient;
846     Srp::Client::Service        service1;
847     uint16_t                    heapAllocations;
848 
849     Log("--------------------------------------------------------------------------------------------");
850     Log("TestUpdateLeaseShortVariant");
851 
852     InitTest();
853 
854     srpServer = &sInstance->Get<Srp::Server>();
855     srpClient = &sInstance->Get<Srp::Client>();
856 
857     heapAllocations = sHeapAllocatedPtrs.GetLength();
858 
859     PrepareService1(service1);
860 
861     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
862     // Start SRP server.
863 
864     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
865     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
866 
867     srpServer->SetServiceHandler(HandleSrpServerUpdate, sInstance);
868 
869     srpServer->SetEnabled(true);
870     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
871 
872     AdvanceTime(10000);
873     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
874 
875     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
876     // Check the default Lease Config on SRP server.
877     // Server to accept lease in [30 sec, 27 hours] and
878     // key-lease in [30 sec, 189 hours].
879 
880     srpServer->GetLeaseConfig(leaseConfig);
881 
882     VerifyOrQuit(leaseConfig.mMinLease == 30);             // 30 seconds
883     VerifyOrQuit(leaseConfig.mMaxLease == 27u * 3600);     // 27 hours
884     VerifyOrQuit(leaseConfig.mMinKeyLease == 30);          // 30 seconds
885     VerifyOrQuit(leaseConfig.mMaxKeyLease == 189u * 3600); // 189 hours
886 
887     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
888     // Start SRP client.
889 
890     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
891 
892     srpClient->EnableAutoStartMode(nullptr, nullptr);
893     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
894 
895     AdvanceTime(2000);
896     VerifyOrQuit(srpClient->IsRunning());
897 
898     SuccessOrQuit(srpClient->SetHostName(kHostName));
899     SuccessOrQuit(srpClient->EnableAutoHostAddress());
900 
901     sUpdateHandlerMode = kAccept;
902 
903     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
904     // Change default lease intervals on SRP client and enable
905     // "use short Update Lease Option" mode.
906 
907     srpClient->SetLeaseInterval(15u * 3600);
908     srpClient->SetKeyLeaseInterval(40u * 3600);
909 
910     srpClient->SetUseShortLeaseOption(true);
911 
912     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
913     // Register a service, validate that update handler is called
914     // and service is successfully registered.
915 
916     SuccessOrQuit(srpClient->AddService(service1));
917 
918     sProcessedUpdateCallback = false;
919     sProcessedClientCallback = false;
920 
921     AdvanceTime(2 * 1000);
922 
923     VerifyOrQuit(sProcessedUpdateCallback);
924     VerifyOrQuit(sProcessedClientCallback);
925     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
926 
927     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
928 
929     ValidateHost(*srpServer, kHostName);
930 
931     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
932     // Validate the lease info for service on SRP server. The client
933     // is set up to use "short Update Lease Option format, so it only
934     // include the lease interval as 15 hours in its request
935     // message. Server should then see 15 hours for both lease and
936     // key lease
937 
938     VerifyOrQuit(sUpdateHostLeaseInfo.mLease == 15u * 3600 * 1000);
939     VerifyOrQuit(sUpdateHostLeaseInfo.mKeyLease == 15u * 3600 * 1000);
940 
941     // Check that SRP server granted 15 hours for both lease and
942     // key lease.
943 
944     service = srpServer->GetNextHost(nullptr)->GetServices().GetHead();
945     VerifyOrQuit(service != nullptr);
946     VerifyOrQuit(service->GetLease() == 15u * 3600);
947     VerifyOrQuit(service->GetKeyLease() == 15u * 3600);
948 
949     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
950     // Remove the service.
951 
952     SuccessOrQuit(srpClient->RemoveService(service1));
953 
954     sProcessedUpdateCallback = false;
955     sProcessedClientCallback = false;
956 
957     AdvanceTime(2 * 1000);
958 
959     VerifyOrQuit(sProcessedUpdateCallback);
960     VerifyOrQuit(sProcessedClientCallback);
961     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
962 
963     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
964 
965     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
966     // Register the service again, but this time change it to request
967     // a lease time that is larger than the `LeaseConfig.mMinLease` of
968     // 27 hours. This ensures that server needs to include the Lease
969     // Option in its response (since it need to grant a different
970     // lease interval).
971 
972     service1.mLease    = 100u * 3600; // 100 hours >= 27 hours.
973     service1.mKeyLease = 110u * 3600;
974 
975     SuccessOrQuit(srpClient->AddService(service1));
976 
977     sProcessedUpdateCallback = false;
978     sProcessedClientCallback = false;
979 
980     AdvanceTime(2 * 1000);
981 
982     VerifyOrQuit(sProcessedUpdateCallback);
983     VerifyOrQuit(sProcessedClientCallback);
984     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
985 
986     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
987 
988     ValidateHost(*srpServer, kHostName);
989 
990     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
991     // Validate the lease info for service on SRP server.
992 
993     // We should see the 100 hours in request from client
994     VerifyOrQuit(sUpdateHostLeaseInfo.mLease == 100u * 3600 * 1000);
995     VerifyOrQuit(sUpdateHostLeaseInfo.mKeyLease == 100u * 3600 * 1000);
996 
997     // Check that SRP server granted  27 hours for both lease and
998     // key lease.
999 
1000     service = srpServer->GetNextHost(nullptr)->GetServices().GetHead();
1001     VerifyOrQuit(service != nullptr);
1002     VerifyOrQuit(service->GetLease() == 27u * 3600);
1003     VerifyOrQuit(service->GetKeyLease() == 27u * 3600);
1004 
1005     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1006     // Disable SRP server, verify that all heap allocations by SRP server
1007     // are freed.
1008 
1009     Log("Disabling SRP server");
1010 
1011     srpServer->SetEnabled(false);
1012     AdvanceTime(100);
1013 
1014     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1015 
1016     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1017     // Finalize OT instance and validate all heap allocations are freed.
1018 
1019     Log("Finalizing OT instance");
1020     FinalizeTest();
1021 
1022     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
1023 
1024     Log("End of TestUpdateLeaseShortVariant");
1025 }
1026 
1027 #endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
1028 
1029 #endif // ENABLE_SRP_TEST
1030 
1031 } // namespace ot
1032 
main(void)1033 int main(void)
1034 {
1035 #if ENABLE_SRP_TEST
1036     ot::TestSrpServerBase();
1037     ot::TestSrpServerReject();
1038     ot::TestSrpServerIgnore();
1039     ot::TestSrpServerClientRemove(/* aShouldRemoveKeyLease */ true);
1040     ot::TestSrpServerClientRemove(/* aShouldRemoveKeyLease */ false);
1041 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
1042     ot::TestUpdateLeaseShortVariant();
1043 #endif
1044     printf("All tests passed\n");
1045 #else
1046     printf("SRP_SERVER or SRP_CLIENT feature is not enabled\n");
1047 #endif
1048 
1049     return 0;
1050 }
1051