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