• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2023, 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_SRP_SERVER_ADVERTISING_PROXY_ENABLE && !OPENTHREAD_CONFIG_TIME_SYNC_ENABLE && \
47     !OPENTHREAD_PLATFORM_POSIX
48 #define ENABLE_ADV_PROXY_TEST 1
49 #else
50 #define ENABLE_ADV_PROXY_TEST 0
51 #endif
52 
53 #if ENABLE_ADV_PROXY_TEST
54 
55 using namespace ot;
56 
57 // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
58 #define Log(...)                                                                                          \
59     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 36000000), (sNow / 60000) % 60, \
60            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
61 
62 static constexpr uint16_t kMaxRaSize = 800;
63 
64 static ot::Instance *sInstance;
65 
66 static uint32_t sNow = 0;
67 static uint32_t sAlarmTime;
68 static bool     sAlarmOn = false;
69 
70 static otRadioFrame sRadioTxFrame;
71 static uint8_t      sRadioTxFramePsdu[OT_RADIO_FRAME_MAX_SIZE];
72 static bool         sRadioTxOngoing = false;
73 
74 //----------------------------------------------------------------------------------------------------------------------
75 // Function prototypes
76 
77 void ProcessRadioTxAndTasklets(void);
78 void AdvanceTime(uint32_t aDuration);
79 
80 //----------------------------------------------------------------------------------------------------------------------
81 // `otPlatRadio`
82 
83 extern "C" {
84 
otPlatRadioGetCaps(otInstance *)85 otRadioCaps otPlatRadioGetCaps(otInstance *) { return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF; }
86 
otPlatRadioTransmit(otInstance *,otRadioFrame *)87 otError otPlatRadioTransmit(otInstance *, otRadioFrame *)
88 {
89     sRadioTxOngoing = true;
90 
91     return OT_ERROR_NONE;
92 }
93 
otPlatRadioGetTransmitBuffer(otInstance *)94 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *) { return &sRadioTxFrame; }
95 
96 //----------------------------------------------------------------------------------------------------------------------
97 // `otPlatAlarm`
98 
otPlatAlarmMilliStop(otInstance *)99 void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
100 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)101 void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
102 {
103     sAlarmOn   = true;
104     sAlarmTime = aT0 + aDt;
105 }
106 
otPlatAlarmMilliGetNow(void)107 uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
108 
109 //----------------------------------------------------------------------------------------------------------------------
110 // `otPlatDnssd`
111 
112 static constexpr uint16_t kDnssdArraySize = 128;
113 
114 struct DnssdRequest
115 {
116     DnssdRequest(void) = default;
117 
DnssdRequestDnssdRequest118     DnssdRequest(otPlatDnssdRequestId aId, otPlatDnssdRegisterCallback aCallback)
119         : mId(aId)
120         , mCallback(aCallback)
121     {
122     }
123 
124     otPlatDnssdRequestId        mId;
125     otPlatDnssdRegisterCallback mCallback;
126 };
127 
128 static Array<DnssdRequest, kDnssdArraySize> sDnssdRegHostRequests;
129 static Array<DnssdRequest, kDnssdArraySize> sDnssdUnregHostRequests;
130 static Array<DnssdRequest, kDnssdArraySize> sDnssdRegServiceRequests;
131 static Array<DnssdRequest, kDnssdArraySize> sDnssdUnregServiceRequests;
132 static Array<DnssdRequest, kDnssdArraySize> sDnssdRegKeyRequests;
133 static Array<DnssdRequest, kDnssdArraySize> sDnssdUnregKeyRequests;
134 
135 static bool             sDnssdShouldCheckWithClient = true;
136 static Error            sDnssdCallbackError         = kErrorPending;
137 static otPlatDnssdState sDnssdState                 = OT_PLAT_DNSSD_READY;
138 static uint16_t         sDnssdNumHostAddresses      = 0;
139 
140 constexpr uint32_t kInfraIfIndex = 1;
141 
otPlatDnssdGetState(otInstance * aInstance)142 otPlatDnssdState otPlatDnssdGetState(otInstance *aInstance)
143 {
144     OT_UNUSED_VARIABLE(aInstance);
145 
146     return sDnssdState;
147 }
148 
otPlatDnssdRegisterService(otInstance * aInstance,const otPlatDnssdService * aService,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)149 void otPlatDnssdRegisterService(otInstance                 *aInstance,
150                                 const otPlatDnssdService   *aService,
151                                 otPlatDnssdRequestId        aRequestId,
152                                 otPlatDnssdRegisterCallback aCallback)
153 {
154     Log("otPlatDnssdRegisterService(aRequestId: %lu)", ToUlong(aRequestId));
155     Log("   hostName       : %s", aService->mHostName);
156     Log("   serviceInstance: %s", aService->mServiceInstance);
157     Log("   serviceType    : %s", aService->mServiceType);
158     Log("   num sub-types  : %u", aService->mSubTypeLabelsLength);
159 
160     for (uint16_t index = 0; index < aService->mSubTypeLabelsLength; index++)
161     {
162         Log("   sub-type %-4u  : %s", index, aService->mSubTypeLabels[index]);
163     }
164 
165     Log("   TXT data len   : %u", aService->mTxtDataLength);
166     Log("   port           : %u", aService->mPort);
167     Log("   priority       : %u", aService->mPriority);
168     Log("   weight         : %u", aService->mWeight);
169     Log("   TTL            : %u", aService->mTtl);
170     Log("   Infra-if index : %u", aService->mInfraIfIndex);
171 
172     VerifyOrQuit(aInstance == sInstance);
173     VerifyOrQuit(aService->mInfraIfIndex == kInfraIfIndex);
174 
175     if (sDnssdShouldCheckWithClient)
176     {
177         Srp::Client &srpClient = AsCoreType(aInstance).Get<Srp::Client>();
178         bool         didFind   = false;
179 
180         VerifyOrQuit(StringMatch(srpClient.GetHostInfo().GetName(), aService->mHostName));
181 
182         didFind = false;
183 
184         for (const Srp::Client::Service &service : srpClient.GetServices())
185         {
186             if (StringMatch(service.GetInstanceName(), aService->mServiceInstance))
187             {
188                 didFind = true;
189                 VerifyOrQuit(StringMatch(service.GetName(), aService->mServiceType));
190                 VerifyOrQuit(service.GetPort() == aService->mPort);
191                 VerifyOrQuit(service.GetWeight() == aService->mWeight);
192                 VerifyOrQuit(service.GetPriority() == aService->mPriority);
193                 VerifyOrQuit(service.HasSubType() == (aService->mSubTypeLabelsLength != 0));
194             }
195         }
196 
197         VerifyOrQuit(didFind);
198     }
199 
200     SuccessOrQuit(sDnssdRegServiceRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
201 
202     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
203     {
204         aCallback(aInstance, aRequestId, sDnssdCallbackError);
205     }
206 }
207 
otPlatDnssdUnregisterService(otInstance * aInstance,const otPlatDnssdService * aService,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)208 void otPlatDnssdUnregisterService(otInstance                 *aInstance,
209                                   const otPlatDnssdService   *aService,
210                                   otPlatDnssdRequestId        aRequestId,
211                                   otPlatDnssdRegisterCallback aCallback)
212 {
213     Log("otPlatDnssdUnregisterService(aRequestId: %lu)", ToUlong(aRequestId));
214     Log("   hostName       : %s", aService->mHostName);
215     Log("   serviceInstance: %s", aService->mServiceInstance);
216     Log("   serviceName    : %s", aService->mServiceType);
217     Log("   Infra-if index : %u", aService->mInfraIfIndex);
218 
219     VerifyOrQuit(aInstance == sInstance);
220     VerifyOrQuit(aService->mInfraIfIndex == kInfraIfIndex);
221 
222     if (sDnssdShouldCheckWithClient)
223     {
224         // Validate the received service info matches one of the services
225         // on SRP client.
226 
227         Srp::Client &srpClient = AsCoreType(aInstance).Get<Srp::Client>();
228         bool         didFind   = false;
229 
230         VerifyOrQuit(StringMatch(srpClient.GetHostInfo().GetName(), aService->mHostName));
231 
232         for (const Srp::Client::Service &service : srpClient.GetServices())
233         {
234             if (StringMatch(service.GetInstanceName(), aService->mServiceInstance))
235             {
236                 didFind = true;
237                 VerifyOrQuit(StringMatch(service.GetName(), aService->mServiceType));
238             }
239         }
240 
241         VerifyOrQuit(didFind);
242     }
243 
244     SuccessOrQuit(sDnssdUnregServiceRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
245 
246     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
247     {
248         aCallback(aInstance, aRequestId, sDnssdCallbackError);
249     }
250 }
251 
otPlatDnssdRegisterHost(otInstance * aInstance,const otPlatDnssdHost * aHost,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)252 void otPlatDnssdRegisterHost(otInstance                 *aInstance,
253                              const otPlatDnssdHost      *aHost,
254                              otPlatDnssdRequestId        aRequestId,
255                              otPlatDnssdRegisterCallback aCallback)
256 {
257     Log("otPlatDnssdRegisterHost(aRequestId: %lu)", ToUlong(aRequestId));
258     Log("   hostName       : %s", aHost->mHostName);
259     Log("   numAddresses   : %u", aHost->mAddressesLength);
260 
261     for (uint16_t index = 0; index < aHost->mAddressesLength; index++)
262     {
263         Log("   Address %-4u   : %s", index, AsCoreType(&aHost->mAddresses[index]).ToString().AsCString());
264     }
265 
266     Log("   TTL            : %u", aHost->mTtl);
267     Log("   Infra-if index : %u", aHost->mInfraIfIndex);
268 
269     VerifyOrQuit(aInstance == sInstance);
270     VerifyOrQuit(aHost->mInfraIfIndex == kInfraIfIndex);
271 
272     sDnssdNumHostAddresses = aHost->mAddressesLength;
273 
274     if (sDnssdShouldCheckWithClient)
275     {
276         VerifyOrQuit(StringMatch(AsCoreType(aInstance).Get<Srp::Client>().GetHostInfo().GetName(), aHost->mHostName));
277     }
278 
279     SuccessOrQuit(sDnssdRegHostRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
280 
281     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
282     {
283         aCallback(aInstance, aRequestId, sDnssdCallbackError);
284     }
285 }
286 
otPlatDnssdUnregisterHost(otInstance * aInstance,const otPlatDnssdHost * aHost,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)287 void otPlatDnssdUnregisterHost(otInstance                 *aInstance,
288                                const otPlatDnssdHost      *aHost,
289                                otPlatDnssdRequestId        aRequestId,
290                                otPlatDnssdRegisterCallback aCallback)
291 {
292     Log("otPlatDnssdUnregisterHost(aRequestId: %lu)", ToUlong(aRequestId));
293     Log("   hostName       : %s", aHost->mHostName);
294     Log("   Infra-if index : %u", aHost->mInfraIfIndex);
295 
296     VerifyOrQuit(sInstance == aInstance);
297     VerifyOrQuit(aHost->mInfraIfIndex == kInfraIfIndex);
298 
299     if (sDnssdShouldCheckWithClient)
300     {
301         VerifyOrQuit(StringMatch(AsCoreType(aInstance).Get<Srp::Client>().GetHostInfo().GetName(), aHost->mHostName));
302     }
303 
304     SuccessOrQuit(sDnssdUnregHostRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
305 
306     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
307     {
308         aCallback(aInstance, aRequestId, sDnssdCallbackError);
309     }
310 }
311 
otPlatDnssdRegisterKey(otInstance * aInstance,const otPlatDnssdKey * aKey,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)312 void otPlatDnssdRegisterKey(otInstance                 *aInstance,
313                             const otPlatDnssdKey       *aKey,
314                             otPlatDnssdRequestId        aRequestId,
315                             otPlatDnssdRegisterCallback aCallback)
316 {
317     Log("otPlatDnssdRegisterKey(aRequestId: %lu)", ToUlong(aRequestId));
318     Log("   name           : %s", aKey->mName);
319     Log("   serviceType    : %s", aKey->mServiceType == nullptr ? "(null)" : aKey->mServiceType);
320     Log("   key data-len   : %u", aKey->mKeyDataLength);
321     Log("   TTL            : %u", aKey->mTtl);
322 
323     VerifyOrQuit(aInstance == sInstance);
324     VerifyOrQuit(aKey->mInfraIfIndex == kInfraIfIndex);
325 
326     if (sDnssdShouldCheckWithClient)
327     {
328         if (aKey->mServiceType == nullptr)
329         {
330             VerifyOrQuit(StringMatch(AsCoreType(aInstance).Get<Srp::Client>().GetHostInfo().GetName(), aKey->mName));
331         }
332         else
333         {
334             bool didFind = false;
335 
336             for (const Srp::Client::Service &service : AsCoreType(aInstance).Get<Srp::Client>().GetServices())
337             {
338                 if (StringMatch(service.GetInstanceName(), aKey->mName))
339                 {
340                     didFind = true;
341                     VerifyOrQuit(StringMatch(service.GetName(), aKey->mServiceType));
342                 }
343             }
344 
345             VerifyOrQuit(didFind);
346         }
347     }
348 
349     SuccessOrQuit(sDnssdRegKeyRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
350 
351     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
352     {
353         aCallback(aInstance, aRequestId, sDnssdCallbackError);
354     }
355 }
356 
otPlatDnssdUnregisterKey(otInstance * aInstance,const otPlatDnssdKey * aKey,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)357 void otPlatDnssdUnregisterKey(otInstance                 *aInstance,
358                               const otPlatDnssdKey       *aKey,
359                               otPlatDnssdRequestId        aRequestId,
360                               otPlatDnssdRegisterCallback aCallback)
361 {
362     Log("otPlatDnssdUnregisterKey(aRequestId: %lu)", ToUlong(aRequestId));
363     Log("   name           : %s", aKey->mName);
364 
365     VerifyOrQuit(aInstance == sInstance);
366     VerifyOrQuit(aKey->mInfraIfIndex == kInfraIfIndex);
367 
368     if (sDnssdShouldCheckWithClient)
369     {
370         if (aKey->mServiceType == nullptr)
371         {
372             VerifyOrQuit(StringMatch(AsCoreType(aInstance).Get<Srp::Client>().GetHostInfo().GetName(), aKey->mName));
373         }
374         else
375         {
376             bool didFind = false;
377 
378             for (const Srp::Client::Service &service : AsCoreType(aInstance).Get<Srp::Client>().GetServices())
379             {
380                 if (StringMatch(service.GetInstanceName(), aKey->mName))
381                 {
382                     didFind = true;
383                     VerifyOrQuit(StringMatch(service.GetName(), aKey->mServiceType));
384                 }
385             }
386 
387             VerifyOrQuit(didFind);
388         }
389     }
390 
391     SuccessOrQuit(sDnssdUnregKeyRequests.PushBack(DnssdRequest(aRequestId, aCallback)));
392 
393     if ((sDnssdCallbackError != kErrorPending) && (aCallback != nullptr))
394     {
395         aCallback(aInstance, aRequestId, sDnssdCallbackError);
396     }
397 }
398 
399 // Number of times we expect each `otPlatDnssd` request to be called
400 struct DnssdRequestCounts : public Clearable<DnssdRequestCounts>
401 {
DnssdRequestCountsDnssdRequestCounts402     DnssdRequestCounts(void) { Clear(); }
403 
404     uint16_t mKeyReg;
405     uint16_t mHostReg;
406     uint16_t mServiceReg;
407     uint16_t mKeyUnreg;
408     uint16_t mHostUnreg;
409     uint16_t mServiceUnreg;
410 };
411 
VerifyDnnsdRequests(const DnssdRequestCounts & aRequestCounts,bool aAllowMoreUnregs=false)412 void VerifyDnnsdRequests(const DnssdRequestCounts &aRequestCounts, bool aAllowMoreUnregs = false)
413 {
414     VerifyOrQuit(sDnssdRegKeyRequests.GetLength() == aRequestCounts.mKeyReg);
415     VerifyOrQuit(sDnssdRegHostRequests.GetLength() == aRequestCounts.mHostReg);
416     VerifyOrQuit(sDnssdRegServiceRequests.GetLength() == aRequestCounts.mServiceReg);
417 
418     if (aAllowMoreUnregs)
419     {
420         VerifyOrQuit(sDnssdUnregKeyRequests.GetLength() >= aRequestCounts.mKeyUnreg);
421         VerifyOrQuit(sDnssdUnregHostRequests.GetLength() >= aRequestCounts.mHostUnreg);
422         VerifyOrQuit(sDnssdUnregServiceRequests.GetLength() >= aRequestCounts.mServiceUnreg);
423     }
424     else
425     {
426         VerifyOrQuit(sDnssdUnregKeyRequests.GetLength() == aRequestCounts.mKeyUnreg);
427         VerifyOrQuit(sDnssdUnregHostRequests.GetLength() == aRequestCounts.mHostUnreg);
428         VerifyOrQuit(sDnssdUnregServiceRequests.GetLength() == aRequestCounts.mServiceUnreg);
429     }
430 }
431 
432 //----------------------------------------------------------------------------------------------------------------------
433 
434 Array<void *, 500> sHeapAllocatedPtrs;
435 
436 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
otPlatCAlloc(size_t aNum,size_t aSize)437 void *otPlatCAlloc(size_t aNum, size_t aSize)
438 {
439     void *ptr = calloc(aNum, aSize);
440 
441     SuccessOrQuit(sHeapAllocatedPtrs.PushBack(ptr));
442 
443     return ptr;
444 }
445 
otPlatFree(void * aPtr)446 void otPlatFree(void *aPtr)
447 {
448     if (aPtr != nullptr)
449     {
450         void **entry = sHeapAllocatedPtrs.Find(aPtr);
451 
452         VerifyOrQuit(entry != nullptr, "A heap allocated item is freed twice");
453         sHeapAllocatedPtrs.Remove(*entry);
454     }
455 
456     free(aPtr);
457 }
458 #endif
459 
460 #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)461 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
462 {
463     OT_UNUSED_VARIABLE(aLogLevel);
464     OT_UNUSED_VARIABLE(aLogRegion);
465 
466     va_list args;
467 
468     printf("   ");
469     va_start(args, aFormat);
470     vprintf(aFormat, args);
471     va_end(args);
472     printf("\n");
473 }
474 #endif
475 
476 } // extern "C"
477 
478 //---------------------------------------------------------------------------------------------------------------------
479 
ProcessRadioTxAndTasklets(void)480 void ProcessRadioTxAndTasklets(void)
481 {
482     do
483     {
484         if (sRadioTxOngoing)
485         {
486             sRadioTxOngoing = false;
487             otPlatRadioTxStarted(sInstance, &sRadioTxFrame);
488             otPlatRadioTxDone(sInstance, &sRadioTxFrame, nullptr, OT_ERROR_NONE);
489         }
490 
491         otTaskletsProcess(sInstance);
492     } while (otTaskletsArePending(sInstance));
493 }
494 
AdvanceTime(uint32_t aDuration)495 void AdvanceTime(uint32_t aDuration)
496 {
497     uint32_t time = sNow + aDuration;
498 
499     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
500 
501     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
502     {
503         ProcessRadioTxAndTasklets();
504         sNow = sAlarmTime;
505         otPlatAlarmMilliFired(sInstance);
506     }
507 
508     ProcessRadioTxAndTasklets();
509     sNow = time;
510 }
511 
InitTest(void)512 void InitTest(void)
513 {
514     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
515     // Initialize OT instance.
516 
517     sNow      = 0;
518     sAlarmOn  = false;
519     sInstance = static_cast<Instance *>(testInitInstance());
520 
521     memset(&sRadioTxFrame, 0, sizeof(sRadioTxFrame));
522     sRadioTxFrame.mPsdu = sRadioTxFramePsdu;
523     sRadioTxOngoing     = false;
524 
525     sDnssdShouldCheckWithClient = true;
526     sDnssdState                 = OT_PLAT_DNSSD_READY;
527     sDnssdCallbackError         = kErrorPending;
528     sDnssdRegHostRequests.Clear();
529     sDnssdUnregHostRequests.Clear();
530     sDnssdRegServiceRequests.Clear();
531     sDnssdUnregServiceRequests.Clear();
532 
533     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
534     // Initialize Border Router and start Thread operation.
535 
536     otOperationalDataset     dataset;
537     otOperationalDatasetTlvs datasetTlvs;
538 
539     SuccessOrQuit(otDatasetCreateNewNetwork(sInstance, &dataset));
540     SuccessOrQuit(otDatasetConvertToTlvs(&dataset, &datasetTlvs));
541     SuccessOrQuit(otDatasetSetActiveTlvs(sInstance, &datasetTlvs));
542 
543     SuccessOrQuit(otIp6SetEnabled(sInstance, true));
544     SuccessOrQuit(otThreadSetEnabled(sInstance, true));
545 
546     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
547     // Ensure device starts as leader.
548 
549     AdvanceTime(10000);
550 
551     VerifyOrQuit(otThreadGetDeviceRole(sInstance) == OT_DEVICE_ROLE_LEADER);
552 }
553 
FinalizeTest(void)554 void FinalizeTest(void)
555 {
556     SuccessOrQuit(otIp6SetEnabled(sInstance, false));
557     SuccessOrQuit(otThreadSetEnabled(sInstance, false));
558     SuccessOrQuit(otInstanceErasePersistentInfo(sInstance));
559     testFreeInstance(sInstance);
560 }
561 
562 //---------------------------------------------------------------------------------------------------------------------
563 // SRP Client callback
564 
565 static bool  sProcessedClientCallback = false;
566 static Error sLastClientCallbackError = kErrorNone;
567 
HandleSrpClientCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices,void * aContext)568 void HandleSrpClientCallback(otError                    aError,
569                              const otSrpClientHostInfo *aHostInfo,
570                              const otSrpClientService  *aServices,
571                              const otSrpClientService  *aRemovedServices,
572                              void                      *aContext)
573 {
574     Log("HandleSrpClientCallback() called with error %s", ErrorToString(aError));
575 
576     VerifyOrQuit(aContext == sInstance);
577 
578     sProcessedClientCallback = true;
579     sLastClientCallbackError = aError;
580 
581     OT_UNUSED_VARIABLE(aHostInfo);
582     OT_UNUSED_VARIABLE(aServices);
583     OT_UNUSED_VARIABLE(aRemovedServices);
584 }
585 
586 static const char kHostName[] = "awesomehost";
587 
PrepareService1(Srp::Client::Service & aService)588 void PrepareService1(Srp::Client::Service &aService)
589 {
590     static const char          kServiceName[]   = "_srv1._udp";
591     static const char          kInstanceLabel[] = "service1";
592     static const char          kSub1[]          = "_sub1";
593     static const char          kSub2[]          = "_sub2";
594     static const char          kSub3[]          = "_sub3";
595     static const char         *kSubLabels[]     = {kSub1, kSub2, kSub3, nullptr};
596     static const char          kTxtKey1[]       = "ABCD";
597     static const uint8_t       kTxtValue1[]     = {'a', '0'};
598     static const char          kTxtKey2[]       = "Z0";
599     static const uint8_t       kTxtValue2[]     = {'1', '2', '3'};
600     static const char          kTxtKey3[]       = "D";
601     static const uint8_t       kTxtValue3[]     = {0};
602     static const otDnsTxtEntry kTxtEntries[]    = {
603            {kTxtKey1, kTxtValue1, sizeof(kTxtValue1)},
604            {kTxtKey2, kTxtValue2, sizeof(kTxtValue2)},
605            {kTxtKey3, kTxtValue3, sizeof(kTxtValue3)},
606     };
607 
608     memset(&aService, 0, sizeof(aService));
609     aService.mName          = kServiceName;
610     aService.mInstanceName  = kInstanceLabel;
611     aService.mSubTypeLabels = kSubLabels;
612     aService.mTxtEntries    = kTxtEntries;
613     aService.mNumTxtEntries = 3;
614     aService.mPort          = 777;
615     aService.mWeight        = 1;
616     aService.mPriority      = 2;
617 }
618 
PrepareService2(Srp::Client::Service & aService)619 void PrepareService2(Srp::Client::Service &aService)
620 {
621     static const char  kService2Name[]   = "_matter._udp";
622     static const char  kInstance2Label[] = "service2";
623     static const char  kSub4[]           = "_44444444";
624     static const char *kSubLabels2[]     = {kSub4, nullptr};
625 
626     memset(&aService, 0, sizeof(aService));
627     aService.mName          = kService2Name;
628     aService.mInstanceName  = kInstance2Label;
629     aService.mSubTypeLabels = kSubLabels2;
630     aService.mTxtEntries    = nullptr;
631     aService.mNumTxtEntries = 0;
632     aService.mPort          = 555;
633     aService.mWeight        = 0;
634     aService.mPriority      = 3;
635 }
636 
637 //----------------------------------------------------------------------------------------------------------------------
638 
639 typedef Dnssd::RequestId      RequestId;
640 typedef Dnssd::RequestIdRange RequestIdRange;
641 
ValidateRequestIdRange(const RequestIdRange & aIdRange,RequestId aStart,RequestId aEnd)642 void ValidateRequestIdRange(const RequestIdRange &aIdRange, RequestId aStart, RequestId aEnd)
643 {
644     RequestId maxId         = NumericLimits<RequestId>::kMax;
645     bool      shouldContain = false;
646 
647     VerifyOrQuit(!aIdRange.IsEmpty());
648 
649     for (RequestId id = aStart - 5; id != aEnd + 6; id++)
650     {
651         // `idRange` should contain IDs within range `[aStart, aEnd]`
652 
653         if (id == aStart)
654         {
655             shouldContain = true;
656         }
657 
658         if (id == aEnd + 1)
659         {
660             shouldContain = false;
661         }
662 
663         VerifyOrQuit(aIdRange.Contains(id) == shouldContain);
664     }
665 
666     // Test values that half the range apart
667 
668     for (RequestId id = aStart + maxId / 2 - 10; id != aEnd + maxId / 2 + 10; id++)
669     {
670         VerifyOrQuit(!aIdRange.Contains(id));
671     }
672 }
673 
TestDnssdRequestIdRange(void)674 void TestDnssdRequestIdRange(void)
675 {
676     RequestId      maxId = NumericLimits<RequestId>::kMax;
677     RequestIdRange idRange;
678 
679     Log("--------------------------------------------------------------------------------------------");
680     Log("TestDnssdRequestIdRange");
681 
682     VerifyOrQuit(idRange.IsEmpty());
683 
684     idRange.Add(5);
685     ValidateRequestIdRange(idRange, 5, 5);
686 
687     idRange.Remove(4);
688     ValidateRequestIdRange(idRange, 5, 5);
689 
690     idRange.Remove(6);
691     ValidateRequestIdRange(idRange, 5, 5);
692 
693     idRange.Remove(5);
694     VerifyOrQuit(idRange.IsEmpty());
695     VerifyOrQuit(!idRange.Contains(5));
696 
697     // Adding and removing multiple IDs
698 
699     idRange.Add(10);
700     idRange.Add(15);
701     ValidateRequestIdRange(idRange, 10, 15);
702 
703     idRange.Add(12);
704     ValidateRequestIdRange(idRange, 10, 15);
705     idRange.Add(15);
706     ValidateRequestIdRange(idRange, 10, 15);
707     idRange.Add(10);
708     ValidateRequestIdRange(idRange, 10, 15);
709 
710     idRange.Add(9);
711     ValidateRequestIdRange(idRange, 9, 15);
712     idRange.Add(16);
713     ValidateRequestIdRange(idRange, 9, 16);
714 
715     idRange.Remove(10);
716     ValidateRequestIdRange(idRange, 9, 16);
717     idRange.Remove(15);
718     ValidateRequestIdRange(idRange, 9, 16);
719 
720     idRange.Remove(8);
721     ValidateRequestIdRange(idRange, 9, 16);
722     idRange.Remove(17);
723     ValidateRequestIdRange(idRange, 9, 16);
724 
725     idRange.Remove(9);
726     ValidateRequestIdRange(idRange, 10, 16);
727     idRange.Remove(16);
728     ValidateRequestIdRange(idRange, 10, 15);
729 
730     idRange.Clear();
731     VerifyOrQuit(idRange.IsEmpty());
732     VerifyOrQuit(!idRange.Contains(10));
733 
734     // Ranges close to roll-over max value
735 
736     idRange.Add(maxId);
737     ValidateRequestIdRange(idRange, maxId, maxId);
738 
739     idRange.Remove(0);
740     ValidateRequestIdRange(idRange, maxId, maxId);
741     idRange.Remove(maxId - 1);
742     ValidateRequestIdRange(idRange, maxId, maxId);
743 
744     idRange.Add(0);
745     ValidateRequestIdRange(idRange, maxId, 0);
746 
747     idRange.Add(maxId - 2);
748     ValidateRequestIdRange(idRange, maxId - 2, 0);
749 
750     idRange.Add(3);
751     ValidateRequestIdRange(idRange, maxId - 2, 3);
752     idRange.Add(3);
753     ValidateRequestIdRange(idRange, maxId - 2, 3);
754 
755     idRange.Remove(4);
756     ValidateRequestIdRange(idRange, maxId - 2, 3);
757     idRange.Remove(maxId - 3);
758     ValidateRequestIdRange(idRange, maxId - 2, 3);
759 
760     idRange.Remove(3);
761     ValidateRequestIdRange(idRange, maxId - 2, 2);
762 
763     idRange.Remove(maxId - 2);
764     ValidateRequestIdRange(idRange, maxId - 1, 2);
765 
766     Log("End of TestDnssdRequestIdRange");
767 }
768 
TestSrpAdvProxy(void)769 void TestSrpAdvProxy(void)
770 {
771     NetworkData::OnMeshPrefixConfig prefixConfig;
772     Srp::Server                    *srpServer;
773     Srp::Client                    *srpClient;
774     Srp::AdvertisingProxy          *advProxy;
775     Srp::Client::Service            service1;
776     Srp::Client::Service            service2;
777     DnssdRequestCounts              dnssdCounts;
778     uint16_t                        heapAllocations;
779 
780     Log("--------------------------------------------------------------------------------------------");
781     Log("TestSrpAdvProxy");
782 
783     InitTest();
784 
785     srpServer = &sInstance->Get<Srp::Server>();
786     srpClient = &sInstance->Get<Srp::Client>();
787     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
788 
789     heapAllocations = sHeapAllocatedPtrs.GetLength();
790 
791     PrepareService1(service1);
792     PrepareService2(service2);
793 
794     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
795     Log("Add an on-mesh prefix (with SLAAC) to network data");
796 
797     prefixConfig.Clear();
798     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
799     prefixConfig.mPrefix.mLength = 64;
800     prefixConfig.mStable         = true;
801     prefixConfig.mSlaac          = true;
802     prefixConfig.mPreferred      = true;
803     prefixConfig.mOnMesh         = true;
804     prefixConfig.mDefaultRoute   = false;
805     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
806 
807     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
808     SuccessOrQuit(otBorderRouterRegister(sInstance));
809 
810     // Configure Dnssd platform API behavior
811 
812     sDnssdRegHostRequests.Clear();
813     sDnssdRegServiceRequests.Clear();
814     sDnssdUnregHostRequests.Clear();
815     sDnssdUnregServiceRequests.Clear();
816     sDnssdRegKeyRequests.Clear();
817     sDnssdUnregKeyRequests.Clear();
818 
819     sDnssdState                 = OT_PLAT_DNSSD_READY;
820     sDnssdShouldCheckWithClient = true;
821     sDnssdCallbackError         = kErrorNone; // Invoke callback directly from dnssd APIs
822 
823     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
824     Log("Start SRP server");
825 
826     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
827 
828     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
829     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
830 
831     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
832 
833     srpServer->SetServiceHandler(nullptr, sInstance);
834 
835     srpServer->SetEnabled(true);
836     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
837 
838     AdvanceTime(10000);
839     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
840     VerifyOrQuit(advProxy->IsRunning());
841 
842     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
843     Log("Start SRP client");
844 
845     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
846     srpClient->SetLeaseInterval(180);
847 
848     srpClient->EnableAutoStartMode(nullptr, nullptr);
849     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
850 
851     AdvanceTime(2000);
852     VerifyOrQuit(srpClient->IsRunning());
853 
854     SuccessOrQuit(srpClient->SetHostName(kHostName));
855     SuccessOrQuit(srpClient->EnableAutoHostAddress());
856 
857     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
858     Log("Register a service");
859 
860     SuccessOrQuit(srpClient->AddService(service1));
861 
862     sProcessedClientCallback = false;
863 
864     AdvanceTime(2 * 1000);
865 
866     dnssdCounts.mKeyReg += 2;
867     dnssdCounts.mHostReg++;
868     dnssdCounts.mServiceReg++;
869     VerifyDnnsdRequests(dnssdCounts);
870 
871     VerifyOrQuit(sProcessedClientCallback);
872     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
873 
874     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
875 
876     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
877     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
878 
879     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
880     Log("Register a second service");
881 
882     SuccessOrQuit(srpClient->AddService(service2));
883 
884     sProcessedClientCallback = false;
885 
886     AdvanceTime(2 * 1000);
887 
888     // This time we should only see the new service and its key being
889     // registered as the host is same as before and already registered
890 
891     dnssdCounts.mKeyReg++;
892     dnssdCounts.mServiceReg++;
893     VerifyDnnsdRequests(dnssdCounts);
894 
895     VerifyOrQuit(sProcessedClientCallback);
896     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
897 
898     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
899     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
900 
901     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
902     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
903 
904     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
905     Log("Wait for longer than lease interval for client to refresh");
906 
907     sProcessedClientCallback = false;
908 
909     AdvanceTime(181 * 1000);
910 
911     VerifyOrQuit(sProcessedClientCallback);
912 
913     // Validate that adv-proxy does not update any of registration on
914     // DNS-SD platform since there is no change.
915 
916     VerifyDnnsdRequests(dnssdCounts);
917 
918     VerifyOrQuit(advProxy->GetCounters().mAdvTotal >= 3);
919     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == advProxy->GetCounters().mAdvTotal);
920 
921     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
922     Log("Add a new on-mesh prefix so to get a new host address");
923 
924     prefixConfig.Clear();
925     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:abba::"));
926     prefixConfig.mPrefix.mLength = 64;
927     prefixConfig.mStable         = true;
928     prefixConfig.mSlaac          = true;
929     prefixConfig.mPreferred      = true;
930     prefixConfig.mOnMesh         = true;
931     prefixConfig.mDefaultRoute   = false;
932     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
933 
934     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
935     SuccessOrQuit(otBorderRouterRegister(sInstance));
936 
937     sProcessedClientCallback = false;
938 
939     AdvanceTime(5 * 1000);
940 
941     // This time we should only see new host registration
942     // since that's the only thing that changes
943 
944     dnssdCounts.mHostReg++;
945     VerifyDnnsdRequests(dnssdCounts);
946 
947     VerifyOrQuit(sProcessedClientCallback);
948     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
949 
950     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
951     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
952 
953     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
954     Log("Remove the first service on client");
955 
956     SuccessOrQuit(srpClient->RemoveService(service1));
957 
958     sProcessedClientCallback = false;
959 
960     AdvanceTime(2 * 1000);
961 
962     // We should see the service being unregistered
963     // by advertising proxy on DNS-SD platform but its key
964     // remains registered.
965 
966     dnssdCounts.mServiceUnreg++;
967     VerifyDnnsdRequests(dnssdCounts);
968 
969     VerifyOrQuit(sProcessedClientCallback);
970     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
971 
972     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
973     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
974 
975     // Wait for more than lease interval again and make sure
976     // there is no change in DNS-SD platform API calls.
977 
978     sProcessedClientCallback = false;
979 
980     AdvanceTime(181 * 1000);
981 
982     VerifyOrQuit(sProcessedClientCallback);
983     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
984 
985     VerifyDnnsdRequests(dnssdCounts);
986 
987     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
988     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
989 
990     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
991     Log("Change service 2 on client, remove its sub-type");
992 
993     SuccessOrQuit(srpClient->ClearService(service2));
994     PrepareService2(service2);
995     service2.mSubTypeLabels = nullptr;
996 
997     SuccessOrQuit(srpClient->AddService(service2));
998 
999     sProcessedClientCallback = false;
1000 
1001     AdvanceTime(2 * 1000);
1002 
1003     // Since the service is now changed, advertising proxy
1004     // should update it (re-register it) on DNS-SD APIs.
1005 
1006     dnssdCounts.mServiceReg++;
1007     VerifyDnnsdRequests(dnssdCounts);
1008 
1009     VerifyOrQuit(sProcessedClientCallback);
1010     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1011 
1012     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
1013     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1014 
1015     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1016     Log("Remove the host on client");
1017 
1018     SuccessOrQuit(srpClient->RemoveHostAndServices(/* aShouldRemoveKeyLease */ false));
1019 
1020     sProcessedClientCallback = false;
1021 
1022     AdvanceTime(2 * 1000);
1023 
1024     // We should see the host and service being unregistered
1025     // on DNS-SD APIs but keys remain unchanged.
1026 
1027     dnssdCounts.mHostUnreg++;
1028     dnssdCounts.mServiceUnreg++;
1029     VerifyDnnsdRequests(dnssdCounts);
1030 
1031     VerifyOrQuit(sProcessedClientCallback);
1032     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1033 
1034     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
1035     VerifyOrQuit(service2.GetState() == Srp::Client::kRemoved);
1036 
1037     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1038     Log("Remove the host on client again and force an update to be sent to server");
1039 
1040     SuccessOrQuit(srpClient->SetHostName(kHostName));
1041     SuccessOrQuit(srpClient->RemoveHostAndServices(/* aShouldRemoveKeyLease */ false, /* aSendUnregToServer */ true));
1042 
1043     sProcessedClientCallback = false;
1044 
1045     AdvanceTime(2 * 1000);
1046 
1047     // We should see no changes (no calls) to DNS-SD APIs.
1048 
1049     VerifyDnnsdRequests(dnssdCounts);
1050 
1051     VerifyOrQuit(sProcessedClientCallback);
1052     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1053 
1054     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1055     Log("Re-add service 1 on client and register with server");
1056 
1057     SuccessOrQuit(srpClient->SetHostName(kHostName));
1058     SuccessOrQuit(srpClient->EnableAutoHostAddress());
1059     PrepareService1(service1);
1060     SuccessOrQuit(srpClient->AddService(service1));
1061 
1062     sProcessedClientCallback = false;
1063 
1064     AdvanceTime(2 * 1000);
1065 
1066     // We should see one host register and one service register
1067     // on DNS-SD APIs. Keys are already registered.
1068 
1069     dnssdCounts.mHostReg++;
1070     dnssdCounts.mServiceReg++;
1071     VerifyDnnsdRequests(dnssdCounts);
1072 
1073     VerifyOrQuit(sProcessedClientCallback);
1074     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1075 
1076     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1077 
1078     // Wait for more than lease interval again and make sure
1079     // there is no change in DNS-SD platform API calls.
1080 
1081     sProcessedClientCallback = false;
1082 
1083     AdvanceTime(181 * 1000);
1084 
1085     VerifyOrQuit(sProcessedClientCallback);
1086     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1087 
1088     VerifyDnnsdRequests(dnssdCounts);
1089 
1090     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1091 
1092     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1093     Log("Disable SRP client and wait for lease time to expire");
1094 
1095     srpClient->ClearHostAndServices(); // does not signal removal to server
1096 
1097     // Since we clear everything on SRP client, we disable
1098     // matching the services with client from `otPlatDnssd`
1099     // APIs.
1100     sDnssdShouldCheckWithClient = false;
1101 
1102     AdvanceTime(181 * 1000);
1103 
1104     // Make sure host and service are unregistered.
1105 
1106     dnssdCounts.mHostUnreg++;
1107     dnssdCounts.mServiceUnreg++;
1108     VerifyDnnsdRequests(dnssdCounts);
1109 
1110     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1111     Log("Disable SRP server");
1112 
1113     // Verify that all heap allocations by SRP server
1114     // and Advertising Proxy are freed.
1115 
1116     srpServer->SetEnabled(false);
1117     AdvanceTime(100);
1118     VerifyOrQuit(!advProxy->IsRunning());
1119 
1120     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == advProxy->GetCounters().mAdvTotal);
1121     VerifyOrQuit(advProxy->GetCounters().mAdvTimeout == 0);
1122     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 0);
1123     VerifyOrQuit(advProxy->GetCounters().mAdvSkipped == 0);
1124     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1125 
1126     dnssdCounts.mKeyUnreg += 3;
1127     VerifyDnnsdRequests(dnssdCounts);
1128 
1129     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1130 
1131     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1132     Log("Finalize OT instance and validate all heap allocations are freed");
1133 
1134     FinalizeTest();
1135 
1136     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
1137 
1138     Log("End of TestSrpAdvProxy");
1139 }
1140 
TestSrpAdvProxyDnssdStateChange(void)1141 void TestSrpAdvProxyDnssdStateChange(void)
1142 {
1143     NetworkData::OnMeshPrefixConfig prefixConfig;
1144     Srp::Server                    *srpServer;
1145     Srp::Client                    *srpClient;
1146     Srp::AdvertisingProxy          *advProxy;
1147     Srp::Client::Service            service1;
1148     Srp::Client::Service            service2;
1149     DnssdRequestCounts              dnssdCounts;
1150     uint16_t                        heapAllocations;
1151 
1152     Log("--------------------------------------------------------------------------------------------");
1153     Log("TestSrpAdvProxyDnssdStateChange");
1154 
1155     InitTest();
1156 
1157     srpServer = &sInstance->Get<Srp::Server>();
1158     srpClient = &sInstance->Get<Srp::Client>();
1159     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
1160 
1161     heapAllocations = sHeapAllocatedPtrs.GetLength();
1162 
1163     PrepareService1(service1);
1164     PrepareService2(service2);
1165 
1166     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1167     Log("Add an on-mesh prefix (with SLAAC) to network data");
1168 
1169     prefixConfig.Clear();
1170     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
1171     prefixConfig.mPrefix.mLength = 64;
1172     prefixConfig.mStable         = true;
1173     prefixConfig.mSlaac          = true;
1174     prefixConfig.mPreferred      = true;
1175     prefixConfig.mOnMesh         = true;
1176     prefixConfig.mDefaultRoute   = false;
1177     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
1178 
1179     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1180     SuccessOrQuit(otBorderRouterRegister(sInstance));
1181 
1182     // Configure Dnssd platform API behavior
1183 
1184     sDnssdRegHostRequests.Clear();
1185     sDnssdRegServiceRequests.Clear();
1186     sDnssdUnregHostRequests.Clear();
1187     sDnssdUnregServiceRequests.Clear();
1188     sDnssdRegKeyRequests.Clear();
1189     sDnssdUnregKeyRequests.Clear();
1190 
1191     sDnssdState                 = OT_PLAT_DNSSD_STOPPED;
1192     sDnssdShouldCheckWithClient = true;
1193     sDnssdCallbackError         = kErrorNone; // Invoke callback directly
1194 
1195     VerifyOrQuit(!advProxy->IsRunning());
1196 
1197     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1198     Log("Start SRP server");
1199 
1200     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
1201 
1202     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
1203     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
1204 
1205     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
1206 
1207     srpServer->SetServiceHandler(nullptr, sInstance);
1208 
1209     srpServer->SetEnabled(true);
1210     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
1211 
1212     AdvanceTime(10000);
1213     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
1214     VerifyOrQuit(!advProxy->IsRunning());
1215 
1216     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1217     Log("Start SRP client");
1218 
1219     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
1220     srpClient->SetLeaseInterval(180);
1221 
1222     srpClient->EnableAutoStartMode(nullptr, nullptr);
1223     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
1224 
1225     AdvanceTime(2000);
1226     VerifyOrQuit(srpClient->IsRunning());
1227 
1228     SuccessOrQuit(srpClient->SetHostName(kHostName));
1229     SuccessOrQuit(srpClient->EnableAutoHostAddress());
1230 
1231     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1232     Log("Register a services");
1233 
1234     SuccessOrQuit(srpClient->AddService(service1));
1235 
1236     sProcessedClientCallback = false;
1237 
1238     AdvanceTime(2 * 1000);
1239 
1240     VerifyOrQuit(sProcessedClientCallback);
1241     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1242 
1243     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1244 
1245     VerifyDnnsdRequests(dnssdCounts);
1246 
1247     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1248     Log("Register a second service");
1249 
1250     SuccessOrQuit(srpClient->AddService(service2));
1251 
1252     sProcessedClientCallback = false;
1253 
1254     AdvanceTime(2 * 1000);
1255 
1256     VerifyOrQuit(sProcessedClientCallback);
1257     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1258 
1259     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1260     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1261 
1262     // None of the DNS-SD APIs should be called since its state
1263     // `OT_PLAT_DNSSD_STOPPED` (`dnssdCounts` is all zeros).
1264     VerifyDnnsdRequests(dnssdCounts);
1265 
1266     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1267     Log("Update DNS-SD state and signal that state is changed");
1268 
1269     sDnssdState = OT_PLAT_DNSSD_READY;
1270     otPlatDnssdStateHandleStateChange(sInstance);
1271 
1272     AdvanceTime(5);
1273 
1274     VerifyOrQuit(advProxy->IsRunning());
1275     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 1);
1276 
1277     // Now the host and two services should be registered on
1278     // DNS-SD platform
1279 
1280     dnssdCounts.mHostReg++;
1281     dnssdCounts.mServiceReg += 2;
1282     dnssdCounts.mKeyReg += 3;
1283     VerifyDnnsdRequests(dnssdCounts);
1284 
1285     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1286     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1287 
1288     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1289     Log("Wait for longer than lease interval for client to refresh");
1290 
1291     sProcessedClientCallback = false;
1292 
1293     AdvanceTime(181 * 1000);
1294 
1295     VerifyOrQuit(sProcessedClientCallback);
1296 
1297     // Validate that adv-proxy does not update any of registration on
1298     // DNS-SD platform since there is no change.
1299     VerifyDnnsdRequests(dnssdCounts);
1300 
1301     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1302     Log("Update DNS-SD state to `STOPPED` and signal its change");
1303 
1304     sDnssdState = OT_PLAT_DNSSD_STOPPED;
1305     otPlatDnssdStateHandleStateChange(sInstance);
1306 
1307     AdvanceTime(5);
1308 
1309     VerifyOrQuit(!advProxy->IsRunning());
1310     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 2);
1311 
1312     // Since DNS-SD platform signal that it is stopped,
1313     // there should be no calls to any of APIs.
1314 
1315     VerifyDnnsdRequests(dnssdCounts);
1316 
1317     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1318     Log("Wait for longer than lease interval for client to refresh");
1319 
1320     sProcessedClientCallback = false;
1321 
1322     AdvanceTime(181 * 1000);
1323 
1324     VerifyOrQuit(sProcessedClientCallback);
1325     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1326     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1327 
1328     // The DNS-SD API counters should remain unchanged
1329 
1330     VerifyDnnsdRequests(dnssdCounts);
1331 
1332     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1333     Log("Update DNS-SD state to `READY` and signal its change");
1334 
1335     sDnssdState = OT_PLAT_DNSSD_READY;
1336     otPlatDnssdStateHandleStateChange(sInstance);
1337 
1338     AdvanceTime(5);
1339 
1340     VerifyOrQuit(advProxy->IsRunning());
1341     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 3);
1342 
1343     // Check that the host and two services are again registered
1344     // on DNS-SD platform by advertising proxy.
1345 
1346     dnssdCounts.mHostReg++;
1347     dnssdCounts.mServiceReg += 2;
1348     dnssdCounts.mKeyReg += 3;
1349     VerifyDnnsdRequests(dnssdCounts);
1350 
1351     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1352     Log("Update DNS-SD state to `STOPPED` and signal its change");
1353 
1354     sDnssdState = OT_PLAT_DNSSD_STOPPED;
1355     otPlatDnssdStateHandleStateChange(sInstance);
1356 
1357     AdvanceTime(5);
1358 
1359     VerifyOrQuit(!advProxy->IsRunning());
1360     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 4);
1361 
1362     // Since DNS-SD platform signal that it is stopped,
1363     // there should be no calls to any of APIs.
1364 
1365     VerifyDnnsdRequests(dnssdCounts);
1366 
1367     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1368     Log("Remove the first service on client");
1369 
1370     SuccessOrQuit(srpClient->RemoveService(service1));
1371 
1372     sProcessedClientCallback = false;
1373 
1374     AdvanceTime(2 * 1000);
1375 
1376     VerifyOrQuit(sProcessedClientCallback);
1377     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1378     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
1379     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1380 
1381     // No changes to DNS-SD API counters (since it is stopped)
1382 
1383     VerifyDnnsdRequests(dnssdCounts);
1384 
1385     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1386     Log("Update DNS-SD state to `READY` and signal its change #2");
1387 
1388     // Since the already removed `service1` is no longer available
1389     // on SRP client, we disable checking the services with client
1390     // from `otPlatDnssd` APIs.
1391     sDnssdShouldCheckWithClient = false;
1392 
1393     sDnssdState = OT_PLAT_DNSSD_READY;
1394     otPlatDnssdStateHandleStateChange(sInstance);
1395 
1396     AdvanceTime(5);
1397 
1398     VerifyOrQuit(advProxy->IsRunning());
1399     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 5);
1400 
1401     // We should see the host and `service2` registered again.
1402     // And all 3 keys (even for removed `service1`) to be
1403     // registered.
1404 
1405     dnssdCounts.mHostReg++;
1406     dnssdCounts.mServiceReg++;
1407     dnssdCounts.mKeyReg += 3;
1408     VerifyDnnsdRequests(dnssdCounts);
1409 
1410     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1411     Log("Disable SRP server");
1412 
1413     // Verify that all heap allocations by SRP server
1414     // and Advertising Proxy are freed.
1415 
1416     srpServer->SetEnabled(false);
1417     AdvanceTime(100);
1418 
1419     VerifyOrQuit(!advProxy->IsRunning());
1420     VerifyOrQuit(advProxy->GetCounters().mStateChanges == 6);
1421     VerifyOrQuit(advProxy->GetCounters().mAdvSkipped > 0);
1422     VerifyOrQuit(advProxy->GetCounters().mAdvTotal ==
1423                  (advProxy->GetCounters().mAdvSuccessful + advProxy->GetCounters().mAdvSkipped));
1424     VerifyOrQuit(advProxy->GetCounters().mAdvTimeout == 0);
1425     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 0);
1426     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1427 
1428     dnssdCounts.mHostUnreg++;
1429     dnssdCounts.mServiceUnreg++;
1430     dnssdCounts.mKeyUnreg += 3;
1431     VerifyDnnsdRequests(dnssdCounts);
1432 
1433     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1434 
1435     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1436     Log("Finalize OT instance and validate all heap allocations are freed");
1437 
1438     FinalizeTest();
1439 
1440     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
1441 
1442     Log("End of TestSrpAdvProxyDnssdStateChange");
1443 }
1444 
TestSrpAdvProxyDelayedCallback(void)1445 void TestSrpAdvProxyDelayedCallback(void)
1446 {
1447     NetworkData::OnMeshPrefixConfig prefixConfig;
1448     Srp::Server                    *srpServer;
1449     Srp::Client                    *srpClient;
1450     Srp::AdvertisingProxy          *advProxy;
1451     Srp::Client::Service            service1;
1452     Srp::Client::Service            service2;
1453     DnssdRequestCounts              dnssdCounts;
1454     uint16_t                        heapAllocations;
1455     const DnssdRequest             *request;
1456 
1457     Log("--------------------------------------------------------------------------------------------");
1458     Log("TestSrpAdvProxyDelayedCallback");
1459 
1460     InitTest();
1461 
1462     srpServer = &sInstance->Get<Srp::Server>();
1463     srpClient = &sInstance->Get<Srp::Client>();
1464     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
1465 
1466     heapAllocations = sHeapAllocatedPtrs.GetLength();
1467 
1468     PrepareService1(service1);
1469     PrepareService2(service2);
1470 
1471     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1472     Log("Add an on-mesh prefix (with SLAAC) to network data");
1473 
1474     prefixConfig.Clear();
1475     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
1476     prefixConfig.mPrefix.mLength = 64;
1477     prefixConfig.mStable         = true;
1478     prefixConfig.mSlaac          = true;
1479     prefixConfig.mPreferred      = true;
1480     prefixConfig.mOnMesh         = true;
1481     prefixConfig.mDefaultRoute   = false;
1482     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
1483 
1484     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1485     SuccessOrQuit(otBorderRouterRegister(sInstance));
1486 
1487     // Configure Dnssd platform API behavior
1488 
1489     sDnssdRegHostRequests.Clear();
1490     sDnssdRegServiceRequests.Clear();
1491     sDnssdUnregHostRequests.Clear();
1492     sDnssdUnregServiceRequests.Clear();
1493     sDnssdRegKeyRequests.Clear();
1494     sDnssdUnregKeyRequests.Clear();
1495 
1496     sDnssdState                 = OT_PLAT_DNSSD_READY;
1497     sDnssdShouldCheckWithClient = true;
1498     sDnssdCallbackError         = kErrorPending; // Do not call the callbacks directly
1499 
1500     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1501     Log("Start SRP server");
1502 
1503     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
1504 
1505     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
1506     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
1507 
1508     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
1509 
1510     srpServer->SetServiceHandler(nullptr, sInstance);
1511 
1512     srpServer->SetEnabled(true);
1513     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
1514 
1515     AdvanceTime(10000);
1516     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
1517     VerifyOrQuit(advProxy->IsRunning());
1518 
1519     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1520     Log("Start SRP client");
1521 
1522     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
1523     srpClient->SetLeaseInterval(180);
1524 
1525     srpClient->EnableAutoStartMode(nullptr, nullptr);
1526     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
1527 
1528     AdvanceTime(2000);
1529     VerifyOrQuit(srpClient->IsRunning());
1530 
1531     SuccessOrQuit(srpClient->SetHostName(kHostName));
1532     SuccessOrQuit(srpClient->EnableAutoHostAddress());
1533 
1534     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1535     Log("Register a service, invoke the registration callback after some delay");
1536 
1537     SuccessOrQuit(srpClient->AddService(service1));
1538 
1539     sProcessedClientCallback = false;
1540 
1541     AdvanceTime(1000);
1542 
1543     dnssdCounts.mHostReg++;
1544     dnssdCounts.mServiceReg++;
1545     dnssdCounts.mKeyReg += 2;
1546     VerifyDnnsdRequests(dnssdCounts);
1547 
1548     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
1549 
1550     VerifyOrQuit(!sProcessedClientCallback);
1551     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
1552 
1553     // Invoke the service and key callbacks first
1554     request = &sDnssdRegServiceRequests[0];
1555     VerifyOrQuit(request->mCallback != nullptr);
1556     request->mCallback(sInstance, request->mId, kErrorNone);
1557 
1558     request = &sDnssdRegKeyRequests[0];
1559     VerifyOrQuit(request->mCallback != nullptr);
1560     request->mCallback(sInstance, request->mId, kErrorNone);
1561 
1562     request = &sDnssdRegKeyRequests[1];
1563     VerifyOrQuit(request->mCallback != nullptr);
1564     request->mCallback(sInstance, request->mId, kErrorNone);
1565 
1566     AdvanceTime(10);
1567     VerifyOrQuit(!sProcessedClientCallback);
1568     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
1569 
1570     // Invoke the host registration callback next
1571     request = &sDnssdRegHostRequests[0];
1572     VerifyOrQuit(request->mCallback != nullptr);
1573     request->mCallback(sInstance, request->mId, kErrorNone);
1574 
1575     AdvanceTime(10);
1576     VerifyOrQuit(srpServer->GetNextHost(nullptr) != nullptr);
1577 
1578     AdvanceTime(100);
1579     VerifyOrQuit(sProcessedClientCallback);
1580     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1581     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1582 
1583     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
1584     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
1585 
1586     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1587     Log("Register a second service, invoke registration callback with `kErrorDuplicated`");
1588 
1589     SuccessOrQuit(srpClient->AddService(service2));
1590 
1591     sProcessedClientCallback = false;
1592 
1593     AdvanceTime(1000);
1594 
1595     VerifyOrQuit(!sProcessedClientCallback);
1596 
1597     dnssdCounts.mServiceReg++;
1598     dnssdCounts.mKeyReg++;
1599     VerifyDnnsdRequests(dnssdCounts);
1600 
1601     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
1602     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
1603 
1604     // Invoke the service callback with kErrorDuplicated
1605 
1606     request = &sDnssdRegServiceRequests[1];
1607     VerifyOrQuit(request->mCallback != nullptr);
1608     request->mCallback(sInstance, request->mId, kErrorDuplicated);
1609 
1610     AdvanceTime(100);
1611 
1612     VerifyOrQuit(sProcessedClientCallback);
1613     VerifyOrQuit(sLastClientCallbackError == kErrorDuplicated);
1614 
1615     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
1616     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
1617     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 1);
1618 
1619     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1620     Log("Try registering service again from client, invoke callback with success");
1621 
1622     SuccessOrQuit(srpClient->ClearService(service2));
1623     PrepareService2(service2);
1624     SuccessOrQuit(srpClient->AddService(service2));
1625 
1626     sProcessedClientCallback = false;
1627 
1628     AdvanceTime(1000);
1629 
1630     VerifyOrQuit(!sProcessedClientCallback);
1631 
1632     // We should see a new service registration request.
1633 
1634     dnssdCounts.mServiceReg++;
1635     dnssdCounts.mKeyReg++;
1636     VerifyDnnsdRequests(dnssdCounts);
1637 
1638     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
1639     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
1640     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 1);
1641 
1642     // Invoked the service and key callback with success.
1643 
1644     request = &sDnssdRegKeyRequests[sDnssdRegKeyRequests.GetLength() - 1];
1645     VerifyOrQuit(request->mCallback != nullptr);
1646     request->mCallback(sInstance, request->mId, kErrorNone);
1647 
1648     request = &sDnssdRegServiceRequests[sDnssdRegServiceRequests.GetLength() - 1];
1649     VerifyOrQuit(request->mCallback != nullptr);
1650     request->mCallback(sInstance, request->mId, kErrorNone);
1651 
1652     AdvanceTime(100);
1653 
1654     VerifyOrQuit(sProcessedClientCallback);
1655     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1656     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
1657     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
1658 
1659     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
1660     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
1661     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 1);
1662 
1663     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1664     Log("Change the service and register again, but ignore the registration callback");
1665 
1666     SuccessOrQuit(srpClient->ClearService(service2));
1667     PrepareService2(service2);
1668     service2.mSubTypeLabels = nullptr;
1669     SuccessOrQuit(srpClient->AddService(service2));
1670 
1671     sProcessedClientCallback = false;
1672 
1673     AdvanceTime(1000);
1674 
1675     VerifyOrQuit(!sProcessedClientCallback);
1676 
1677     // We should see a new service registration request.
1678 
1679     dnssdCounts.mServiceReg++;
1680     VerifyDnnsdRequests(dnssdCounts);
1681 
1682     // Wait for advertising proxy timeout (there will be no callback from
1683     // platform) so validate that registration failure is reported to
1684     // the SRP client.
1685 
1686     AdvanceTime(2 * 1000);
1687 
1688     VerifyOrQuit(sProcessedClientCallback);
1689     VerifyOrQuit(sLastClientCallbackError != kErrorNone);
1690 
1691     VerifyOrQuit(advProxy->GetCounters().mAdvTimeout == 1);
1692 
1693     // Wait for longer than client retry time.
1694 
1695     AdvanceTime(3 * 1000);
1696 
1697     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1698     Log("Disable SRP server");
1699 
1700     // Verify that all heap allocations by SRP server
1701     // and Advertising Proxy are freed.
1702 
1703     srpServer->SetEnabled(false);
1704     AdvanceTime(100);
1705 
1706     // Make sure the host and two services are unregistered
1707     // (even though the second service was not successfully
1708     // registered yet).
1709 
1710     VerifyOrQuit(sDnssdRegHostRequests.GetLength() == 1);
1711     VerifyOrQuit(sDnssdRegServiceRequests.GetLength() >= 4);
1712     VerifyOrQuit(sDnssdRegKeyRequests.GetLength() >= 3);
1713     VerifyOrQuit(sDnssdUnregHostRequests.GetLength() == 1);
1714     VerifyOrQuit(sDnssdUnregServiceRequests.GetLength() == 2);
1715     VerifyOrQuit(sDnssdUnregKeyRequests.GetLength() == 3);
1716 
1717     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
1718 
1719     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1720     Log("Finalize OT instance and validate all heap allocations are freed");
1721 
1722     FinalizeTest();
1723 
1724     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
1725 
1726     Log("End of TestSrpAdvProxyDelayedCallback");
1727 }
1728 
TestSrpAdvProxyReplacedEntries(void)1729 void TestSrpAdvProxyReplacedEntries(void)
1730 {
1731     NetworkData::OnMeshPrefixConfig prefixConfig;
1732     Srp::Server                    *srpServer;
1733     Srp::Client                    *srpClient;
1734     Srp::AdvertisingProxy          *advProxy;
1735     Srp::Client::Service            service1;
1736     Srp::Client::Service            service2;
1737     DnssdRequestCounts              dnssdCounts;
1738     uint16_t                        heapAllocations;
1739     const DnssdRequest             *request;
1740     uint16_t                        numServices;
1741 
1742     Log("--------------------------------------------------------------------------------------------");
1743     Log("TestSrpAdvProxyReplacedEntries");
1744 
1745     InitTest();
1746 
1747     srpServer = &sInstance->Get<Srp::Server>();
1748     srpClient = &sInstance->Get<Srp::Client>();
1749     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
1750 
1751     heapAllocations = sHeapAllocatedPtrs.GetLength();
1752 
1753     PrepareService1(service1);
1754     PrepareService2(service2);
1755 
1756     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1757     Log("Add an on-mesh prefix (with SLAAC) to network data");
1758 
1759     prefixConfig.Clear();
1760     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
1761     prefixConfig.mPrefix.mLength = 64;
1762     prefixConfig.mStable         = true;
1763     prefixConfig.mSlaac          = true;
1764     prefixConfig.mPreferred      = true;
1765     prefixConfig.mOnMesh         = true;
1766     prefixConfig.mDefaultRoute   = false;
1767     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
1768 
1769     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
1770     SuccessOrQuit(otBorderRouterRegister(sInstance));
1771 
1772     // Configure Dnssd platform API behavior
1773 
1774     sDnssdRegHostRequests.Clear();
1775     sDnssdRegServiceRequests.Clear();
1776     sDnssdUnregHostRequests.Clear();
1777     sDnssdUnregServiceRequests.Clear();
1778     sDnssdRegKeyRequests.Clear();
1779     sDnssdUnregKeyRequests.Clear();
1780 
1781     sDnssdState                 = OT_PLAT_DNSSD_READY;
1782     sDnssdShouldCheckWithClient = true;
1783     sDnssdCallbackError         = kErrorPending; // Do not call the callbacks directly
1784 
1785     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1786     Log("Start SRP server");
1787 
1788     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
1789 
1790     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
1791     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
1792 
1793     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
1794 
1795     srpServer->SetServiceHandler(nullptr, sInstance);
1796 
1797     srpServer->SetEnabled(true);
1798     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
1799 
1800     AdvanceTime(10000);
1801     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
1802     VerifyOrQuit(advProxy->IsRunning());
1803 
1804     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1805     Log("Set AdvTimeout to 5 minutes on AdvProxy");
1806 
1807     // Change the timeout on AvdertisingProxy to 5 minutes
1808     // so that we can send multiple SRP updates and create
1809     // situations where previous advertisement are replaced.
1810 
1811     advProxy->SetAdvTimeout(5 * 60 * 1000);
1812     VerifyOrQuit(advProxy->GetAdvTimeout() == 5 * 60 * 1000);
1813 
1814     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1815     Log("Start SRP client");
1816 
1817     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
1818 
1819     srpClient->EnableAutoStartMode(nullptr, nullptr);
1820     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
1821 
1822     AdvanceTime(2000);
1823     VerifyOrQuit(srpClient->IsRunning());
1824 
1825     SuccessOrQuit(srpClient->SetHostName(kHostName));
1826     SuccessOrQuit(srpClient->EnableAutoHostAddress());
1827 
1828     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1829     Log("Register a service and do not invoke the registration request callbacks");
1830 
1831     SuccessOrQuit(srpClient->AddService(service1));
1832 
1833     sProcessedClientCallback = false;
1834 
1835     AdvanceTime(1200);
1836 
1837     dnssdCounts.mHostReg++;
1838     dnssdCounts.mServiceReg++;
1839     dnssdCounts.mKeyReg += 2;
1840     VerifyDnnsdRequests(dnssdCounts);
1841 
1842     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
1843     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1844 
1845     VerifyOrQuit(!sProcessedClientCallback);
1846     VerifyOrQuit(srpServer->GetNextHost(nullptr) == nullptr);
1847 
1848     // SRP client min retry is 1800 msec, we wait for longer
1849     // to make sure client retries.
1850 
1851     AdvanceTime(2000);
1852 
1853     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
1854     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1855 
1856     // We should see no new service or host registrations on
1857     // DNS-SD platform APIs as the requests should be same
1858     // and fully matching the outstanding ones.
1859 
1860     VerifyDnnsdRequests(dnssdCounts);
1861 
1862     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1863     Log("Invoke the DNS-SD API callbacks");
1864 
1865     request = &sDnssdRegServiceRequests[0];
1866     VerifyOrQuit(request->mCallback != nullptr);
1867     request->mCallback(sInstance, request->mId, kErrorNone);
1868 
1869     request = &sDnssdRegHostRequests[0];
1870     VerifyOrQuit(request->mCallback != nullptr);
1871     request->mCallback(sInstance, request->mId, kErrorNone);
1872 
1873     for (uint16_t index = 0; index < 2; index++)
1874     {
1875         request = &sDnssdRegKeyRequests[index];
1876         VerifyOrQuit(request->mCallback != nullptr);
1877         request->mCallback(sInstance, request->mId, kErrorNone);
1878     }
1879 
1880     AdvanceTime(100);
1881 
1882     VerifyOrQuit(sProcessedClientCallback);
1883     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1884     VerifyOrQuit(srpServer->GetNextHost(nullptr) != nullptr);
1885 
1886     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
1887     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
1888     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1889 
1890     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1891     Log("Check outstanding Adv being replaced");
1892 
1893     // Change service 1
1894     SuccessOrQuit(srpClient->ClearService(service1));
1895     PrepareService1(service1);
1896     service1.mSubTypeLabels = nullptr; // No sub-types
1897     SuccessOrQuit(srpClient->AddService(service1));
1898 
1899     sProcessedClientCallback = false;
1900 
1901     AdvanceTime(1200);
1902 
1903     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
1904     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
1905     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
1906 
1907     // We should see the changed service registered on DNS-SD
1908     // platform APIs.
1909 
1910     dnssdCounts.mServiceReg++;
1911     VerifyDnnsdRequests(dnssdCounts);
1912 
1913     // Change service 1 again (add sub-types back).
1914     SuccessOrQuit(srpClient->ClearService(service1));
1915     PrepareService1(service1);
1916     SuccessOrQuit(srpClient->AddService(service1));
1917 
1918     AdvanceTime(1200);
1919 
1920     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 4);
1921     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
1922     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
1923 
1924     // We should see the changed service registered on DNS-SD
1925     // platform APIs again.
1926 
1927     dnssdCounts.mServiceReg++;
1928     VerifyDnnsdRequests(dnssdCounts);
1929 
1930     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1931     Log("Invoke the replaced entry DNS-SD API callback");
1932 
1933     request = &sDnssdRegServiceRequests[1];
1934     VerifyOrQuit(request->mCallback != nullptr);
1935     request->mCallback(sInstance, request->mId, kErrorNone);
1936 
1937     AdvanceTime(100);
1938 
1939     // Since adv is replaced invoking the old registration callback
1940     // should not complete it.
1941 
1942     VerifyOrQuit(!sProcessedClientCallback);
1943     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 4);
1944     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
1945     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
1946 
1947     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1948     Log("Invoke the new entry DNS-SD API callback");
1949 
1950     request = &sDnssdRegServiceRequests[2];
1951     VerifyOrQuit(request->mCallback != nullptr);
1952     request->mCallback(sInstance, request->mId, kErrorNone);
1953 
1954     AdvanceTime(100);
1955 
1956     VerifyOrQuit(sProcessedClientCallback);
1957     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
1958 
1959     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 4);
1960     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 4);
1961     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
1962 
1963     // Make sure the service entry on the SRP server is the
1964     // last (most recent) request with three sub-types
1965 
1966     VerifyOrQuit(srpServer->GetNextHost(nullptr)->GetServices().GetHead() != nullptr);
1967     VerifyOrQuit(srpServer->GetNextHost(nullptr)->GetServices().GetHead()->GetNumberOfSubTypes() == 3);
1968 
1969     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
1970     Log("Check replacing Adv being blocked till old Adv is completed");
1971 
1972     // Change service 1 and add service 2
1973     SuccessOrQuit(srpClient->ClearService(service1));
1974     PrepareService1(service1);
1975     service1.mSubTypeLabels = nullptr; // No sub-types
1976     SuccessOrQuit(srpClient->AddService(service1));
1977     SuccessOrQuit(srpClient->AddService(service2));
1978 
1979     sProcessedClientCallback = false;
1980 
1981     AdvanceTime(1200);
1982 
1983     // We should see a new Adv with two new service registrations
1984     // on DNS-SD APIs.
1985 
1986     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 5);
1987     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 4);
1988     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
1989 
1990     dnssdCounts.mServiceReg += 2;
1991     dnssdCounts.mKeyReg++;
1992     VerifyDnnsdRequests(dnssdCounts);
1993 
1994     // Invoke the key registration callback
1995 
1996     request = &sDnssdRegKeyRequests[sDnssdRegKeyRequests.GetLength() - 1];
1997     VerifyOrQuit(request->mCallback != nullptr);
1998     request->mCallback(sInstance, request->mId, kErrorNone);
1999 
2000     // Now have SRP client send a new SRP update message
2001     // just changing `service2`. We clear `servcie1` on client
2002     // so it is not included in new SRP update message.
2003 
2004     SuccessOrQuit(srpClient->ClearService(service1));
2005     SuccessOrQuit(srpClient->ClearService(service2));
2006     PrepareService2(service2);
2007     service2.mPort = 2222; // Use a different port number
2008     SuccessOrQuit(srpClient->AddService(service2));
2009 
2010     AdvanceTime(1200);
2011 
2012     // We should see the new Adv (total increasing) and
2013     // also replacing the outstanding one
2014 
2015     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 6);
2016     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 4);
2017     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 2);
2018 
2019     // We should see new registration for the changed `service2`
2020 
2021     dnssdCounts.mServiceReg++;
2022     VerifyDnnsdRequests(dnssdCounts);
2023 
2024     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2025     Log("Invoke the callback for new registration replacing old one first");
2026 
2027     request = &sDnssdRegServiceRequests[5];
2028     VerifyOrQuit(request->mCallback != nullptr);
2029     request->mCallback(sInstance, request->mId, kErrorNone);
2030 
2031     AdvanceTime(100);
2032 
2033     // This should not change anything, since the new Avd should
2034     // be still blocked by the earlier Adv that it replaced.
2035 
2036     VerifyOrQuit(!sProcessedClientCallback);
2037 
2038     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 6);
2039     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 4);
2040     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 2);
2041 
2042     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2043     Log("Invoke the callback for replaced Adv services");
2044 
2045     request = &sDnssdRegServiceRequests[4];
2046     VerifyOrQuit(request->mCallback != nullptr);
2047     request->mCallback(sInstance, request->mId, kErrorNone);
2048 
2049     request = &sDnssdRegServiceRequests[3];
2050     VerifyOrQuit(request->mCallback != nullptr);
2051     request->mCallback(sInstance, request->mId, kErrorNone);
2052 
2053     AdvanceTime(100);
2054 
2055     // This should trigger both Adv to complete.
2056 
2057     VerifyOrQuit(sProcessedClientCallback);
2058     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2059 
2060     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 6);
2061     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 6);
2062     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 2);
2063 
2064     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
2065 
2066     // Make sure the `service2` entry on the SRP server is the
2067     // last (most recent) request with new port number.
2068 
2069     VerifyOrQuit(srpServer->GetNextHost(nullptr)->GetServices().GetHead() != nullptr);
2070 
2071     numServices = 0;
2072 
2073     for (const Srp::Server::Service &service : srpServer->GetNextHost(nullptr)->GetServices())
2074     {
2075         numServices++;
2076 
2077         if (StringMatch(service.GetInstanceLabel(), service2.GetInstanceName(), kStringCaseInsensitiveMatch))
2078         {
2079             VerifyOrQuit(service.GetPort() == service2.GetPort());
2080         }
2081         else if (StringMatch(service.GetInstanceLabel(), service1.GetInstanceName(), kStringCaseInsensitiveMatch))
2082         {
2083             // Service 1 was changed to have no sub-types
2084             VerifyOrQuit(service.GetPort() == service1.GetPort());
2085             VerifyOrQuit(service.GetNumberOfSubTypes() == 0);
2086         }
2087         else
2088         {
2089             VerifyOrQuit(false); // Unexpected extra service on SRP server.
2090         }
2091     }
2092 
2093     VerifyOrQuit(numServices == 2);
2094 
2095     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2096     Log("Check replacing Adv being blocked till old Adv is completed when removing services");
2097 
2098     // Change and re-add both services so they are both
2099     // included in a new SRP update message from client.
2100 
2101     SuccessOrQuit(srpClient->ClearService(service2));
2102     PrepareService1(service1);
2103     PrepareService2(service2);
2104     SuccessOrQuit(srpClient->AddService(service1));
2105     SuccessOrQuit(srpClient->AddService(service2));
2106 
2107     sProcessedClientCallback = false;
2108 
2109     AdvanceTime(1200);
2110 
2111     // We should see a new Adv with two new service registrations
2112     // on DNS-SD APIs.
2113 
2114     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 7);
2115     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 6);
2116     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 2);
2117 
2118     dnssdCounts.mServiceReg += 2;
2119     VerifyDnnsdRequests(dnssdCounts);
2120 
2121     // Now have SRP client send a new SRP update message
2122     // just removing `service1`. We clear `servcie2` on client
2123     // so it is not included in new SRP update message.
2124 
2125     SuccessOrQuit(srpClient->RemoveService(service1));
2126     SuccessOrQuit(srpClient->ClearService(service2));
2127 
2128     AdvanceTime(1200);
2129 
2130     // We should see a new Adv added replacing the outstanding
2131     // one.
2132 
2133     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 8);
2134     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 6);
2135     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 3);
2136 
2137     dnssdCounts.mServiceUnreg++;
2138     VerifyDnnsdRequests(dnssdCounts);
2139 
2140     // Even though the new SRP update which removed `servcie2`
2141     // is already unregistered, it should be blocked by the
2142     // earlier Adv.
2143 
2144     VerifyOrQuit(!sProcessedClientCallback);
2145 
2146     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2147     Log("Invoke the callback for replaced Adv services");
2148 
2149     request = &sDnssdRegServiceRequests[6];
2150     VerifyOrQuit(request->mCallback != nullptr);
2151     request->mCallback(sInstance, request->mId, kErrorNone);
2152 
2153     request = &sDnssdRegServiceRequests[7];
2154     VerifyOrQuit(request->mCallback != nullptr);
2155     request->mCallback(sInstance, request->mId, kErrorNone);
2156 
2157     AdvanceTime(100);
2158 
2159     // This should trigger both Adv to complete, and first one
2160     // should be committed before the second one removing the
2161     // `service2`.
2162 
2163     VerifyOrQuit(sProcessedClientCallback);
2164     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2165 
2166     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 8);
2167     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 8);
2168     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 3);
2169 
2170     VerifyOrQuit(service1.GetState() == Srp::Client::kRemoved);
2171 
2172     // Check services on server and make sure `service2`
2173     // is marked as deleted.
2174 
2175     VerifyOrQuit(srpServer->GetNextHost(nullptr)->GetServices().GetHead() != nullptr);
2176 
2177     numServices = 0;
2178 
2179     for (const Srp::Server::Service &service : srpServer->GetNextHost(nullptr)->GetServices())
2180     {
2181         numServices++;
2182 
2183         if (StringMatch(service.GetInstanceLabel(), service1.GetInstanceName(), kStringCaseInsensitiveMatch))
2184         {
2185             VerifyOrQuit(service.IsDeleted());
2186         }
2187         else if (StringMatch(service.GetInstanceLabel(), service2.GetInstanceName(), kStringCaseInsensitiveMatch))
2188         {
2189             VerifyOrQuit(!service.IsDeleted());
2190         }
2191         else
2192         {
2193             VerifyOrQuit(false); // Unexpected extra service on SRP server.
2194         }
2195     }
2196 
2197     VerifyOrQuit(numServices == 2);
2198 
2199     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2200     Log("Disable SRP server");
2201 
2202     sDnssdShouldCheckWithClient = false;
2203 
2204     // Verify that all heap allocations by SRP server
2205     // and Advertising Proxy are freed.
2206 
2207     srpServer->SetEnabled(false);
2208     AdvanceTime(100);
2209 
2210     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2211 
2212     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2213     Log("Finalize OT instance and validate all heap allocations are freed");
2214 
2215     FinalizeTest();
2216 
2217     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
2218 
2219     Log("End of TestSrpAdvProxyReplacedEntries");
2220 }
2221 
TestSrpAdvProxyHostWithOffMeshRoutableAddress(void)2222 void TestSrpAdvProxyHostWithOffMeshRoutableAddress(void)
2223 {
2224     NetworkData::OnMeshPrefixConfig prefixConfig;
2225     Srp::Server                    *srpServer;
2226     Srp::Client                    *srpClient;
2227     Srp::AdvertisingProxy          *advProxy;
2228     Srp::Client::Service            service1;
2229     Srp::Client::Service            service2;
2230     DnssdRequestCounts              dnssdCounts;
2231     uint16_t                        heapAllocations;
2232     const DnssdRequest             *request;
2233 
2234     Log("--------------------------------------------------------------------------------------------");
2235     Log("TestSrpAdvProxyHostWithOffMeshRoutableAddress");
2236 
2237     InitTest();
2238 
2239     srpServer = &sInstance->Get<Srp::Server>();
2240     srpClient = &sInstance->Get<Srp::Client>();
2241     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
2242 
2243     heapAllocations = sHeapAllocatedPtrs.GetLength();
2244 
2245     PrepareService1(service1);
2246     PrepareService2(service2);
2247 
2248     // Configure Dnssd platform API behavior
2249 
2250     sDnssdRegHostRequests.Clear();
2251     sDnssdRegServiceRequests.Clear();
2252     sDnssdUnregHostRequests.Clear();
2253     sDnssdUnregServiceRequests.Clear();
2254     sDnssdRegKeyRequests.Clear();
2255     sDnssdUnregKeyRequests.Clear();
2256 
2257     sDnssdState                 = OT_PLAT_DNSSD_READY;
2258     sDnssdShouldCheckWithClient = true;
2259     sDnssdCallbackError         = kErrorNone; // Invoke callback directly from dnssd APIs
2260 
2261     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2262     Log("Start SRP server");
2263 
2264     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
2265 
2266     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
2267     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
2268 
2269     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
2270 
2271     srpServer->SetServiceHandler(nullptr, sInstance);
2272 
2273     srpServer->SetEnabled(true);
2274     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
2275 
2276     AdvanceTime(10000);
2277     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
2278     VerifyOrQuit(advProxy->IsRunning());
2279 
2280     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2281     Log("Start SRP client");
2282 
2283     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
2284     srpClient->SetLeaseInterval(400);
2285 
2286     srpClient->EnableAutoStartMode(nullptr, nullptr);
2287     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
2288 
2289     AdvanceTime(2000);
2290     VerifyOrQuit(srpClient->IsRunning());
2291 
2292     SuccessOrQuit(srpClient->SetHostName(kHostName));
2293     SuccessOrQuit(srpClient->EnableAutoHostAddress());
2294 
2295     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2296     Log("Register a service");
2297 
2298     SuccessOrQuit(srpClient->AddService(service1));
2299 
2300     sProcessedClientCallback = false;
2301 
2302     AdvanceTime(2 * 1000);
2303 
2304     dnssdCounts.mHostReg++;
2305     dnssdCounts.mServiceReg++;
2306     dnssdCounts.mKeyReg += 2;
2307 
2308     VerifyDnnsdRequests(dnssdCounts);
2309     VerifyOrQuit(sDnssdNumHostAddresses == 0);
2310 
2311     VerifyOrQuit(sProcessedClientCallback);
2312     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2313 
2314     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
2315 
2316     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
2317     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2318 
2319     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2320     Log("Register a second service");
2321 
2322     SuccessOrQuit(srpClient->AddService(service2));
2323 
2324     sProcessedClientCallback = false;
2325 
2326     AdvanceTime(2 * 1000);
2327 
2328     dnssdCounts.mServiceReg++;
2329     dnssdCounts.mKeyReg++;
2330     VerifyDnnsdRequests(dnssdCounts);
2331 
2332     VerifyOrQuit(sProcessedClientCallback);
2333     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2334 
2335     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
2336     VerifyOrQuit(service2.GetState() == Srp::Client::kRegistered);
2337 
2338     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
2339     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 2);
2340 
2341     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2342     Log("Disable SRP server");
2343 
2344     // Verify that all heap allocations by SRP server
2345     // and Advertising Proxy are freed.
2346 
2347     srpServer->SetEnabled(false);
2348     AdvanceTime(100);
2349     VerifyOrQuit(!advProxy->IsRunning());
2350 
2351     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == advProxy->GetCounters().mAdvTotal);
2352     VerifyOrQuit(advProxy->GetCounters().mAdvTimeout == 0);
2353     VerifyOrQuit(advProxy->GetCounters().mAdvRejected == 0);
2354     VerifyOrQuit(advProxy->GetCounters().mAdvSkipped == 0);
2355     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
2356 
2357     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2358 
2359     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2360     Log("Finalize OT instance and validate all heap allocations are freed");
2361 
2362     FinalizeTest();
2363 
2364     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
2365 
2366     Log("End of TestSrpAdvProxyHostWithOffMeshRoutableAddress");
2367 }
2368 
TestSrpAdvProxyRemoveBeforeCommitted(void)2369 void TestSrpAdvProxyRemoveBeforeCommitted(void)
2370 {
2371     NetworkData::OnMeshPrefixConfig prefixConfig;
2372     Srp::Server                    *srpServer;
2373     Srp::Client                    *srpClient;
2374     Srp::AdvertisingProxy          *advProxy;
2375     Srp::Client::Service            service1;
2376     Srp::Client::Service            service2;
2377     DnssdRequestCounts              dnssdCounts;
2378     uint16_t                        heapAllocations;
2379     const DnssdRequest             *request;
2380 
2381     Log("--------------------------------------------------------------------------------------------");
2382     Log("TestSrpAdvProxyRemoveBeforeCommitted");
2383 
2384     InitTest();
2385 
2386     srpServer = &sInstance->Get<Srp::Server>();
2387     srpClient = &sInstance->Get<Srp::Client>();
2388     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
2389 
2390     heapAllocations = sHeapAllocatedPtrs.GetLength();
2391 
2392     PrepareService1(service1);
2393     PrepareService2(service2);
2394 
2395     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2396     Log("Add an on-mesh prefix (with SLAAC) to network data");
2397 
2398     prefixConfig.Clear();
2399     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
2400     prefixConfig.mPrefix.mLength = 64;
2401     prefixConfig.mStable         = true;
2402     prefixConfig.mSlaac          = true;
2403     prefixConfig.mPreferred      = true;
2404     prefixConfig.mOnMesh         = true;
2405     prefixConfig.mDefaultRoute   = false;
2406     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
2407 
2408     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
2409     SuccessOrQuit(otBorderRouterRegister(sInstance));
2410 
2411     // Configure Dnssd platform API behavior
2412 
2413     sDnssdRegHostRequests.Clear();
2414     sDnssdRegServiceRequests.Clear();
2415     sDnssdUnregHostRequests.Clear();
2416     sDnssdUnregServiceRequests.Clear();
2417     sDnssdRegKeyRequests.Clear();
2418     sDnssdUnregKeyRequests.Clear();
2419 
2420     sDnssdState                 = OT_PLAT_DNSSD_READY;
2421     sDnssdShouldCheckWithClient = true;
2422     sDnssdCallbackError         = kErrorNone; // Do not call the callbacks directly
2423 
2424     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2425     Log("Start SRP server");
2426 
2427     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
2428 
2429     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
2430     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
2431 
2432     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
2433 
2434     srpServer->SetServiceHandler(nullptr, sInstance);
2435 
2436     srpServer->SetEnabled(true);
2437     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
2438 
2439     AdvanceTime(10000);
2440     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
2441     VerifyOrQuit(advProxy->IsRunning());
2442 
2443     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2444     Log("Start SRP client");
2445 
2446     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
2447 
2448     srpClient->EnableAutoStartMode(nullptr, nullptr);
2449     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
2450 
2451     AdvanceTime(2000);
2452     VerifyOrQuit(srpClient->IsRunning());
2453 
2454     SuccessOrQuit(srpClient->SetHostName(kHostName));
2455     SuccessOrQuit(srpClient->EnableAutoHostAddress());
2456 
2457     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2458     Log("Register host and one service");
2459 
2460     SuccessOrQuit(srpClient->AddService(service1));
2461 
2462     sProcessedClientCallback = false;
2463 
2464     AdvanceTime(2000);
2465 
2466     dnssdCounts.mHostReg++;
2467     dnssdCounts.mServiceReg++;
2468     dnssdCounts.mKeyReg += 2;
2469     VerifyDnnsdRequests(dnssdCounts);
2470 
2471     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
2472     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2473     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
2474 
2475     VerifyOrQuit(sProcessedClientCallback);
2476     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2477 
2478     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
2479 
2480     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2481     Log("Set AdvTimeout to 5 minutes on AdvProxy");
2482 
2483     // Change the timeout on AvdertisingProxy to 5 minutes
2484     // so that we can send multiple SRP updates and create
2485     // situations where previous advertisement are replaced.
2486 
2487     advProxy->SetAdvTimeout(5 * 60 * 1000);
2488     VerifyOrQuit(advProxy->GetAdvTimeout() == 5 * 60 * 1000);
2489 
2490     sDnssdCallbackError = kErrorPending; // Do not invoke callback
2491 
2492     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2493     Log("Remove service1 while adding a new service2 and do not invoke callback from DNSSD plat");
2494 
2495     SuccessOrQuit(srpClient->RemoveService(service1));
2496     SuccessOrQuit(srpClient->AddService(service2));
2497 
2498     sProcessedClientCallback = false;
2499 
2500     AdvanceTime(1000);
2501 
2502     dnssdCounts.mServiceReg++;
2503     dnssdCounts.mServiceUnreg++;
2504     dnssdCounts.mKeyReg++;
2505     VerifyDnnsdRequests(dnssdCounts);
2506 
2507     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
2508     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2509     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
2510 
2511     VerifyOrQuit(!sProcessedClientCallback);
2512 
2513     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2514     Log("Remove host and its services without removing key-lease");
2515 
2516     SuccessOrQuit(srpClient->RemoveHostAndServices(/* aShouldRemoveKeyLease */ false));
2517 
2518     AdvanceTime(1000);
2519 
2520     // Proxy will unregister both services again
2521     // (to be safe).
2522 
2523     dnssdCounts.mHostUnreg++;
2524     dnssdCounts.mServiceUnreg++;
2525     VerifyDnnsdRequests(dnssdCounts, /* aAllowMoreUnregs */ true);
2526 
2527     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
2528     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2529     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
2530 
2531     VerifyOrQuit(!sProcessedClientCallback);
2532 
2533     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2534     Log("Invoke callback for last key registration");
2535 
2536     // This should be enough for all `AdvInfo` entries to be finished.
2537 
2538     request = &sDnssdRegKeyRequests[sDnssdRegKeyRequests.GetLength() - 1];
2539     VerifyOrQuit(request->mCallback != nullptr);
2540     request->mCallback(sInstance, request->mId, kErrorNone);
2541 
2542     AdvanceTime(50);
2543 
2544     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
2545     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 3);
2546     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
2547 
2548     VerifyOrQuit(sProcessedClientCallback);
2549 
2550     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2551     Log("Disable SRP server");
2552 
2553     sDnssdShouldCheckWithClient = false;
2554 
2555     // Verify that all heap allocations by SRP server
2556     // and Advertising Proxy are freed.
2557 
2558     srpServer->SetEnabled(false);
2559     AdvanceTime(100);
2560 
2561     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2562 
2563     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2564     Log("Finalize OT instance and validate all heap allocations are freed");
2565 
2566     FinalizeTest();
2567 
2568     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
2569 
2570     Log("End of TestSrpAdvProxyRemoveBeforeCommitted");
2571 }
2572 
TestSrpAdvProxyFullyRemoveBeforeCommitted(void)2573 void TestSrpAdvProxyFullyRemoveBeforeCommitted(void)
2574 {
2575     NetworkData::OnMeshPrefixConfig prefixConfig;
2576     Srp::Server                    *srpServer;
2577     Srp::Client                    *srpClient;
2578     Srp::AdvertisingProxy          *advProxy;
2579     Srp::Client::Service            service1;
2580     Srp::Client::Service            service2;
2581     DnssdRequestCounts              dnssdCounts;
2582     uint16_t                        heapAllocations;
2583     const DnssdRequest             *request;
2584 
2585     Log("--------------------------------------------------------------------------------------------");
2586     Log("TestSrpAdvProxyFullyRemoveBeforeCommitted");
2587 
2588     InitTest();
2589 
2590     srpServer = &sInstance->Get<Srp::Server>();
2591     srpClient = &sInstance->Get<Srp::Client>();
2592     advProxy  = &sInstance->Get<Srp::AdvertisingProxy>();
2593 
2594     heapAllocations = sHeapAllocatedPtrs.GetLength();
2595 
2596     PrepareService1(service1);
2597     PrepareService2(service2);
2598 
2599     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2600     Log("Add an on-mesh prefix (with SLAAC) to network data");
2601 
2602     prefixConfig.Clear();
2603     SuccessOrQuit(AsCoreType(&prefixConfig.mPrefix.mPrefix).FromString("fd00:cafe:beef::"));
2604     prefixConfig.mPrefix.mLength = 64;
2605     prefixConfig.mStable         = true;
2606     prefixConfig.mSlaac          = true;
2607     prefixConfig.mPreferred      = true;
2608     prefixConfig.mOnMesh         = true;
2609     prefixConfig.mDefaultRoute   = false;
2610     prefixConfig.mPreference     = NetworkData::kRoutePreferenceMedium;
2611 
2612     SuccessOrQuit(otBorderRouterAddOnMeshPrefix(sInstance, &prefixConfig));
2613     SuccessOrQuit(otBorderRouterRegister(sInstance));
2614 
2615     // Configure Dnssd platform API behavior
2616 
2617     sDnssdRegHostRequests.Clear();
2618     sDnssdRegServiceRequests.Clear();
2619     sDnssdUnregHostRequests.Clear();
2620     sDnssdUnregServiceRequests.Clear();
2621     sDnssdRegKeyRequests.Clear();
2622     sDnssdUnregKeyRequests.Clear();
2623 
2624     sDnssdState                 = OT_PLAT_DNSSD_READY;
2625     sDnssdShouldCheckWithClient = true;
2626     sDnssdCallbackError         = kErrorNone; // Do not call the callbacks directly
2627 
2628     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2629     Log("Start SRP server");
2630 
2631     SuccessOrQuit(otBorderRoutingInit(sInstance, /* aInfraIfIndex */ kInfraIfIndex, /* aInfraIfIsRunning */ true));
2632 
2633     SuccessOrQuit(srpServer->SetAddressMode(Srp::Server::kAddressModeUnicast));
2634     VerifyOrQuit(srpServer->GetAddressMode() == Srp::Server::kAddressModeUnicast);
2635 
2636     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateDisabled);
2637 
2638     srpServer->SetServiceHandler(nullptr, sInstance);
2639 
2640     srpServer->SetEnabled(true);
2641     VerifyOrQuit(srpServer->GetState() != Srp::Server::kStateDisabled);
2642 
2643     AdvanceTime(10000);
2644     VerifyOrQuit(srpServer->GetState() == Srp::Server::kStateRunning);
2645     VerifyOrQuit(advProxy->IsRunning());
2646 
2647     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2648     Log("Start SRP client");
2649 
2650     srpClient->SetCallback(HandleSrpClientCallback, sInstance);
2651 
2652     srpClient->EnableAutoStartMode(nullptr, nullptr);
2653     VerifyOrQuit(srpClient->IsAutoStartModeEnabled());
2654 
2655     AdvanceTime(2000);
2656     VerifyOrQuit(srpClient->IsRunning());
2657 
2658     SuccessOrQuit(srpClient->SetHostName(kHostName));
2659     SuccessOrQuit(srpClient->EnableAutoHostAddress());
2660 
2661     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2662     Log("Register host and one service");
2663 
2664     SuccessOrQuit(srpClient->AddService(service1));
2665 
2666     sProcessedClientCallback = false;
2667 
2668     AdvanceTime(2000);
2669 
2670     dnssdCounts.mHostReg++;
2671     dnssdCounts.mServiceReg++;
2672     dnssdCounts.mKeyReg += 2;
2673     VerifyDnnsdRequests(dnssdCounts);
2674 
2675     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 1);
2676     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2677     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
2678 
2679     VerifyOrQuit(sProcessedClientCallback);
2680     VerifyOrQuit(sLastClientCallbackError == kErrorNone);
2681 
2682     VerifyOrQuit(service1.GetState() == Srp::Client::kRegistered);
2683 
2684     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2685     Log("Set AdvTimeout to 5 minutes on AdvProxy");
2686 
2687     // Change the timeout on AvdertisingProxy to 5 minutes
2688     // so that we can send multiple SRP updates and create
2689     // situations where previous advertisement are replaced.
2690 
2691     advProxy->SetAdvTimeout(5 * 60 * 1000);
2692     VerifyOrQuit(advProxy->GetAdvTimeout() == 5 * 60 * 1000);
2693 
2694     sDnssdCallbackError = kErrorPending; // Do not invoke callback
2695 
2696     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2697     Log("Remove service1 while adding a new service2 and do not invoke callback from DNSSD plat");
2698 
2699     SuccessOrQuit(srpClient->RemoveService(service1));
2700     SuccessOrQuit(srpClient->AddService(service2));
2701 
2702     sProcessedClientCallback = false;
2703 
2704     AdvanceTime(1000);
2705 
2706     dnssdCounts.mServiceReg++;
2707     dnssdCounts.mServiceUnreg++;
2708     dnssdCounts.mKeyReg++;
2709     VerifyDnnsdRequests(dnssdCounts);
2710 
2711     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 2);
2712     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 1);
2713     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 0);
2714 
2715     VerifyOrQuit(!sProcessedClientCallback);
2716 
2717     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2718     Log("Remove host and its services and remove key-lease");
2719 
2720     SuccessOrQuit(srpClient->RemoveHostAndServices(/* aShouldRemoveKeyLease */ true));
2721 
2722     AdvanceTime(1000);
2723 
2724     // Proxy should unregister everything.
2725     //  Keys may be unregistered multiple times.
2726 
2727     dnssdCounts.mHostUnreg++;
2728     dnssdCounts.mServiceUnreg++;
2729     dnssdCounts.mKeyUnreg += 3;
2730     VerifyDnnsdRequests(dnssdCounts, /* aAllowMoreUnregs */ true);
2731 
2732     VerifyOrQuit(advProxy->GetCounters().mAdvTotal == 3);
2733     VerifyOrQuit(advProxy->GetCounters().mAdvSuccessful == 3);
2734     VerifyOrQuit(advProxy->GetCounters().mAdvReplaced == 1);
2735 
2736     VerifyOrQuit(sProcessedClientCallback);
2737 
2738     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2739     Log("Disable SRP server");
2740 
2741     sDnssdShouldCheckWithClient = false;
2742 
2743     // Verify that all heap allocations by SRP server
2744     // and Advertising Proxy are freed.
2745 
2746     srpServer->SetEnabled(false);
2747     AdvanceTime(100);
2748 
2749     VerifyOrQuit(heapAllocations == sHeapAllocatedPtrs.GetLength());
2750 
2751     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
2752     Log("Finalize OT instance and validate all heap allocations are freed");
2753 
2754     FinalizeTest();
2755 
2756     VerifyOrQuit(sHeapAllocatedPtrs.IsEmpty());
2757 
2758     Log("End of TestSrpAdvProxyFullyRemoveBeforeCommitted");
2759 }
2760 
2761 #endif // ENABLE_ADV_PROXY_TEST
2762 
main(void)2763 int main(void)
2764 {
2765 #if ENABLE_ADV_PROXY_TEST
2766     TestDnssdRequestIdRange();
2767     TestSrpAdvProxy();
2768     TestSrpAdvProxyDnssdStateChange();
2769     TestSrpAdvProxyDelayedCallback();
2770     TestSrpAdvProxyReplacedEntries();
2771     TestSrpAdvProxyHostWithOffMeshRoutableAddress();
2772     TestSrpAdvProxyRemoveBeforeCommitted();
2773     TestSrpAdvProxyFullyRemoveBeforeCommitted();
2774 
2775     printf("All tests passed\n");
2776 #else
2777     printf("SRP_ADV_PROXY feature is not enabled\n");
2778 #endif
2779 
2780     return 0;
2781 }
2782