xref: /aosp_15_r20/external/openthread/tests/unit/test_mdns.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2024, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include <openthread/config.h>
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
32*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include "common/arg_macros.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
36*cfb92d14SAndroid Build Coastguard Worker #include "common/as_core_type.hpp"
37*cfb92d14SAndroid Build Coastguard Worker #include "common/num_utils.hpp"
38*cfb92d14SAndroid Build Coastguard Worker #include "common/owning_list.hpp"
39*cfb92d14SAndroid Build Coastguard Worker #include "common/string.hpp"
40*cfb92d14SAndroid Build Coastguard Worker #include "common/time.hpp"
41*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
42*cfb92d14SAndroid Build Coastguard Worker #include "net/dns_dso.hpp"
43*cfb92d14SAndroid Build Coastguard Worker #include "net/mdns.hpp"
44*cfb92d14SAndroid Build Coastguard Worker 
45*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
46*cfb92d14SAndroid Build Coastguard Worker 
47*cfb92d14SAndroid Build Coastguard Worker namespace ot {
48*cfb92d14SAndroid Build Coastguard Worker namespace Dns {
49*cfb92d14SAndroid Build Coastguard Worker namespace Multicast {
50*cfb92d14SAndroid Build Coastguard Worker 
51*cfb92d14SAndroid Build Coastguard Worker #define ENABLE_TEST_LOG 1 // Enable to get logs from unit test.
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker // Logs a message and adds current time (sNow) as "<hours>:<min>:<secs>.<msec>"
54*cfb92d14SAndroid Build Coastguard Worker #if ENABLE_TEST_LOG
55*cfb92d14SAndroid Build Coastguard Worker #define Log(...)                                                                                         \
56*cfb92d14SAndroid Build Coastguard Worker     printf("%02u:%02u:%02u.%03u " OT_FIRST_ARG(__VA_ARGS__) "\n", (sNow / 3600000), (sNow / 60000) % 60, \
57*cfb92d14SAndroid Build Coastguard Worker            (sNow / 1000) % 60, sNow % 1000 OT_REST_ARGS(__VA_ARGS__))
58*cfb92d14SAndroid Build Coastguard Worker #else
59*cfb92d14SAndroid Build Coastguard Worker #define Log(...)
60*cfb92d14SAndroid Build Coastguard Worker #endif
61*cfb92d14SAndroid Build Coastguard Worker 
62*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
63*cfb92d14SAndroid Build Coastguard Worker // Constants
64*cfb92d14SAndroid Build Coastguard Worker 
65*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kClassQueryUnicastFlag  = (1U << 15);
66*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kClassCacheFlushFlag    = (1U << 15);
67*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kClassMask              = 0x7fff;
68*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kStringSize             = 300;
69*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxDataSize            = 400;
70*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kNumAnnounces           = 3;
71*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kNumInitalQueries       = 3;
72*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kNumRefreshQueries      = 4;
73*cfb92d14SAndroid Build Coastguard Worker static constexpr bool     kCacheFlush             = true;
74*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMdnsPort               = 5353;
75*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kEphemeralPort          = 49152;
76*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kLegacyUnicastMessageId = 1;
77*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxLegacyUnicastTtl    = 10;
78*cfb92d14SAndroid Build Coastguard Worker static constexpr uint32_t kInfraIfIndex           = 1;
79*cfb92d14SAndroid Build Coastguard Worker 
80*cfb92d14SAndroid Build Coastguard Worker static const char kDeviceIp6Address[] = "fd01::1";
81*cfb92d14SAndroid Build Coastguard Worker 
82*cfb92d14SAndroid Build Coastguard Worker class DnsMessage;
83*cfb92d14SAndroid Build Coastguard Worker 
84*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
85*cfb92d14SAndroid Build Coastguard Worker // Variables
86*cfb92d14SAndroid Build Coastguard Worker 
87*cfb92d14SAndroid Build Coastguard Worker static Instance *sInstance;
88*cfb92d14SAndroid Build Coastguard Worker 
89*cfb92d14SAndroid Build Coastguard Worker static uint32_t sNow = 0;
90*cfb92d14SAndroid Build Coastguard Worker static uint32_t sAlarmTime;
91*cfb92d14SAndroid Build Coastguard Worker static bool     sAlarmOn = false;
92*cfb92d14SAndroid Build Coastguard Worker 
93*cfb92d14SAndroid Build Coastguard Worker OwningList<DnsMessage> sDnsMessages;
94*cfb92d14SAndroid Build Coastguard Worker uint32_t               sInfraIfIndex;
95*cfb92d14SAndroid Build Coastguard Worker 
96*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
97*cfb92d14SAndroid Build Coastguard Worker // Prototypes
98*cfb92d14SAndroid Build Coastguard Worker 
99*cfb92d14SAndroid Build Coastguard Worker static const char *RecordTypeToString(uint16_t aType);
100*cfb92d14SAndroid Build Coastguard Worker 
101*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
102*cfb92d14SAndroid Build Coastguard Worker // Types
103*cfb92d14SAndroid Build Coastguard Worker 
104*cfb92d14SAndroid Build Coastguard Worker template <typename Type> class Allocatable
105*cfb92d14SAndroid Build Coastguard Worker {
106*cfb92d14SAndroid Build Coastguard Worker public:
Allocate(void)107*cfb92d14SAndroid Build Coastguard Worker     static Type *Allocate(void)
108*cfb92d14SAndroid Build Coastguard Worker     {
109*cfb92d14SAndroid Build Coastguard Worker         void *buf = calloc(1, sizeof(Type));
110*cfb92d14SAndroid Build Coastguard Worker 
111*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(buf != nullptr);
112*cfb92d14SAndroid Build Coastguard Worker         return new (buf) Type();
113*cfb92d14SAndroid Build Coastguard Worker     }
114*cfb92d14SAndroid Build Coastguard Worker 
Free(void)115*cfb92d14SAndroid Build Coastguard Worker     void Free(void)
116*cfb92d14SAndroid Build Coastguard Worker     {
117*cfb92d14SAndroid Build Coastguard Worker         static_cast<Type *>(this)->~Type();
118*cfb92d14SAndroid Build Coastguard Worker         free(this);
119*cfb92d14SAndroid Build Coastguard Worker     }
120*cfb92d14SAndroid Build Coastguard Worker };
121*cfb92d14SAndroid Build Coastguard Worker 
122*cfb92d14SAndroid Build Coastguard Worker struct DnsName
123*cfb92d14SAndroid Build Coastguard Worker {
124*cfb92d14SAndroid Build Coastguard Worker     Name::Buffer mName;
125*cfb92d14SAndroid Build Coastguard Worker 
ParseFromot::Dns::Multicast::DnsName126*cfb92d14SAndroid Build Coastguard Worker     void ParseFrom(const Message &aMessage, uint16_t &aOffset)
127*cfb92d14SAndroid Build Coastguard Worker     {
128*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Name::ReadName(aMessage, aOffset, mName));
129*cfb92d14SAndroid Build Coastguard Worker     }
130*cfb92d14SAndroid Build Coastguard Worker 
CopyFromot::Dns::Multicast::DnsName131*cfb92d14SAndroid Build Coastguard Worker     void CopyFrom(const char *aName)
132*cfb92d14SAndroid Build Coastguard Worker     {
133*cfb92d14SAndroid Build Coastguard Worker         if (aName == nullptr)
134*cfb92d14SAndroid Build Coastguard Worker         {
135*cfb92d14SAndroid Build Coastguard Worker             mName[0] = '\0';
136*cfb92d14SAndroid Build Coastguard Worker         }
137*cfb92d14SAndroid Build Coastguard Worker         else
138*cfb92d14SAndroid Build Coastguard Worker         {
139*cfb92d14SAndroid Build Coastguard Worker             uint16_t len = StringLength(aName, sizeof(mName));
140*cfb92d14SAndroid Build Coastguard Worker 
141*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(len < sizeof(mName));
142*cfb92d14SAndroid Build Coastguard Worker             memcpy(mName, aName, len + 1);
143*cfb92d14SAndroid Build Coastguard Worker         }
144*cfb92d14SAndroid Build Coastguard Worker     }
145*cfb92d14SAndroid Build Coastguard Worker 
AsCStringot::Dns::Multicast::DnsName146*cfb92d14SAndroid Build Coastguard Worker     const char *AsCString(void) const { return mName; }
Matchesot::Dns::Multicast::DnsName147*cfb92d14SAndroid Build Coastguard Worker     bool        Matches(const char *aName) const { return StringMatch(mName, aName, kStringCaseInsensitiveMatch); }
148*cfb92d14SAndroid Build Coastguard Worker };
149*cfb92d14SAndroid Build Coastguard Worker 
150*cfb92d14SAndroid Build Coastguard Worker typedef String<Name::kMaxNameSize> DnsNameString;
151*cfb92d14SAndroid Build Coastguard Worker 
152*cfb92d14SAndroid Build Coastguard Worker struct AddrAndTtl
153*cfb92d14SAndroid Build Coastguard Worker {
operator ==ot::Dns::Multicast::AddrAndTtl154*cfb92d14SAndroid Build Coastguard Worker     bool operator==(const AddrAndTtl &aOther) const { return (mTtl == aOther.mTtl) && (mAddress == aOther.mAddress); }
155*cfb92d14SAndroid Build Coastguard Worker 
156*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address mAddress;
157*cfb92d14SAndroid Build Coastguard Worker     uint32_t     mTtl;
158*cfb92d14SAndroid Build Coastguard Worker };
159*cfb92d14SAndroid Build Coastguard Worker 
160*cfb92d14SAndroid Build Coastguard Worker struct DnsQuestion : public Allocatable<DnsQuestion>, public LinkedListEntry<DnsQuestion>
161*cfb92d14SAndroid Build Coastguard Worker {
162*cfb92d14SAndroid Build Coastguard Worker     DnsQuestion *mNext;
163*cfb92d14SAndroid Build Coastguard Worker     DnsName      mName;
164*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mType;
165*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mClass;
166*cfb92d14SAndroid Build Coastguard Worker     bool         mUnicastResponse;
167*cfb92d14SAndroid Build Coastguard Worker 
ParseFromot::Dns::Multicast::DnsQuestion168*cfb92d14SAndroid Build Coastguard Worker     void ParseFrom(const Message &aMessage, uint16_t &aOffset)
169*cfb92d14SAndroid Build Coastguard Worker     {
170*cfb92d14SAndroid Build Coastguard Worker         Question question;
171*cfb92d14SAndroid Build Coastguard Worker 
172*cfb92d14SAndroid Build Coastguard Worker         mName.ParseFrom(aMessage, aOffset);
173*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(aMessage.Read(aOffset, question));
174*cfb92d14SAndroid Build Coastguard Worker         aOffset += sizeof(Question);
175*cfb92d14SAndroid Build Coastguard Worker 
176*cfb92d14SAndroid Build Coastguard Worker         mNext            = nullptr;
177*cfb92d14SAndroid Build Coastguard Worker         mType            = question.GetType();
178*cfb92d14SAndroid Build Coastguard Worker         mClass           = question.GetClass() & kClassMask;
179*cfb92d14SAndroid Build Coastguard Worker         mUnicastResponse = question.GetClass() & kClassQueryUnicastFlag;
180*cfb92d14SAndroid Build Coastguard Worker 
181*cfb92d14SAndroid Build Coastguard Worker         Log("      %s %s %s class:%u", mName.AsCString(), RecordTypeToString(mType), mUnicastResponse ? "QU" : "QM",
182*cfb92d14SAndroid Build Coastguard Worker             mClass);
183*cfb92d14SAndroid Build Coastguard Worker     }
184*cfb92d14SAndroid Build Coastguard Worker 
Matchesot::Dns::Multicast::DnsQuestion185*cfb92d14SAndroid Build Coastguard Worker     bool Matches(const char *aName) const { return mName.Matches(aName); }
186*cfb92d14SAndroid Build Coastguard Worker };
187*cfb92d14SAndroid Build Coastguard Worker 
188*cfb92d14SAndroid Build Coastguard Worker struct DnsQuestions : public OwningList<DnsQuestion>
189*cfb92d14SAndroid Build Coastguard Worker {
Containsot::Dns::Multicast::DnsQuestions190*cfb92d14SAndroid Build Coastguard Worker     bool Contains(uint16_t aRrType, const DnsNameString &aFullName, bool aUnicastResponse = false) const
191*cfb92d14SAndroid Build Coastguard Worker     {
192*cfb92d14SAndroid Build Coastguard Worker         bool               contains = false;
193*cfb92d14SAndroid Build Coastguard Worker         const DnsQuestion *question = FindMatching(aFullName.AsCString());
194*cfb92d14SAndroid Build Coastguard Worker 
195*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(question != nullptr);
196*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(question->mType == aRrType);
197*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(question->mClass == ResourceRecord::kClassInternet);
198*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(question->mUnicastResponse == aUnicastResponse);
199*cfb92d14SAndroid Build Coastguard Worker         contains = true;
200*cfb92d14SAndroid Build Coastguard Worker 
201*cfb92d14SAndroid Build Coastguard Worker     exit:
202*cfb92d14SAndroid Build Coastguard Worker         return contains;
203*cfb92d14SAndroid Build Coastguard Worker     }
204*cfb92d14SAndroid Build Coastguard Worker 
Containsot::Dns::Multicast::DnsQuestions205*cfb92d14SAndroid Build Coastguard Worker     bool Contains(const DnsNameString &aFullName, bool aUnicastResponse) const
206*cfb92d14SAndroid Build Coastguard Worker     {
207*cfb92d14SAndroid Build Coastguard Worker         return Contains(ResourceRecord::kTypeAny, aFullName, aUnicastResponse);
208*cfb92d14SAndroid Build Coastguard Worker     }
209*cfb92d14SAndroid Build Coastguard Worker };
210*cfb92d14SAndroid Build Coastguard Worker 
211*cfb92d14SAndroid Build Coastguard Worker enum TtlCheckMode : uint8_t
212*cfb92d14SAndroid Build Coastguard Worker {
213*cfb92d14SAndroid Build Coastguard Worker     kZeroTtl,
214*cfb92d14SAndroid Build Coastguard Worker     kNonZeroTtl,
215*cfb92d14SAndroid Build Coastguard Worker     kLegacyUnicastTtl,
216*cfb92d14SAndroid Build Coastguard Worker };
217*cfb92d14SAndroid Build Coastguard Worker 
218*cfb92d14SAndroid Build Coastguard Worker enum Section : uint8_t
219*cfb92d14SAndroid Build Coastguard Worker {
220*cfb92d14SAndroid Build Coastguard Worker     kInAnswerSection,
221*cfb92d14SAndroid Build Coastguard Worker     kInAdditionalSection,
222*cfb92d14SAndroid Build Coastguard Worker };
223*cfb92d14SAndroid Build Coastguard Worker 
224*cfb92d14SAndroid Build Coastguard Worker struct Data : public ot::Data<kWithUint16Length>
225*cfb92d14SAndroid Build Coastguard Worker {
Dataot::Dns::Multicast::Data226*cfb92d14SAndroid Build Coastguard Worker     Data(const void *aBuffer, uint16_t aLength) { Init(aBuffer, aLength); }
227*cfb92d14SAndroid Build Coastguard Worker 
Matchesot::Dns::Multicast::Data228*cfb92d14SAndroid Build Coastguard Worker     bool Matches(const Array<uint8_t, kMaxDataSize> &aDataArray) const
229*cfb92d14SAndroid Build Coastguard Worker     {
230*cfb92d14SAndroid Build Coastguard Worker         return (aDataArray.GetLength() == GetLength()) && MatchesBytesIn(aDataArray.GetArrayBuffer());
231*cfb92d14SAndroid Build Coastguard Worker     }
232*cfb92d14SAndroid Build Coastguard Worker };
233*cfb92d14SAndroid Build Coastguard Worker 
234*cfb92d14SAndroid Build Coastguard Worker struct DnsRecord : public Allocatable<DnsRecord>, public LinkedListEntry<DnsRecord>
235*cfb92d14SAndroid Build Coastguard Worker {
236*cfb92d14SAndroid Build Coastguard Worker     struct SrvData
237*cfb92d14SAndroid Build Coastguard Worker     {
238*cfb92d14SAndroid Build Coastguard Worker         uint16_t mPriority;
239*cfb92d14SAndroid Build Coastguard Worker         uint16_t mWeight;
240*cfb92d14SAndroid Build Coastguard Worker         uint16_t mPort;
241*cfb92d14SAndroid Build Coastguard Worker         DnsName  mHostName;
242*cfb92d14SAndroid Build Coastguard Worker     };
243*cfb92d14SAndroid Build Coastguard Worker 
244*cfb92d14SAndroid Build Coastguard Worker     union RecordData
245*cfb92d14SAndroid Build Coastguard Worker     {
RecordData(void)246*cfb92d14SAndroid Build Coastguard Worker         RecordData(void) { memset(this, 0, sizeof(*this)); }
247*cfb92d14SAndroid Build Coastguard Worker 
248*cfb92d14SAndroid Build Coastguard Worker         Ip6::Address                 mIp6Address; // For AAAAA (or A)
249*cfb92d14SAndroid Build Coastguard Worker         SrvData                      mSrv;        // For SRV
250*cfb92d14SAndroid Build Coastguard Worker         Array<uint8_t, kMaxDataSize> mData;       // For TXT or KEY
251*cfb92d14SAndroid Build Coastguard Worker         DnsName                      mPtrName;    // For PTR
252*cfb92d14SAndroid Build Coastguard Worker         NsecRecord::TypeBitMap       mNsecBitmap; // For NSEC
253*cfb92d14SAndroid Build Coastguard Worker     };
254*cfb92d14SAndroid Build Coastguard Worker 
255*cfb92d14SAndroid Build Coastguard Worker     DnsRecord *mNext;
256*cfb92d14SAndroid Build Coastguard Worker     DnsName    mName;
257*cfb92d14SAndroid Build Coastguard Worker     uint16_t   mType;
258*cfb92d14SAndroid Build Coastguard Worker     uint16_t   mClass;
259*cfb92d14SAndroid Build Coastguard Worker     uint32_t   mTtl;
260*cfb92d14SAndroid Build Coastguard Worker     bool       mCacheFlush;
261*cfb92d14SAndroid Build Coastguard Worker     RecordData mData;
262*cfb92d14SAndroid Build Coastguard Worker 
Matchesot::Dns::Multicast::DnsRecord263*cfb92d14SAndroid Build Coastguard Worker     bool Matches(const char *aName) const { return mName.Matches(aName); }
264*cfb92d14SAndroid Build Coastguard Worker 
ParseFromot::Dns::Multicast::DnsRecord265*cfb92d14SAndroid Build Coastguard Worker     void ParseFrom(const Message &aMessage, uint16_t &aOffset)
266*cfb92d14SAndroid Build Coastguard Worker     {
267*cfb92d14SAndroid Build Coastguard Worker         String<kStringSize> logStr;
268*cfb92d14SAndroid Build Coastguard Worker         ResourceRecord      record;
269*cfb92d14SAndroid Build Coastguard Worker         uint16_t            offset;
270*cfb92d14SAndroid Build Coastguard Worker 
271*cfb92d14SAndroid Build Coastguard Worker         mName.ParseFrom(aMessage, aOffset);
272*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(aMessage.Read(aOffset, record));
273*cfb92d14SAndroid Build Coastguard Worker         aOffset += sizeof(ResourceRecord);
274*cfb92d14SAndroid Build Coastguard Worker 
275*cfb92d14SAndroid Build Coastguard Worker         mNext       = nullptr;
276*cfb92d14SAndroid Build Coastguard Worker         mType       = record.GetType();
277*cfb92d14SAndroid Build Coastguard Worker         mClass      = record.GetClass() & kClassMask;
278*cfb92d14SAndroid Build Coastguard Worker         mCacheFlush = record.GetClass() & kClassCacheFlushFlag;
279*cfb92d14SAndroid Build Coastguard Worker         mTtl        = record.GetTtl();
280*cfb92d14SAndroid Build Coastguard Worker 
281*cfb92d14SAndroid Build Coastguard Worker         logStr.Append("%s %s%s cls:%u ttl:%u", mName.AsCString(), RecordTypeToString(mType),
282*cfb92d14SAndroid Build Coastguard Worker                       mCacheFlush ? " cache-flush" : "", mClass, mTtl);
283*cfb92d14SAndroid Build Coastguard Worker 
284*cfb92d14SAndroid Build Coastguard Worker         offset = aOffset;
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker         switch (mType)
287*cfb92d14SAndroid Build Coastguard Worker         {
288*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypeAaaa:
289*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(record.GetLength() == sizeof(Ip6::Address));
290*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(aMessage.Read(offset, mData.mIp6Address));
291*cfb92d14SAndroid Build Coastguard Worker             logStr.Append(" %s", mData.mIp6Address.ToString().AsCString());
292*cfb92d14SAndroid Build Coastguard Worker             break;
293*cfb92d14SAndroid Build Coastguard Worker 
294*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypeKey:
295*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypeTxt:
296*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(record.GetLength() > 0);
297*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(record.GetLength() < kMaxDataSize);
298*cfb92d14SAndroid Build Coastguard Worker             mData.mData.SetLength(record.GetLength());
299*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(aMessage.Read(offset, mData.mData.GetArrayBuffer(), record.GetLength()));
300*cfb92d14SAndroid Build Coastguard Worker             logStr.Append(" data-len:%u", record.GetLength());
301*cfb92d14SAndroid Build Coastguard Worker             break;
302*cfb92d14SAndroid Build Coastguard Worker 
303*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypePtr:
304*cfb92d14SAndroid Build Coastguard Worker             mData.mPtrName.ParseFrom(aMessage, offset);
305*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(offset - aOffset == record.GetLength());
306*cfb92d14SAndroid Build Coastguard Worker             logStr.Append(" %s", mData.mPtrName.AsCString());
307*cfb92d14SAndroid Build Coastguard Worker             break;
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypeSrv:
310*cfb92d14SAndroid Build Coastguard Worker         {
311*cfb92d14SAndroid Build Coastguard Worker             SrvRecord srv;
312*cfb92d14SAndroid Build Coastguard Worker 
313*cfb92d14SAndroid Build Coastguard Worker             offset -= sizeof(ResourceRecord);
314*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(aMessage.Read(offset, srv));
315*cfb92d14SAndroid Build Coastguard Worker             offset += sizeof(srv);
316*cfb92d14SAndroid Build Coastguard Worker             mData.mSrv.mHostName.ParseFrom(aMessage, offset);
317*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(offset - aOffset == record.GetLength());
318*cfb92d14SAndroid Build Coastguard Worker             mData.mSrv.mPriority = srv.GetPriority();
319*cfb92d14SAndroid Build Coastguard Worker             mData.mSrv.mWeight   = srv.GetWeight();
320*cfb92d14SAndroid Build Coastguard Worker             mData.mSrv.mPort     = srv.GetPort();
321*cfb92d14SAndroid Build Coastguard Worker             logStr.Append(" port:%u w:%u prio:%u host:%s", mData.mSrv.mPort, mData.mSrv.mWeight, mData.mSrv.mPriority,
322*cfb92d14SAndroid Build Coastguard Worker                           mData.mSrv.mHostName.AsCString());
323*cfb92d14SAndroid Build Coastguard Worker             break;
324*cfb92d14SAndroid Build Coastguard Worker         }
325*cfb92d14SAndroid Build Coastguard Worker 
326*cfb92d14SAndroid Build Coastguard Worker         case ResourceRecord::kTypeNsec:
327*cfb92d14SAndroid Build Coastguard Worker         {
328*cfb92d14SAndroid Build Coastguard Worker             NsecRecord::TypeBitMap &bitmap = mData.mNsecBitmap;
329*cfb92d14SAndroid Build Coastguard Worker 
330*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(Name::CompareName(aMessage, offset, mName.AsCString()));
331*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(aMessage.Read(offset, &bitmap, NsecRecord::TypeBitMap::kMinSize));
332*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(bitmap.GetBlockNumber() == 0);
333*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(bitmap.GetBitmapLength() <= NsecRecord::TypeBitMap::kMaxLength);
334*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(aMessage.Read(offset, &bitmap, bitmap.GetSize()));
335*cfb92d14SAndroid Build Coastguard Worker 
336*cfb92d14SAndroid Build Coastguard Worker             offset += bitmap.GetSize();
337*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(offset - aOffset == record.GetLength());
338*cfb92d14SAndroid Build Coastguard Worker 
339*cfb92d14SAndroid Build Coastguard Worker             logStr.Append(" [ ");
340*cfb92d14SAndroid Build Coastguard Worker 
341*cfb92d14SAndroid Build Coastguard Worker             for (uint16_t type = 0; type < bitmap.GetBitmapLength() * kBitsPerByte; type++)
342*cfb92d14SAndroid Build Coastguard Worker             {
343*cfb92d14SAndroid Build Coastguard Worker                 if (bitmap.ContainsType(type))
344*cfb92d14SAndroid Build Coastguard Worker                 {
345*cfb92d14SAndroid Build Coastguard Worker                     logStr.Append("%s ", RecordTypeToString(type));
346*cfb92d14SAndroid Build Coastguard Worker                 }
347*cfb92d14SAndroid Build Coastguard Worker             }
348*cfb92d14SAndroid Build Coastguard Worker 
349*cfb92d14SAndroid Build Coastguard Worker             logStr.Append("]");
350*cfb92d14SAndroid Build Coastguard Worker             break;
351*cfb92d14SAndroid Build Coastguard Worker         }
352*cfb92d14SAndroid Build Coastguard Worker 
353*cfb92d14SAndroid Build Coastguard Worker         default:
354*cfb92d14SAndroid Build Coastguard Worker             break;
355*cfb92d14SAndroid Build Coastguard Worker         }
356*cfb92d14SAndroid Build Coastguard Worker 
357*cfb92d14SAndroid Build Coastguard Worker         Log("      %s", logStr.AsCString());
358*cfb92d14SAndroid Build Coastguard Worker 
359*cfb92d14SAndroid Build Coastguard Worker         aOffset += record.GetLength();
360*cfb92d14SAndroid Build Coastguard Worker     }
361*cfb92d14SAndroid Build Coastguard Worker 
MatchesTtlot::Dns::Multicast::DnsRecord362*cfb92d14SAndroid Build Coastguard Worker     bool MatchesTtl(TtlCheckMode aTtlCheckMode, uint32_t aTtl) const
363*cfb92d14SAndroid Build Coastguard Worker     {
364*cfb92d14SAndroid Build Coastguard Worker         bool matches = false;
365*cfb92d14SAndroid Build Coastguard Worker 
366*cfb92d14SAndroid Build Coastguard Worker         switch (aTtlCheckMode)
367*cfb92d14SAndroid Build Coastguard Worker         {
368*cfb92d14SAndroid Build Coastguard Worker         case kZeroTtl:
369*cfb92d14SAndroid Build Coastguard Worker             VerifyOrExit(mTtl == 0);
370*cfb92d14SAndroid Build Coastguard Worker             break;
371*cfb92d14SAndroid Build Coastguard Worker         case kNonZeroTtl:
372*cfb92d14SAndroid Build Coastguard Worker             if (aTtl > 0)
373*cfb92d14SAndroid Build Coastguard Worker             {
374*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(mTtl == aTtl);
375*cfb92d14SAndroid Build Coastguard Worker             }
376*cfb92d14SAndroid Build Coastguard Worker 
377*cfb92d14SAndroid Build Coastguard Worker             VerifyOrExit(mTtl > 0);
378*cfb92d14SAndroid Build Coastguard Worker             break;
379*cfb92d14SAndroid Build Coastguard Worker         case kLegacyUnicastTtl:
380*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mTtl <= kMaxLegacyUnicastTtl);
381*cfb92d14SAndroid Build Coastguard Worker             break;
382*cfb92d14SAndroid Build Coastguard Worker         }
383*cfb92d14SAndroid Build Coastguard Worker 
384*cfb92d14SAndroid Build Coastguard Worker         matches = true;
385*cfb92d14SAndroid Build Coastguard Worker 
386*cfb92d14SAndroid Build Coastguard Worker     exit:
387*cfb92d14SAndroid Build Coastguard Worker         return matches;
388*cfb92d14SAndroid Build Coastguard Worker     }
389*cfb92d14SAndroid Build Coastguard Worker };
390*cfb92d14SAndroid Build Coastguard Worker 
391*cfb92d14SAndroid Build Coastguard Worker struct DnsRecords : public OwningList<DnsRecord>
392*cfb92d14SAndroid Build Coastguard Worker {
ContainsAaaaot::Dns::Multicast::DnsRecords393*cfb92d14SAndroid Build Coastguard Worker     bool ContainsAaaa(const DnsNameString &aFullName,
394*cfb92d14SAndroid Build Coastguard Worker                       const Ip6::Address  &aAddress,
395*cfb92d14SAndroid Build Coastguard Worker                       bool                 aCacheFlush,
396*cfb92d14SAndroid Build Coastguard Worker                       TtlCheckMode         aTtlCheckMode,
397*cfb92d14SAndroid Build Coastguard Worker                       uint32_t             aTtl = 0) const
398*cfb92d14SAndroid Build Coastguard Worker     {
399*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
400*cfb92d14SAndroid Build Coastguard Worker 
401*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
402*cfb92d14SAndroid Build Coastguard Worker         {
403*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypeAaaa) &&
404*cfb92d14SAndroid Build Coastguard Worker                 (record.mData.mIp6Address == aAddress))
405*cfb92d14SAndroid Build Coastguard Worker             {
406*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mClass == ResourceRecord::kClassInternet);
407*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mCacheFlush == aCacheFlush);
408*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.MatchesTtl(aTtlCheckMode, aTtl));
409*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
410*cfb92d14SAndroid Build Coastguard Worker                 ExitNow();
411*cfb92d14SAndroid Build Coastguard Worker             }
412*cfb92d14SAndroid Build Coastguard Worker         }
413*cfb92d14SAndroid Build Coastguard Worker 
414*cfb92d14SAndroid Build Coastguard Worker     exit:
415*cfb92d14SAndroid Build Coastguard Worker         return contains;
416*cfb92d14SAndroid Build Coastguard Worker     }
417*cfb92d14SAndroid Build Coastguard Worker 
ContainsKeyot::Dns::Multicast::DnsRecords418*cfb92d14SAndroid Build Coastguard Worker     bool ContainsKey(const DnsNameString &aFullName,
419*cfb92d14SAndroid Build Coastguard Worker                      const Data          &aKeyData,
420*cfb92d14SAndroid Build Coastguard Worker                      bool                 aCacheFlush,
421*cfb92d14SAndroid Build Coastguard Worker                      TtlCheckMode         aTtlCheckMode,
422*cfb92d14SAndroid Build Coastguard Worker                      uint32_t             aTtl = 0) const
423*cfb92d14SAndroid Build Coastguard Worker     {
424*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
425*cfb92d14SAndroid Build Coastguard Worker 
426*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
427*cfb92d14SAndroid Build Coastguard Worker         {
428*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypeKey) &&
429*cfb92d14SAndroid Build Coastguard Worker                 aKeyData.Matches(record.mData.mData))
430*cfb92d14SAndroid Build Coastguard Worker             {
431*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mClass == ResourceRecord::kClassInternet);
432*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mCacheFlush == aCacheFlush);
433*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.MatchesTtl(aTtlCheckMode, aTtl));
434*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
435*cfb92d14SAndroid Build Coastguard Worker                 ExitNow();
436*cfb92d14SAndroid Build Coastguard Worker             }
437*cfb92d14SAndroid Build Coastguard Worker         }
438*cfb92d14SAndroid Build Coastguard Worker 
439*cfb92d14SAndroid Build Coastguard Worker     exit:
440*cfb92d14SAndroid Build Coastguard Worker         return contains;
441*cfb92d14SAndroid Build Coastguard Worker     }
442*cfb92d14SAndroid Build Coastguard Worker 
ContainsSrvot::Dns::Multicast::DnsRecords443*cfb92d14SAndroid Build Coastguard Worker     bool ContainsSrv(const DnsNameString &aFullName,
444*cfb92d14SAndroid Build Coastguard Worker                      const Core::Service &aService,
445*cfb92d14SAndroid Build Coastguard Worker                      bool                 aCacheFlush,
446*cfb92d14SAndroid Build Coastguard Worker                      TtlCheckMode         aTtlCheckMode,
447*cfb92d14SAndroid Build Coastguard Worker                      uint32_t             aTtl = 0) const
448*cfb92d14SAndroid Build Coastguard Worker     {
449*cfb92d14SAndroid Build Coastguard Worker         bool          contains = false;
450*cfb92d14SAndroid Build Coastguard Worker         DnsNameString hostName;
451*cfb92d14SAndroid Build Coastguard Worker 
452*cfb92d14SAndroid Build Coastguard Worker         hostName.Append("%s.local.", aService.mHostName);
453*cfb92d14SAndroid Build Coastguard Worker 
454*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
455*cfb92d14SAndroid Build Coastguard Worker         {
456*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypeSrv))
457*cfb92d14SAndroid Build Coastguard Worker             {
458*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mClass == ResourceRecord::kClassInternet);
459*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mCacheFlush == aCacheFlush);
460*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.MatchesTtl(aTtlCheckMode, aTtl));
461*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mData.mSrv.mPort == aService.mPort);
462*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mData.mSrv.mPriority == aService.mPriority);
463*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mData.mSrv.mWeight == aService.mWeight);
464*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mData.mSrv.mHostName.Matches(hostName.AsCString()));
465*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
466*cfb92d14SAndroid Build Coastguard Worker                 ExitNow();
467*cfb92d14SAndroid Build Coastguard Worker             }
468*cfb92d14SAndroid Build Coastguard Worker         }
469*cfb92d14SAndroid Build Coastguard Worker 
470*cfb92d14SAndroid Build Coastguard Worker     exit:
471*cfb92d14SAndroid Build Coastguard Worker         return contains;
472*cfb92d14SAndroid Build Coastguard Worker     }
473*cfb92d14SAndroid Build Coastguard Worker 
ContainsTxtot::Dns::Multicast::DnsRecords474*cfb92d14SAndroid Build Coastguard Worker     bool ContainsTxt(const DnsNameString &aFullName,
475*cfb92d14SAndroid Build Coastguard Worker                      const Core::Service &aService,
476*cfb92d14SAndroid Build Coastguard Worker                      bool                 aCacheFlush,
477*cfb92d14SAndroid Build Coastguard Worker                      TtlCheckMode         aTtlCheckMode,
478*cfb92d14SAndroid Build Coastguard Worker                      uint32_t             aTtl = 0) const
479*cfb92d14SAndroid Build Coastguard Worker     {
480*cfb92d14SAndroid Build Coastguard Worker         static const uint8_t kEmptyTxtData[1] = {0};
481*cfb92d14SAndroid Build Coastguard Worker 
482*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
483*cfb92d14SAndroid Build Coastguard Worker         Data txtData(aService.mTxtData, aService.mTxtDataLength);
484*cfb92d14SAndroid Build Coastguard Worker 
485*cfb92d14SAndroid Build Coastguard Worker         if ((aService.mTxtData == nullptr) || (aService.mTxtDataLength == 0))
486*cfb92d14SAndroid Build Coastguard Worker         {
487*cfb92d14SAndroid Build Coastguard Worker             txtData.Init(kEmptyTxtData, sizeof(kEmptyTxtData));
488*cfb92d14SAndroid Build Coastguard Worker         }
489*cfb92d14SAndroid Build Coastguard Worker 
490*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
491*cfb92d14SAndroid Build Coastguard Worker         {
492*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypeTxt) &&
493*cfb92d14SAndroid Build Coastguard Worker                 txtData.Matches(record.mData.mData))
494*cfb92d14SAndroid Build Coastguard Worker             {
495*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mClass == ResourceRecord::kClassInternet);
496*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mCacheFlush == aCacheFlush);
497*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.MatchesTtl(aTtlCheckMode, aTtl));
498*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
499*cfb92d14SAndroid Build Coastguard Worker                 ExitNow();
500*cfb92d14SAndroid Build Coastguard Worker             }
501*cfb92d14SAndroid Build Coastguard Worker         }
502*cfb92d14SAndroid Build Coastguard Worker 
503*cfb92d14SAndroid Build Coastguard Worker     exit:
504*cfb92d14SAndroid Build Coastguard Worker         return contains;
505*cfb92d14SAndroid Build Coastguard Worker     }
506*cfb92d14SAndroid Build Coastguard Worker 
ContainsPtrot::Dns::Multicast::DnsRecords507*cfb92d14SAndroid Build Coastguard Worker     bool ContainsPtr(const DnsNameString &aFullName,
508*cfb92d14SAndroid Build Coastguard Worker                      const DnsNameString &aPtrName,
509*cfb92d14SAndroid Build Coastguard Worker                      TtlCheckMode         aTtlCheckMode,
510*cfb92d14SAndroid Build Coastguard Worker                      uint32_t             aTtl = 0) const
511*cfb92d14SAndroid Build Coastguard Worker     {
512*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
513*cfb92d14SAndroid Build Coastguard Worker 
514*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
515*cfb92d14SAndroid Build Coastguard Worker         {
516*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypePtr) &&
517*cfb92d14SAndroid Build Coastguard Worker                 (record.mData.mPtrName.Matches(aPtrName.AsCString())))
518*cfb92d14SAndroid Build Coastguard Worker             {
519*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mClass == ResourceRecord::kClassInternet);
520*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(!record.mCacheFlush); // PTR should never use cache-flush
521*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.MatchesTtl(aTtlCheckMode, aTtl));
522*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
523*cfb92d14SAndroid Build Coastguard Worker                 ExitNow();
524*cfb92d14SAndroid Build Coastguard Worker             }
525*cfb92d14SAndroid Build Coastguard Worker         }
526*cfb92d14SAndroid Build Coastguard Worker 
527*cfb92d14SAndroid Build Coastguard Worker     exit:
528*cfb92d14SAndroid Build Coastguard Worker         return contains;
529*cfb92d14SAndroid Build Coastguard Worker     }
530*cfb92d14SAndroid Build Coastguard Worker 
ContainsServicesPtrot::Dns::Multicast::DnsRecords531*cfb92d14SAndroid Build Coastguard Worker     bool ContainsServicesPtr(const DnsNameString &aServiceType) const
532*cfb92d14SAndroid Build Coastguard Worker     {
533*cfb92d14SAndroid Build Coastguard Worker         DnsNameString allServices;
534*cfb92d14SAndroid Build Coastguard Worker 
535*cfb92d14SAndroid Build Coastguard Worker         allServices.Append("_services._dns-sd._udp.local.");
536*cfb92d14SAndroid Build Coastguard Worker 
537*cfb92d14SAndroid Build Coastguard Worker         return ContainsPtr(allServices, aServiceType, kNonZeroTtl, 0);
538*cfb92d14SAndroid Build Coastguard Worker     }
539*cfb92d14SAndroid Build Coastguard Worker 
ContainsNsecot::Dns::Multicast::DnsRecords540*cfb92d14SAndroid Build Coastguard Worker     bool ContainsNsec(const DnsNameString &aFullName, uint16_t aRecordType) const
541*cfb92d14SAndroid Build Coastguard Worker     {
542*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
543*cfb92d14SAndroid Build Coastguard Worker 
544*cfb92d14SAndroid Build Coastguard Worker         for (const DnsRecord &record : *this)
545*cfb92d14SAndroid Build Coastguard Worker         {
546*cfb92d14SAndroid Build Coastguard Worker             if (record.Matches(aFullName.AsCString()) && (record.mType == ResourceRecord::kTypeNsec))
547*cfb92d14SAndroid Build Coastguard Worker             {
548*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(!contains); // Ensure only one NSEC record
549*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(record.mData.mNsecBitmap.ContainsType(aRecordType));
550*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
551*cfb92d14SAndroid Build Coastguard Worker             }
552*cfb92d14SAndroid Build Coastguard Worker         }
553*cfb92d14SAndroid Build Coastguard Worker 
554*cfb92d14SAndroid Build Coastguard Worker     exit:
555*cfb92d14SAndroid Build Coastguard Worker         return contains;
556*cfb92d14SAndroid Build Coastguard Worker     }
557*cfb92d14SAndroid Build Coastguard Worker };
558*cfb92d14SAndroid Build Coastguard Worker 
559*cfb92d14SAndroid Build Coastguard Worker // Bit-flags used in `Validate()` with a `Service`
560*cfb92d14SAndroid Build Coastguard Worker // to specify which records should be checked in the announce
561*cfb92d14SAndroid Build Coastguard Worker // message.
562*cfb92d14SAndroid Build Coastguard Worker 
563*cfb92d14SAndroid Build Coastguard Worker typedef uint8_t AnnounceCheckFlags;
564*cfb92d14SAndroid Build Coastguard Worker 
565*cfb92d14SAndroid Build Coastguard Worker static constexpr uint8_t kCheckSrv         = (1 << 0);
566*cfb92d14SAndroid Build Coastguard Worker static constexpr uint8_t kCheckTxt         = (1 << 1);
567*cfb92d14SAndroid Build Coastguard Worker static constexpr uint8_t kCheckPtr         = (1 << 2);
568*cfb92d14SAndroid Build Coastguard Worker static constexpr uint8_t kCheckServicesPtr = (1 << 3);
569*cfb92d14SAndroid Build Coastguard Worker 
570*cfb92d14SAndroid Build Coastguard Worker enum GoodBye : bool // Used to indicate "goodbye" records (with zero TTL)
571*cfb92d14SAndroid Build Coastguard Worker {
572*cfb92d14SAndroid Build Coastguard Worker     kNotGoodBye = false,
573*cfb92d14SAndroid Build Coastguard Worker     kGoodBye    = true,
574*cfb92d14SAndroid Build Coastguard Worker };
575*cfb92d14SAndroid Build Coastguard Worker 
576*cfb92d14SAndroid Build Coastguard Worker enum DnsMessageType : uint8_t
577*cfb92d14SAndroid Build Coastguard Worker {
578*cfb92d14SAndroid Build Coastguard Worker     kMulticastQuery,
579*cfb92d14SAndroid Build Coastguard Worker     kMulticastResponse,
580*cfb92d14SAndroid Build Coastguard Worker     kUnicastResponse,
581*cfb92d14SAndroid Build Coastguard Worker     kLegacyUnicastResponse,
582*cfb92d14SAndroid Build Coastguard Worker };
583*cfb92d14SAndroid Build Coastguard Worker 
584*cfb92d14SAndroid Build Coastguard Worker struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMessage>
585*cfb92d14SAndroid Build Coastguard Worker {
586*cfb92d14SAndroid Build Coastguard Worker     DnsMessage       *mNext;
587*cfb92d14SAndroid Build Coastguard Worker     uint32_t          mTimestamp;
588*cfb92d14SAndroid Build Coastguard Worker     DnsMessageType    mType;
589*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo mUnicastDest;
590*cfb92d14SAndroid Build Coastguard Worker     Header            mHeader;
591*cfb92d14SAndroid Build Coastguard Worker     DnsQuestions      mQuestions;
592*cfb92d14SAndroid Build Coastguard Worker     DnsRecords        mAnswerRecords;
593*cfb92d14SAndroid Build Coastguard Worker     DnsRecords        mAuthRecords;
594*cfb92d14SAndroid Build Coastguard Worker     DnsRecords        mAdditionalRecords;
595*cfb92d14SAndroid Build Coastguard Worker 
DnsMessageot::Dns::Multicast::DnsMessage596*cfb92d14SAndroid Build Coastguard Worker     DnsMessage(void)
597*cfb92d14SAndroid Build Coastguard Worker         : mNext(nullptr)
598*cfb92d14SAndroid Build Coastguard Worker         , mTimestamp(sNow)
599*cfb92d14SAndroid Build Coastguard Worker     {
600*cfb92d14SAndroid Build Coastguard Worker     }
601*cfb92d14SAndroid Build Coastguard Worker 
RecordsForot::Dns::Multicast::DnsMessage602*cfb92d14SAndroid Build Coastguard Worker     const DnsRecords &RecordsFor(Section aSection) const
603*cfb92d14SAndroid Build Coastguard Worker     {
604*cfb92d14SAndroid Build Coastguard Worker         const DnsRecords *records = nullptr;
605*cfb92d14SAndroid Build Coastguard Worker 
606*cfb92d14SAndroid Build Coastguard Worker         switch (aSection)
607*cfb92d14SAndroid Build Coastguard Worker         {
608*cfb92d14SAndroid Build Coastguard Worker         case kInAnswerSection:
609*cfb92d14SAndroid Build Coastguard Worker             records = &mAnswerRecords;
610*cfb92d14SAndroid Build Coastguard Worker             break;
611*cfb92d14SAndroid Build Coastguard Worker         case kInAdditionalSection:
612*cfb92d14SAndroid Build Coastguard Worker             records = &mAdditionalRecords;
613*cfb92d14SAndroid Build Coastguard Worker             break;
614*cfb92d14SAndroid Build Coastguard Worker         }
615*cfb92d14SAndroid Build Coastguard Worker 
616*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(records != nullptr);
617*cfb92d14SAndroid Build Coastguard Worker 
618*cfb92d14SAndroid Build Coastguard Worker         return *records;
619*cfb92d14SAndroid Build Coastguard Worker     }
620*cfb92d14SAndroid Build Coastguard Worker 
ParseRecordsot::Dns::Multicast::DnsMessage621*cfb92d14SAndroid Build Coastguard Worker     void ParseRecords(const Message         &aMessage,
622*cfb92d14SAndroid Build Coastguard Worker                       uint16_t              &aOffset,
623*cfb92d14SAndroid Build Coastguard Worker                       uint16_t               aNumRecords,
624*cfb92d14SAndroid Build Coastguard Worker                       OwningList<DnsRecord> &aRecords,
625*cfb92d14SAndroid Build Coastguard Worker                       const char            *aSectionName)
626*cfb92d14SAndroid Build Coastguard Worker     {
627*cfb92d14SAndroid Build Coastguard Worker         if (aNumRecords > 0)
628*cfb92d14SAndroid Build Coastguard Worker         {
629*cfb92d14SAndroid Build Coastguard Worker             Log("   %s", aSectionName);
630*cfb92d14SAndroid Build Coastguard Worker         }
631*cfb92d14SAndroid Build Coastguard Worker 
632*cfb92d14SAndroid Build Coastguard Worker         for (; aNumRecords > 0; aNumRecords--)
633*cfb92d14SAndroid Build Coastguard Worker         {
634*cfb92d14SAndroid Build Coastguard Worker             DnsRecord *record = DnsRecord::Allocate();
635*cfb92d14SAndroid Build Coastguard Worker 
636*cfb92d14SAndroid Build Coastguard Worker             record->ParseFrom(aMessage, aOffset);
637*cfb92d14SAndroid Build Coastguard Worker             aRecords.PushAfterTail(*record);
638*cfb92d14SAndroid Build Coastguard Worker         }
639*cfb92d14SAndroid Build Coastguard Worker     }
640*cfb92d14SAndroid Build Coastguard Worker 
ParseFromot::Dns::Multicast::DnsMessage641*cfb92d14SAndroid Build Coastguard Worker     void ParseFrom(const Message &aMessage)
642*cfb92d14SAndroid Build Coastguard Worker     {
643*cfb92d14SAndroid Build Coastguard Worker         uint16_t offset = 0;
644*cfb92d14SAndroid Build Coastguard Worker 
645*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(aMessage.Read(offset, mHeader));
646*cfb92d14SAndroid Build Coastguard Worker         offset += sizeof(Header);
647*cfb92d14SAndroid Build Coastguard Worker 
648*cfb92d14SAndroid Build Coastguard Worker         Log("   %s id:%u qt:%u t:%u rcode:%u [q:%u ans:%u auth:%u addn:%u]",
649*cfb92d14SAndroid Build Coastguard Worker             mHeader.GetType() == Header::kTypeQuery ? "Query" : "Response", mHeader.GetMessageId(),
650*cfb92d14SAndroid Build Coastguard Worker             mHeader.GetQueryType(), mHeader.IsTruncationFlagSet(), mHeader.GetResponseCode(),
651*cfb92d14SAndroid Build Coastguard Worker             mHeader.GetQuestionCount(), mHeader.GetAnswerCount(), mHeader.GetAuthorityRecordCount(),
652*cfb92d14SAndroid Build Coastguard Worker             mHeader.GetAdditionalRecordCount());
653*cfb92d14SAndroid Build Coastguard Worker 
654*cfb92d14SAndroid Build Coastguard Worker         if (mHeader.GetQuestionCount() > 0)
655*cfb92d14SAndroid Build Coastguard Worker         {
656*cfb92d14SAndroid Build Coastguard Worker             Log("   Question");
657*cfb92d14SAndroid Build Coastguard Worker         }
658*cfb92d14SAndroid Build Coastguard Worker 
659*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t num = mHeader.GetQuestionCount(); num > 0; num--)
660*cfb92d14SAndroid Build Coastguard Worker         {
661*cfb92d14SAndroid Build Coastguard Worker             DnsQuestion *question = DnsQuestion::Allocate();
662*cfb92d14SAndroid Build Coastguard Worker 
663*cfb92d14SAndroid Build Coastguard Worker             question->ParseFrom(aMessage, offset);
664*cfb92d14SAndroid Build Coastguard Worker             mQuestions.PushAfterTail(*question);
665*cfb92d14SAndroid Build Coastguard Worker         }
666*cfb92d14SAndroid Build Coastguard Worker 
667*cfb92d14SAndroid Build Coastguard Worker         ParseRecords(aMessage, offset, mHeader.GetAnswerCount(), mAnswerRecords, "Answer");
668*cfb92d14SAndroid Build Coastguard Worker         ParseRecords(aMessage, offset, mHeader.GetAuthorityRecordCount(), mAuthRecords, "Authority");
669*cfb92d14SAndroid Build Coastguard Worker         ParseRecords(aMessage, offset, mHeader.GetAdditionalRecordCount(), mAdditionalRecords, "Additional");
670*cfb92d14SAndroid Build Coastguard Worker     }
671*cfb92d14SAndroid Build Coastguard Worker 
ValidateHeaderot::Dns::Multicast::DnsMessage672*cfb92d14SAndroid Build Coastguard Worker     void ValidateHeader(DnsMessageType aType,
673*cfb92d14SAndroid Build Coastguard Worker                         uint16_t       aQuestionCount,
674*cfb92d14SAndroid Build Coastguard Worker                         uint16_t       aAnswerCount,
675*cfb92d14SAndroid Build Coastguard Worker                         uint16_t       aAuthCount,
676*cfb92d14SAndroid Build Coastguard Worker                         uint16_t       aAdditionalCount) const
677*cfb92d14SAndroid Build Coastguard Worker     {
678*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mType == aType);
679*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetQuestionCount() == aQuestionCount);
680*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetAnswerCount() == aAnswerCount);
681*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetAuthorityRecordCount() == aAuthCount);
682*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetAdditionalRecordCount() == aAdditionalCount);
683*cfb92d14SAndroid Build Coastguard Worker 
684*cfb92d14SAndroid Build Coastguard Worker         if (aType == kUnicastResponse)
685*cfb92d14SAndroid Build Coastguard Worker         {
686*cfb92d14SAndroid Build Coastguard Worker             Ip6::Address ip6Address;
687*cfb92d14SAndroid Build Coastguard Worker 
688*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ip6Address.FromString(kDeviceIp6Address));
689*cfb92d14SAndroid Build Coastguard Worker 
690*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mUnicastDest.mPort == kMdnsPort);
691*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mUnicastDest.GetAddress() == ip6Address);
692*cfb92d14SAndroid Build Coastguard Worker         }
693*cfb92d14SAndroid Build Coastguard Worker 
694*cfb92d14SAndroid Build Coastguard Worker         if (aType == kLegacyUnicastResponse)
695*cfb92d14SAndroid Build Coastguard Worker         {
696*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mHeader.GetMessageId() == kLegacyUnicastMessageId);
697*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mUnicastDest.mPort == kEphemeralPort);
698*cfb92d14SAndroid Build Coastguard Worker         }
699*cfb92d14SAndroid Build Coastguard Worker     }
700*cfb92d14SAndroid Build Coastguard Worker 
DetermineFullNameForKeyot::Dns::Multicast::DnsMessage701*cfb92d14SAndroid Build Coastguard Worker     static void DetermineFullNameForKey(const Core::Key &aKey, DnsNameString &aFullName)
702*cfb92d14SAndroid Build Coastguard Worker     {
703*cfb92d14SAndroid Build Coastguard Worker         if (aKey.mServiceType != nullptr)
704*cfb92d14SAndroid Build Coastguard Worker         {
705*cfb92d14SAndroid Build Coastguard Worker             aFullName.Append("%s.%s.local.", aKey.mName, aKey.mServiceType);
706*cfb92d14SAndroid Build Coastguard Worker         }
707*cfb92d14SAndroid Build Coastguard Worker         else
708*cfb92d14SAndroid Build Coastguard Worker         {
709*cfb92d14SAndroid Build Coastguard Worker             aFullName.Append("%s.local.", aKey.mName);
710*cfb92d14SAndroid Build Coastguard Worker         }
711*cfb92d14SAndroid Build Coastguard Worker     }
712*cfb92d14SAndroid Build Coastguard Worker 
DetermineTtlCheckModeot::Dns::Multicast::DnsMessage713*cfb92d14SAndroid Build Coastguard Worker     static TtlCheckMode DetermineTtlCheckMode(DnsMessageType aMessageType, bool aIsGoodBye)
714*cfb92d14SAndroid Build Coastguard Worker     {
715*cfb92d14SAndroid Build Coastguard Worker         TtlCheckMode ttlCheck;
716*cfb92d14SAndroid Build Coastguard Worker 
717*cfb92d14SAndroid Build Coastguard Worker         if (aMessageType == kLegacyUnicastResponse)
718*cfb92d14SAndroid Build Coastguard Worker         {
719*cfb92d14SAndroid Build Coastguard Worker             ttlCheck = kLegacyUnicastTtl;
720*cfb92d14SAndroid Build Coastguard Worker         }
721*cfb92d14SAndroid Build Coastguard Worker         else
722*cfb92d14SAndroid Build Coastguard Worker         {
723*cfb92d14SAndroid Build Coastguard Worker             ttlCheck = aIsGoodBye ? kZeroTtl : kNonZeroTtl;
724*cfb92d14SAndroid Build Coastguard Worker         }
725*cfb92d14SAndroid Build Coastguard Worker 
726*cfb92d14SAndroid Build Coastguard Worker         return ttlCheck;
727*cfb92d14SAndroid Build Coastguard Worker     }
728*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsProbeForot::Dns::Multicast::DnsMessage729*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsProbeFor(const Core::Host &aHost, bool aUnicastResponse) const
730*cfb92d14SAndroid Build Coastguard Worker     {
731*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
732*cfb92d14SAndroid Build Coastguard Worker 
733*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
734*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
735*cfb92d14SAndroid Build Coastguard Worker 
736*cfb92d14SAndroid Build Coastguard Worker         fullName.Append("%s.local.", aHost.mHostName);
737*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(fullName, aUnicastResponse));
738*cfb92d14SAndroid Build Coastguard Worker 
739*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < aHost.mAddressesLength; index++)
740*cfb92d14SAndroid Build Coastguard Worker         {
741*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mAuthRecords.ContainsAaaa(fullName, AsCoreType(&aHost.mAddresses[index]), !kCacheFlush,
742*cfb92d14SAndroid Build Coastguard Worker                                                    kNonZeroTtl, aHost.mTtl));
743*cfb92d14SAndroid Build Coastguard Worker         }
744*cfb92d14SAndroid Build Coastguard Worker     }
745*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsProbeForot::Dns::Multicast::DnsMessage746*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsProbeFor(const Core::Service &aService, bool aUnicastResponse) const
747*cfb92d14SAndroid Build Coastguard Worker     {
748*cfb92d14SAndroid Build Coastguard Worker         DnsNameString serviceName;
749*cfb92d14SAndroid Build Coastguard Worker 
750*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
751*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
752*cfb92d14SAndroid Build Coastguard Worker 
753*cfb92d14SAndroid Build Coastguard Worker         serviceName.Append("%s.%s.local.", aService.mServiceInstance, aService.mServiceType);
754*cfb92d14SAndroid Build Coastguard Worker 
755*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(serviceName, aUnicastResponse));
756*cfb92d14SAndroid Build Coastguard Worker 
757*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mAuthRecords.ContainsSrv(serviceName, aService, !kCacheFlush, kNonZeroTtl, aService.mTtl));
758*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mAuthRecords.ContainsTxt(serviceName, aService, !kCacheFlush, kNonZeroTtl, aService.mTtl));
759*cfb92d14SAndroid Build Coastguard Worker     }
760*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsProbeForot::Dns::Multicast::DnsMessage761*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsProbeFor(const Core::Key &aKey, bool aUnicastResponse) const
762*cfb92d14SAndroid Build Coastguard Worker     {
763*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
764*cfb92d14SAndroid Build Coastguard Worker 
765*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
766*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
767*cfb92d14SAndroid Build Coastguard Worker 
768*cfb92d14SAndroid Build Coastguard Worker         DetermineFullNameForKey(aKey, fullName);
769*cfb92d14SAndroid Build Coastguard Worker 
770*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(fullName, aUnicastResponse));
771*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mAuthRecords.ContainsKey(fullName, Data(aKey.mKeyData, aKey.mKeyDataLength), !kCacheFlush,
772*cfb92d14SAndroid Build Coastguard Worker                                               kNonZeroTtl, aKey.mTtl));
773*cfb92d14SAndroid Build Coastguard Worker     }
774*cfb92d14SAndroid Build Coastguard Worker 
Validateot::Dns::Multicast::DnsMessage775*cfb92d14SAndroid Build Coastguard Worker     void Validate(const Core::Host &aHost, Section aSection, GoodBye aIsGoodBye = kNotGoodBye) const
776*cfb92d14SAndroid Build Coastguard Worker     {
777*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
778*cfb92d14SAndroid Build Coastguard Worker         TtlCheckMode  ttlCheck;
779*cfb92d14SAndroid Build Coastguard Worker 
780*cfb92d14SAndroid Build Coastguard Worker         bool cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
781*cfb92d14SAndroid Build Coastguard Worker 
782*cfb92d14SAndroid Build Coastguard Worker         ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
783*cfb92d14SAndroid Build Coastguard Worker 
784*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
785*cfb92d14SAndroid Build Coastguard Worker 
786*cfb92d14SAndroid Build Coastguard Worker         fullName.Append("%s.local.", aHost.mHostName);
787*cfb92d14SAndroid Build Coastguard Worker 
788*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < aHost.mAddressesLength; index++)
789*cfb92d14SAndroid Build Coastguard Worker         {
790*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(RecordsFor(aSection).ContainsAaaa(fullName, AsCoreType(&aHost.mAddresses[index]),
791*cfb92d14SAndroid Build Coastguard Worker                                                            cacheFlushSet, ttlCheck, aHost.mTtl));
792*cfb92d14SAndroid Build Coastguard Worker         }
793*cfb92d14SAndroid Build Coastguard Worker 
794*cfb92d14SAndroid Build Coastguard Worker         if (!aIsGoodBye && (aSection == kInAnswerSection))
795*cfb92d14SAndroid Build Coastguard Worker         {
796*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mAdditionalRecords.ContainsNsec(fullName, ResourceRecord::kTypeAaaa));
797*cfb92d14SAndroid Build Coastguard Worker         }
798*cfb92d14SAndroid Build Coastguard Worker     }
799*cfb92d14SAndroid Build Coastguard Worker 
Validateot::Dns::Multicast::DnsMessage800*cfb92d14SAndroid Build Coastguard Worker     void Validate(const Core::Service &aService,
801*cfb92d14SAndroid Build Coastguard Worker                   Section              aSection,
802*cfb92d14SAndroid Build Coastguard Worker                   AnnounceCheckFlags   aCheckFlags,
803*cfb92d14SAndroid Build Coastguard Worker                   GoodBye              aIsGoodBye = kNotGoodBye) const
804*cfb92d14SAndroid Build Coastguard Worker     {
805*cfb92d14SAndroid Build Coastguard Worker         DnsNameString serviceName;
806*cfb92d14SAndroid Build Coastguard Worker         DnsNameString serviceType;
807*cfb92d14SAndroid Build Coastguard Worker         TtlCheckMode  ttlCheck;
808*cfb92d14SAndroid Build Coastguard Worker         bool          checkNsec     = false;
809*cfb92d14SAndroid Build Coastguard Worker         bool          cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
810*cfb92d14SAndroid Build Coastguard Worker 
811*cfb92d14SAndroid Build Coastguard Worker         ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
812*cfb92d14SAndroid Build Coastguard Worker 
813*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
814*cfb92d14SAndroid Build Coastguard Worker 
815*cfb92d14SAndroid Build Coastguard Worker         serviceName.Append("%s.%s.local.", aService.mServiceInstance, aService.mServiceType);
816*cfb92d14SAndroid Build Coastguard Worker         serviceType.Append("%s.local.", aService.mServiceType);
817*cfb92d14SAndroid Build Coastguard Worker 
818*cfb92d14SAndroid Build Coastguard Worker         if (aCheckFlags & kCheckSrv)
819*cfb92d14SAndroid Build Coastguard Worker         {
820*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(
821*cfb92d14SAndroid Build Coastguard Worker                 RecordsFor(aSection).ContainsSrv(serviceName, aService, cacheFlushSet, ttlCheck, aService.mTtl));
822*cfb92d14SAndroid Build Coastguard Worker 
823*cfb92d14SAndroid Build Coastguard Worker             checkNsec = true;
824*cfb92d14SAndroid Build Coastguard Worker         }
825*cfb92d14SAndroid Build Coastguard Worker 
826*cfb92d14SAndroid Build Coastguard Worker         if (aCheckFlags & kCheckTxt)
827*cfb92d14SAndroid Build Coastguard Worker         {
828*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(
829*cfb92d14SAndroid Build Coastguard Worker                 RecordsFor(aSection).ContainsTxt(serviceName, aService, cacheFlushSet, ttlCheck, aService.mTtl));
830*cfb92d14SAndroid Build Coastguard Worker 
831*cfb92d14SAndroid Build Coastguard Worker             checkNsec = true;
832*cfb92d14SAndroid Build Coastguard Worker         }
833*cfb92d14SAndroid Build Coastguard Worker 
834*cfb92d14SAndroid Build Coastguard Worker         if (aCheckFlags & kCheckPtr)
835*cfb92d14SAndroid Build Coastguard Worker         {
836*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(RecordsFor(aSection).ContainsPtr(serviceType, serviceName, ttlCheck, aService.mTtl));
837*cfb92d14SAndroid Build Coastguard Worker         }
838*cfb92d14SAndroid Build Coastguard Worker 
839*cfb92d14SAndroid Build Coastguard Worker         if (aCheckFlags & kCheckServicesPtr)
840*cfb92d14SAndroid Build Coastguard Worker         {
841*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(RecordsFor(aSection).ContainsServicesPtr(serviceType));
842*cfb92d14SAndroid Build Coastguard Worker         }
843*cfb92d14SAndroid Build Coastguard Worker 
844*cfb92d14SAndroid Build Coastguard Worker         if (!aIsGoodBye && checkNsec && (aSection == kInAnswerSection))
845*cfb92d14SAndroid Build Coastguard Worker         {
846*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mAdditionalRecords.ContainsNsec(serviceName, ResourceRecord::kTypeSrv));
847*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mAdditionalRecords.ContainsNsec(serviceName, ResourceRecord::kTypeTxt));
848*cfb92d14SAndroid Build Coastguard Worker         }
849*cfb92d14SAndroid Build Coastguard Worker     }
850*cfb92d14SAndroid Build Coastguard Worker 
Validateot::Dns::Multicast::DnsMessage851*cfb92d14SAndroid Build Coastguard Worker     void Validate(const Core::Key &aKey, Section aSection, GoodBye aIsGoodBye = kNotGoodBye) const
852*cfb92d14SAndroid Build Coastguard Worker     {
853*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
854*cfb92d14SAndroid Build Coastguard Worker         TtlCheckMode  ttlCheck;
855*cfb92d14SAndroid Build Coastguard Worker         bool          cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
856*cfb92d14SAndroid Build Coastguard Worker 
857*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
858*cfb92d14SAndroid Build Coastguard Worker 
859*cfb92d14SAndroid Build Coastguard Worker         DetermineFullNameForKey(aKey, fullName);
860*cfb92d14SAndroid Build Coastguard Worker 
861*cfb92d14SAndroid Build Coastguard Worker         ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
862*cfb92d14SAndroid Build Coastguard Worker 
863*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(RecordsFor(aSection).ContainsKey(fullName, Data(aKey.mKeyData, aKey.mKeyDataLength), cacheFlushSet,
864*cfb92d14SAndroid Build Coastguard Worker                                                       ttlCheck, aKey.mTtl));
865*cfb92d14SAndroid Build Coastguard Worker 
866*cfb92d14SAndroid Build Coastguard Worker         if (!aIsGoodBye && (aSection == kInAnswerSection))
867*cfb92d14SAndroid Build Coastguard Worker         {
868*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(mAdditionalRecords.ContainsNsec(fullName, ResourceRecord::kTypeKey));
869*cfb92d14SAndroid Build Coastguard Worker         }
870*cfb92d14SAndroid Build Coastguard Worker     }
871*cfb92d14SAndroid Build Coastguard Worker 
ValidateSubTypeot::Dns::Multicast::DnsMessage872*cfb92d14SAndroid Build Coastguard Worker     void ValidateSubType(const char *aSubLabel, const Core::Service &aService, GoodBye aIsGoodBye = kNotGoodBye) const
873*cfb92d14SAndroid Build Coastguard Worker     {
874*cfb92d14SAndroid Build Coastguard Worker         DnsNameString serviceName;
875*cfb92d14SAndroid Build Coastguard Worker         DnsNameString subServiceType;
876*cfb92d14SAndroid Build Coastguard Worker 
877*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
878*cfb92d14SAndroid Build Coastguard Worker 
879*cfb92d14SAndroid Build Coastguard Worker         serviceName.Append("%s.%s.local.", aService.mServiceInstance, aService.mServiceType);
880*cfb92d14SAndroid Build Coastguard Worker         subServiceType.Append("%s._sub.%s.local.", aSubLabel, aService.mServiceType);
881*cfb92d14SAndroid Build Coastguard Worker 
882*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mAnswerRecords.ContainsPtr(subServiceType, serviceName, aIsGoodBye ? kZeroTtl : kNonZeroTtl,
883*cfb92d14SAndroid Build Coastguard Worker                                                 aService.mTtl));
884*cfb92d14SAndroid Build Coastguard Worker     }
885*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsQueryForot::Dns::Multicast::DnsMessage886*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsQueryFor(const Core::Browser &aBrowser) const
887*cfb92d14SAndroid Build Coastguard Worker     {
888*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullServiceType;
889*cfb92d14SAndroid Build Coastguard Worker 
890*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
891*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
892*cfb92d14SAndroid Build Coastguard Worker 
893*cfb92d14SAndroid Build Coastguard Worker         if (aBrowser.mSubTypeLabel == nullptr)
894*cfb92d14SAndroid Build Coastguard Worker         {
895*cfb92d14SAndroid Build Coastguard Worker             fullServiceType.Append("%s.local.", aBrowser.mServiceType);
896*cfb92d14SAndroid Build Coastguard Worker         }
897*cfb92d14SAndroid Build Coastguard Worker         else
898*cfb92d14SAndroid Build Coastguard Worker         {
899*cfb92d14SAndroid Build Coastguard Worker             fullServiceType.Append("%s._sub.%s.local", aBrowser.mSubTypeLabel, aBrowser.mServiceType);
900*cfb92d14SAndroid Build Coastguard Worker         }
901*cfb92d14SAndroid Build Coastguard Worker 
902*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(ResourceRecord::kTypePtr, fullServiceType));
903*cfb92d14SAndroid Build Coastguard Worker     }
904*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsQueryForot::Dns::Multicast::DnsMessage905*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsQueryFor(const Core::SrvResolver &aResolver) const
906*cfb92d14SAndroid Build Coastguard Worker     {
907*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
908*cfb92d14SAndroid Build Coastguard Worker 
909*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
910*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
911*cfb92d14SAndroid Build Coastguard Worker 
912*cfb92d14SAndroid Build Coastguard Worker         fullName.Append("%s.%s.local.", aResolver.mServiceInstance, aResolver.mServiceType);
913*cfb92d14SAndroid Build Coastguard Worker 
914*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(ResourceRecord::kTypeSrv, fullName));
915*cfb92d14SAndroid Build Coastguard Worker     }
916*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsQueryForot::Dns::Multicast::DnsMessage917*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsQueryFor(const Core::TxtResolver &aResolver) const
918*cfb92d14SAndroid Build Coastguard Worker     {
919*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
920*cfb92d14SAndroid Build Coastguard Worker 
921*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
922*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
923*cfb92d14SAndroid Build Coastguard Worker 
924*cfb92d14SAndroid Build Coastguard Worker         fullName.Append("%s.%s.local.", aResolver.mServiceInstance, aResolver.mServiceType);
925*cfb92d14SAndroid Build Coastguard Worker 
926*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(ResourceRecord::kTypeTxt, fullName));
927*cfb92d14SAndroid Build Coastguard Worker     }
928*cfb92d14SAndroid Build Coastguard Worker 
ValidateAsQueryForot::Dns::Multicast::DnsMessage929*cfb92d14SAndroid Build Coastguard Worker     void ValidateAsQueryFor(const Core::AddressResolver &aResolver) const
930*cfb92d14SAndroid Build Coastguard Worker     {
931*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
932*cfb92d14SAndroid Build Coastguard Worker 
933*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
934*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mHeader.IsTruncationFlagSet());
935*cfb92d14SAndroid Build Coastguard Worker 
936*cfb92d14SAndroid Build Coastguard Worker         fullName.Append("%s.local.", aResolver.mHostName);
937*cfb92d14SAndroid Build Coastguard Worker 
938*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(mQuestions.Contains(ResourceRecord::kTypeAaaa, fullName));
939*cfb92d14SAndroid Build Coastguard Worker     }
940*cfb92d14SAndroid Build Coastguard Worker };
941*cfb92d14SAndroid Build Coastguard Worker 
942*cfb92d14SAndroid Build Coastguard Worker struct RegCallback
943*cfb92d14SAndroid Build Coastguard Worker {
Resetot::Dns::Multicast::RegCallback944*cfb92d14SAndroid Build Coastguard Worker     void Reset(void) { mWasCalled = false; }
945*cfb92d14SAndroid Build Coastguard Worker 
946*cfb92d14SAndroid Build Coastguard Worker     bool  mWasCalled;
947*cfb92d14SAndroid Build Coastguard Worker     Error mError;
948*cfb92d14SAndroid Build Coastguard Worker };
949*cfb92d14SAndroid Build Coastguard Worker 
950*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxCallbacks = 8;
951*cfb92d14SAndroid Build Coastguard Worker 
952*cfb92d14SAndroid Build Coastguard Worker static RegCallback sRegCallbacks[kMaxCallbacks];
953*cfb92d14SAndroid Build Coastguard Worker 
HandleCallback(otInstance * aInstance,otMdnsRequestId aRequestId,otError aError)954*cfb92d14SAndroid Build Coastguard Worker static void HandleCallback(otInstance *aInstance, otMdnsRequestId aRequestId, otError aError)
955*cfb92d14SAndroid Build Coastguard Worker {
956*cfb92d14SAndroid Build Coastguard Worker     Log("Register callback - ResuestId:%u Error:%s", aRequestId, otThreadErrorToString(aError));
957*cfb92d14SAndroid Build Coastguard Worker 
958*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
959*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aRequestId < kMaxCallbacks);
960*cfb92d14SAndroid Build Coastguard Worker 
961*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sRegCallbacks[aRequestId].mWasCalled);
962*cfb92d14SAndroid Build Coastguard Worker 
963*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[aRequestId].mWasCalled = true;
964*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[aRequestId].mError     = aError;
965*cfb92d14SAndroid Build Coastguard Worker }
966*cfb92d14SAndroid Build Coastguard Worker 
HandleSuccessCallback(otInstance * aInstance,otMdnsRequestId aRequestId,otError aError)967*cfb92d14SAndroid Build Coastguard Worker static void HandleSuccessCallback(otInstance *aInstance, otMdnsRequestId aRequestId, otError aError)
968*cfb92d14SAndroid Build Coastguard Worker {
969*cfb92d14SAndroid Build Coastguard Worker     HandleCallback(aInstance, aRequestId, aError);
970*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aError);
971*cfb92d14SAndroid Build Coastguard Worker }
972*cfb92d14SAndroid Build Coastguard Worker 
973*cfb92d14SAndroid Build Coastguard Worker struct ConflictCallback
974*cfb92d14SAndroid Build Coastguard Worker {
Resetot::Dns::Multicast::ConflictCallback975*cfb92d14SAndroid Build Coastguard Worker     void Reset(void) { mWasCalled = false; }
976*cfb92d14SAndroid Build Coastguard Worker 
Handleot::Dns::Multicast::ConflictCallback977*cfb92d14SAndroid Build Coastguard Worker     void Handle(const char *aName, const char *aServiceType)
978*cfb92d14SAndroid Build Coastguard Worker     {
979*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!mWasCalled);
980*cfb92d14SAndroid Build Coastguard Worker 
981*cfb92d14SAndroid Build Coastguard Worker         mWasCalled = true;
982*cfb92d14SAndroid Build Coastguard Worker         mName.Clear();
983*cfb92d14SAndroid Build Coastguard Worker         mName.Append("%s", aName);
984*cfb92d14SAndroid Build Coastguard Worker 
985*cfb92d14SAndroid Build Coastguard Worker         mHasServiceType = (aServiceType != nullptr);
986*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(mHasServiceType);
987*cfb92d14SAndroid Build Coastguard Worker         mServiceType.Clear();
988*cfb92d14SAndroid Build Coastguard Worker         mServiceType.Append("%s", aServiceType);
989*cfb92d14SAndroid Build Coastguard Worker 
990*cfb92d14SAndroid Build Coastguard Worker     exit:
991*cfb92d14SAndroid Build Coastguard Worker         return;
992*cfb92d14SAndroid Build Coastguard Worker     }
993*cfb92d14SAndroid Build Coastguard Worker 
994*cfb92d14SAndroid Build Coastguard Worker     bool          mWasCalled;
995*cfb92d14SAndroid Build Coastguard Worker     bool          mHasServiceType;
996*cfb92d14SAndroid Build Coastguard Worker     DnsNameString mName;
997*cfb92d14SAndroid Build Coastguard Worker     DnsNameString mServiceType;
998*cfb92d14SAndroid Build Coastguard Worker };
999*cfb92d14SAndroid Build Coastguard Worker 
1000*cfb92d14SAndroid Build Coastguard Worker static ConflictCallback sConflictCallback;
1001*cfb92d14SAndroid Build Coastguard Worker 
HandleConflict(otInstance * aInstance,const char * aName,const char * aServiceType)1002*cfb92d14SAndroid Build Coastguard Worker static void HandleConflict(otInstance *aInstance, const char *aName, const char *aServiceType)
1003*cfb92d14SAndroid Build Coastguard Worker {
1004*cfb92d14SAndroid Build Coastguard Worker     Log("Conflict callback - %s %s", aName, (aServiceType == nullptr) ? "" : aServiceType);
1005*cfb92d14SAndroid Build Coastguard Worker 
1006*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
1007*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Handle(aName, aServiceType);
1008*cfb92d14SAndroid Build Coastguard Worker }
1009*cfb92d14SAndroid Build Coastguard Worker 
1010*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
1011*cfb92d14SAndroid Build Coastguard Worker // Helper functions and methods
1012*cfb92d14SAndroid Build Coastguard Worker 
RecordTypeToString(uint16_t aType)1013*cfb92d14SAndroid Build Coastguard Worker static const char *RecordTypeToString(uint16_t aType)
1014*cfb92d14SAndroid Build Coastguard Worker {
1015*cfb92d14SAndroid Build Coastguard Worker     const char *str = "Other";
1016*cfb92d14SAndroid Build Coastguard Worker 
1017*cfb92d14SAndroid Build Coastguard Worker     switch (aType)
1018*cfb92d14SAndroid Build Coastguard Worker     {
1019*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeZero:
1020*cfb92d14SAndroid Build Coastguard Worker         str = "ZERO";
1021*cfb92d14SAndroid Build Coastguard Worker         break;
1022*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeA:
1023*cfb92d14SAndroid Build Coastguard Worker         str = "A";
1024*cfb92d14SAndroid Build Coastguard Worker         break;
1025*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeSoa:
1026*cfb92d14SAndroid Build Coastguard Worker         str = "SOA";
1027*cfb92d14SAndroid Build Coastguard Worker         break;
1028*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeCname:
1029*cfb92d14SAndroid Build Coastguard Worker         str = "CNAME";
1030*cfb92d14SAndroid Build Coastguard Worker         break;
1031*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypePtr:
1032*cfb92d14SAndroid Build Coastguard Worker         str = "PTR";
1033*cfb92d14SAndroid Build Coastguard Worker         break;
1034*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeTxt:
1035*cfb92d14SAndroid Build Coastguard Worker         str = "TXT";
1036*cfb92d14SAndroid Build Coastguard Worker         break;
1037*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeSig:
1038*cfb92d14SAndroid Build Coastguard Worker         str = "SIG";
1039*cfb92d14SAndroid Build Coastguard Worker         break;
1040*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeKey:
1041*cfb92d14SAndroid Build Coastguard Worker         str = "KEY";
1042*cfb92d14SAndroid Build Coastguard Worker         break;
1043*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeAaaa:
1044*cfb92d14SAndroid Build Coastguard Worker         str = "AAAA";
1045*cfb92d14SAndroid Build Coastguard Worker         break;
1046*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeSrv:
1047*cfb92d14SAndroid Build Coastguard Worker         str = "SRV";
1048*cfb92d14SAndroid Build Coastguard Worker         break;
1049*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeOpt:
1050*cfb92d14SAndroid Build Coastguard Worker         str = "OPT";
1051*cfb92d14SAndroid Build Coastguard Worker         break;
1052*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeNsec:
1053*cfb92d14SAndroid Build Coastguard Worker         str = "NSEC";
1054*cfb92d14SAndroid Build Coastguard Worker         break;
1055*cfb92d14SAndroid Build Coastguard Worker     case ResourceRecord::kTypeAny:
1056*cfb92d14SAndroid Build Coastguard Worker         str = "ANY";
1057*cfb92d14SAndroid Build Coastguard Worker         break;
1058*cfb92d14SAndroid Build Coastguard Worker     }
1059*cfb92d14SAndroid Build Coastguard Worker 
1060*cfb92d14SAndroid Build Coastguard Worker     return str;
1061*cfb92d14SAndroid Build Coastguard Worker }
1062*cfb92d14SAndroid Build Coastguard Worker 
ParseMessage(const Message & aMessage,const Core::AddressInfo * aUnicastDest)1063*cfb92d14SAndroid Build Coastguard Worker static void ParseMessage(const Message &aMessage, const Core::AddressInfo *aUnicastDest)
1064*cfb92d14SAndroid Build Coastguard Worker {
1065*cfb92d14SAndroid Build Coastguard Worker     DnsMessage *msg = DnsMessage::Allocate();
1066*cfb92d14SAndroid Build Coastguard Worker 
1067*cfb92d14SAndroid Build Coastguard Worker     msg->ParseFrom(aMessage);
1068*cfb92d14SAndroid Build Coastguard Worker 
1069*cfb92d14SAndroid Build Coastguard Worker     switch (msg->mHeader.GetType())
1070*cfb92d14SAndroid Build Coastguard Worker     {
1071*cfb92d14SAndroid Build Coastguard Worker     case Header::kTypeQuery:
1072*cfb92d14SAndroid Build Coastguard Worker         msg->mType = kMulticastQuery;
1073*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(aUnicastDest == nullptr);
1074*cfb92d14SAndroid Build Coastguard Worker         break;
1075*cfb92d14SAndroid Build Coastguard Worker 
1076*cfb92d14SAndroid Build Coastguard Worker     case Header::kTypeResponse:
1077*cfb92d14SAndroid Build Coastguard Worker         if (aUnicastDest == nullptr)
1078*cfb92d14SAndroid Build Coastguard Worker         {
1079*cfb92d14SAndroid Build Coastguard Worker             msg->mType = kMulticastResponse;
1080*cfb92d14SAndroid Build Coastguard Worker         }
1081*cfb92d14SAndroid Build Coastguard Worker         else
1082*cfb92d14SAndroid Build Coastguard Worker         {
1083*cfb92d14SAndroid Build Coastguard Worker             msg->mType        = (aUnicastDest->mPort == kEphemeralPort) ? kLegacyUnicastResponse : kUnicastResponse;
1084*cfb92d14SAndroid Build Coastguard Worker             msg->mUnicastDest = *aUnicastDest;
1085*cfb92d14SAndroid Build Coastguard Worker         }
1086*cfb92d14SAndroid Build Coastguard Worker     }
1087*cfb92d14SAndroid Build Coastguard Worker 
1088*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.PushAfterTail(*msg);
1089*cfb92d14SAndroid Build Coastguard Worker }
1090*cfb92d14SAndroid Build Coastguard Worker 
SendQuery(const char * aName,uint16_t aRecordType,uint16_t aRecordClass=ResourceRecord::kClassInternet,bool aTruncated=false,bool aLegacyUnicastQuery=false)1091*cfb92d14SAndroid Build Coastguard Worker static void SendQuery(const char *aName,
1092*cfb92d14SAndroid Build Coastguard Worker                       uint16_t    aRecordType,
1093*cfb92d14SAndroid Build Coastguard Worker                       uint16_t    aRecordClass        = ResourceRecord::kClassInternet,
1094*cfb92d14SAndroid Build Coastguard Worker                       bool        aTruncated          = false,
1095*cfb92d14SAndroid Build Coastguard Worker                       bool        aLegacyUnicastQuery = false)
1096*cfb92d14SAndroid Build Coastguard Worker {
1097*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1098*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1099*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1100*cfb92d14SAndroid Build Coastguard Worker 
1101*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1102*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1103*cfb92d14SAndroid Build Coastguard Worker 
1104*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1105*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeQuery);
1106*cfb92d14SAndroid Build Coastguard Worker     header.SetQuestionCount(1);
1107*cfb92d14SAndroid Build Coastguard Worker 
1108*cfb92d14SAndroid Build Coastguard Worker     if (aLegacyUnicastQuery)
1109*cfb92d14SAndroid Build Coastguard Worker     {
1110*cfb92d14SAndroid Build Coastguard Worker         header.SetMessageId(kLegacyUnicastMessageId);
1111*cfb92d14SAndroid Build Coastguard Worker     }
1112*cfb92d14SAndroid Build Coastguard Worker 
1113*cfb92d14SAndroid Build Coastguard Worker     if (aTruncated)
1114*cfb92d14SAndroid Build Coastguard Worker     {
1115*cfb92d14SAndroid Build Coastguard Worker         header.SetTruncationFlag();
1116*cfb92d14SAndroid Build Coastguard Worker     }
1117*cfb92d14SAndroid Build Coastguard Worker 
1118*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1119*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName, *message));
1120*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(Question(aRecordType, aRecordClass)));
1121*cfb92d14SAndroid Build Coastguard Worker 
1122*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1123*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = aLegacyUnicastQuery ? kEphemeralPort : kMdnsPort;
1124*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1125*cfb92d14SAndroid Build Coastguard Worker 
1126*cfb92d14SAndroid Build Coastguard Worker     Log("Sending query for %s %s", aName, RecordTypeToString(aRecordType));
1127*cfb92d14SAndroid Build Coastguard Worker 
1128*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1129*cfb92d14SAndroid Build Coastguard Worker }
1130*cfb92d14SAndroid Build Coastguard Worker 
SendQueryForTwo(const char * aName1,uint16_t aRecordType1,const char * aName2,uint16_t aRecordType2,bool aIsLegacyUnicast=false)1131*cfb92d14SAndroid Build Coastguard Worker static void SendQueryForTwo(const char *aName1,
1132*cfb92d14SAndroid Build Coastguard Worker                             uint16_t    aRecordType1,
1133*cfb92d14SAndroid Build Coastguard Worker                             const char *aName2,
1134*cfb92d14SAndroid Build Coastguard Worker                             uint16_t    aRecordType2,
1135*cfb92d14SAndroid Build Coastguard Worker                             bool        aIsLegacyUnicast = false)
1136*cfb92d14SAndroid Build Coastguard Worker {
1137*cfb92d14SAndroid Build Coastguard Worker     // Send query with two questions.
1138*cfb92d14SAndroid Build Coastguard Worker 
1139*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1140*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1141*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1142*cfb92d14SAndroid Build Coastguard Worker 
1143*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1144*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1145*cfb92d14SAndroid Build Coastguard Worker 
1146*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1147*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeQuery);
1148*cfb92d14SAndroid Build Coastguard Worker     header.SetQuestionCount(2);
1149*cfb92d14SAndroid Build Coastguard Worker 
1150*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1151*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName1, *message));
1152*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(Question(aRecordType1, ResourceRecord::kClassInternet)));
1153*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName2, *message));
1154*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(Question(aRecordType2, ResourceRecord::kClassInternet)));
1155*cfb92d14SAndroid Build Coastguard Worker 
1156*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1157*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = aIsLegacyUnicast ? kEphemeralPort : kMdnsPort;
1158*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1159*cfb92d14SAndroid Build Coastguard Worker 
1160*cfb92d14SAndroid Build Coastguard Worker     Log("Sending query for %s %s and %s %s", aName1, RecordTypeToString(aRecordType1), aName2,
1161*cfb92d14SAndroid Build Coastguard Worker         RecordTypeToString(aRecordType2));
1162*cfb92d14SAndroid Build Coastguard Worker 
1163*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1164*cfb92d14SAndroid Build Coastguard Worker }
1165*cfb92d14SAndroid Build Coastguard Worker 
SendPtrResponse(const char * aName,const char * aPtrName,uint32_t aTtl,Section aSection)1166*cfb92d14SAndroid Build Coastguard Worker static void SendPtrResponse(const char *aName, const char *aPtrName, uint32_t aTtl, Section aSection)
1167*cfb92d14SAndroid Build Coastguard Worker {
1168*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1169*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1170*cfb92d14SAndroid Build Coastguard Worker     PtrRecord         ptr;
1171*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1172*cfb92d14SAndroid Build Coastguard Worker 
1173*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1174*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1175*cfb92d14SAndroid Build Coastguard Worker 
1176*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1177*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeResponse);
1178*cfb92d14SAndroid Build Coastguard Worker 
1179*cfb92d14SAndroid Build Coastguard Worker     switch (aSection)
1180*cfb92d14SAndroid Build Coastguard Worker     {
1181*cfb92d14SAndroid Build Coastguard Worker     case kInAnswerSection:
1182*cfb92d14SAndroid Build Coastguard Worker         header.SetAnswerCount(1);
1183*cfb92d14SAndroid Build Coastguard Worker         break;
1184*cfb92d14SAndroid Build Coastguard Worker     case kInAdditionalSection:
1185*cfb92d14SAndroid Build Coastguard Worker         header.SetAdditionalRecordCount(1);
1186*cfb92d14SAndroid Build Coastguard Worker         break;
1187*cfb92d14SAndroid Build Coastguard Worker     }
1188*cfb92d14SAndroid Build Coastguard Worker 
1189*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1190*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName, *message));
1191*cfb92d14SAndroid Build Coastguard Worker 
1192*cfb92d14SAndroid Build Coastguard Worker     ptr.Init();
1193*cfb92d14SAndroid Build Coastguard Worker     ptr.SetTtl(aTtl);
1194*cfb92d14SAndroid Build Coastguard Worker     ptr.SetLength(StringLength(aPtrName, Name::kMaxNameSize) + 1);
1195*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(ptr));
1196*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aPtrName, *message));
1197*cfb92d14SAndroid Build Coastguard Worker 
1198*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1199*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1200*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1201*cfb92d14SAndroid Build Coastguard Worker 
1202*cfb92d14SAndroid Build Coastguard Worker     Log("Sending PTR response for %s with %s, ttl:%lu", aName, aPtrName, ToUlong(aTtl));
1203*cfb92d14SAndroid Build Coastguard Worker 
1204*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1205*cfb92d14SAndroid Build Coastguard Worker }
1206*cfb92d14SAndroid Build Coastguard Worker 
SendSrvResponse(const char * aServiceName,const char * aHostName,uint16_t aPort,uint16_t aPriority,uint16_t aWeight,uint32_t aTtl,Section aSection)1207*cfb92d14SAndroid Build Coastguard Worker static void SendSrvResponse(const char *aServiceName,
1208*cfb92d14SAndroid Build Coastguard Worker                             const char *aHostName,
1209*cfb92d14SAndroid Build Coastguard Worker                             uint16_t    aPort,
1210*cfb92d14SAndroid Build Coastguard Worker                             uint16_t    aPriority,
1211*cfb92d14SAndroid Build Coastguard Worker                             uint16_t    aWeight,
1212*cfb92d14SAndroid Build Coastguard Worker                             uint32_t    aTtl,
1213*cfb92d14SAndroid Build Coastguard Worker                             Section     aSection)
1214*cfb92d14SAndroid Build Coastguard Worker {
1215*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1216*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1217*cfb92d14SAndroid Build Coastguard Worker     SrvRecord         srv;
1218*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1219*cfb92d14SAndroid Build Coastguard Worker 
1220*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1221*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1222*cfb92d14SAndroid Build Coastguard Worker 
1223*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1224*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeResponse);
1225*cfb92d14SAndroid Build Coastguard Worker 
1226*cfb92d14SAndroid Build Coastguard Worker     switch (aSection)
1227*cfb92d14SAndroid Build Coastguard Worker     {
1228*cfb92d14SAndroid Build Coastguard Worker     case kInAnswerSection:
1229*cfb92d14SAndroid Build Coastguard Worker         header.SetAnswerCount(1);
1230*cfb92d14SAndroid Build Coastguard Worker         break;
1231*cfb92d14SAndroid Build Coastguard Worker     case kInAdditionalSection:
1232*cfb92d14SAndroid Build Coastguard Worker         header.SetAdditionalRecordCount(1);
1233*cfb92d14SAndroid Build Coastguard Worker         break;
1234*cfb92d14SAndroid Build Coastguard Worker     }
1235*cfb92d14SAndroid Build Coastguard Worker 
1236*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1237*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aServiceName, *message));
1238*cfb92d14SAndroid Build Coastguard Worker 
1239*cfb92d14SAndroid Build Coastguard Worker     srv.Init();
1240*cfb92d14SAndroid Build Coastguard Worker     srv.SetTtl(aTtl);
1241*cfb92d14SAndroid Build Coastguard Worker     srv.SetPort(aPort);
1242*cfb92d14SAndroid Build Coastguard Worker     srv.SetPriority(aPriority);
1243*cfb92d14SAndroid Build Coastguard Worker     srv.SetWeight(aWeight);
1244*cfb92d14SAndroid Build Coastguard Worker     srv.SetLength(sizeof(srv) - sizeof(ResourceRecord) + StringLength(aHostName, Name::kMaxNameSize) + 1);
1245*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(srv));
1246*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aHostName, *message));
1247*cfb92d14SAndroid Build Coastguard Worker 
1248*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1249*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1250*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1251*cfb92d14SAndroid Build Coastguard Worker 
1252*cfb92d14SAndroid Build Coastguard Worker     Log("Sending SRV response for %s, host:%s, port:%u, ttl:%lu", aServiceName, aHostName, aPort, ToUlong(aTtl));
1253*cfb92d14SAndroid Build Coastguard Worker 
1254*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1255*cfb92d14SAndroid Build Coastguard Worker }
1256*cfb92d14SAndroid Build Coastguard Worker 
SendTxtResponse(const char * aServiceName,const uint8_t * aTxtData,uint16_t aTxtDataLength,uint32_t aTtl,Section aSection)1257*cfb92d14SAndroid Build Coastguard Worker static void SendTxtResponse(const char    *aServiceName,
1258*cfb92d14SAndroid Build Coastguard Worker                             const uint8_t *aTxtData,
1259*cfb92d14SAndroid Build Coastguard Worker                             uint16_t       aTxtDataLength,
1260*cfb92d14SAndroid Build Coastguard Worker                             uint32_t       aTtl,
1261*cfb92d14SAndroid Build Coastguard Worker                             Section        aSection)
1262*cfb92d14SAndroid Build Coastguard Worker {
1263*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1264*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1265*cfb92d14SAndroid Build Coastguard Worker     TxtRecord         txt;
1266*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1267*cfb92d14SAndroid Build Coastguard Worker 
1268*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1269*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1270*cfb92d14SAndroid Build Coastguard Worker 
1271*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1272*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeResponse);
1273*cfb92d14SAndroid Build Coastguard Worker 
1274*cfb92d14SAndroid Build Coastguard Worker     switch (aSection)
1275*cfb92d14SAndroid Build Coastguard Worker     {
1276*cfb92d14SAndroid Build Coastguard Worker     case kInAnswerSection:
1277*cfb92d14SAndroid Build Coastguard Worker         header.SetAnswerCount(1);
1278*cfb92d14SAndroid Build Coastguard Worker         break;
1279*cfb92d14SAndroid Build Coastguard Worker     case kInAdditionalSection:
1280*cfb92d14SAndroid Build Coastguard Worker         header.SetAdditionalRecordCount(1);
1281*cfb92d14SAndroid Build Coastguard Worker         break;
1282*cfb92d14SAndroid Build Coastguard Worker     }
1283*cfb92d14SAndroid Build Coastguard Worker 
1284*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1285*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aServiceName, *message));
1286*cfb92d14SAndroid Build Coastguard Worker 
1287*cfb92d14SAndroid Build Coastguard Worker     txt.Init();
1288*cfb92d14SAndroid Build Coastguard Worker     txt.SetTtl(aTtl);
1289*cfb92d14SAndroid Build Coastguard Worker     txt.SetLength(aTxtDataLength);
1290*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(txt));
1291*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->AppendBytes(aTxtData, aTxtDataLength));
1292*cfb92d14SAndroid Build Coastguard Worker 
1293*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1294*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1295*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1296*cfb92d14SAndroid Build Coastguard Worker 
1297*cfb92d14SAndroid Build Coastguard Worker     Log("Sending TXT response for %s, len:%u, ttl:%lu", aServiceName, aTxtDataLength, ToUlong(aTtl));
1298*cfb92d14SAndroid Build Coastguard Worker 
1299*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1300*cfb92d14SAndroid Build Coastguard Worker }
1301*cfb92d14SAndroid Build Coastguard Worker 
SendHostAddrResponse(const char * aHostName,AddrAndTtl * aAddrAndTtls,uint32_t aNumAddrs,bool aCacheFlush,Section aSection)1302*cfb92d14SAndroid Build Coastguard Worker static void SendHostAddrResponse(const char *aHostName,
1303*cfb92d14SAndroid Build Coastguard Worker                                  AddrAndTtl *aAddrAndTtls,
1304*cfb92d14SAndroid Build Coastguard Worker                                  uint32_t    aNumAddrs,
1305*cfb92d14SAndroid Build Coastguard Worker                                  bool        aCacheFlush,
1306*cfb92d14SAndroid Build Coastguard Worker                                  Section     aSection)
1307*cfb92d14SAndroid Build Coastguard Worker {
1308*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1309*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1310*cfb92d14SAndroid Build Coastguard Worker     AaaaRecord        record;
1311*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1312*cfb92d14SAndroid Build Coastguard Worker 
1313*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1314*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1315*cfb92d14SAndroid Build Coastguard Worker 
1316*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1317*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeResponse);
1318*cfb92d14SAndroid Build Coastguard Worker 
1319*cfb92d14SAndroid Build Coastguard Worker     switch (aSection)
1320*cfb92d14SAndroid Build Coastguard Worker     {
1321*cfb92d14SAndroid Build Coastguard Worker     case kInAnswerSection:
1322*cfb92d14SAndroid Build Coastguard Worker         header.SetAnswerCount(aNumAddrs);
1323*cfb92d14SAndroid Build Coastguard Worker         break;
1324*cfb92d14SAndroid Build Coastguard Worker     case kInAdditionalSection:
1325*cfb92d14SAndroid Build Coastguard Worker         header.SetAdditionalRecordCount(aNumAddrs);
1326*cfb92d14SAndroid Build Coastguard Worker         break;
1327*cfb92d14SAndroid Build Coastguard Worker     }
1328*cfb92d14SAndroid Build Coastguard Worker 
1329*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1330*cfb92d14SAndroid Build Coastguard Worker 
1331*cfb92d14SAndroid Build Coastguard Worker     record.Init();
1332*cfb92d14SAndroid Build Coastguard Worker 
1333*cfb92d14SAndroid Build Coastguard Worker     if (aCacheFlush)
1334*cfb92d14SAndroid Build Coastguard Worker     {
1335*cfb92d14SAndroid Build Coastguard Worker         record.SetClass(record.GetClass() | kClassCacheFlushFlag);
1336*cfb92d14SAndroid Build Coastguard Worker     }
1337*cfb92d14SAndroid Build Coastguard Worker 
1338*cfb92d14SAndroid Build Coastguard Worker     Log("Sending AAAA response for %s numAddrs:%u, cach-flush:%u", aHostName, aNumAddrs, aCacheFlush);
1339*cfb92d14SAndroid Build Coastguard Worker 
1340*cfb92d14SAndroid Build Coastguard Worker     for (uint32_t index = 0; index < aNumAddrs; index++)
1341*cfb92d14SAndroid Build Coastguard Worker     {
1342*cfb92d14SAndroid Build Coastguard Worker         record.SetTtl(aAddrAndTtls[index].mTtl);
1343*cfb92d14SAndroid Build Coastguard Worker         record.SetAddress(aAddrAndTtls[index].mAddress);
1344*cfb92d14SAndroid Build Coastguard Worker 
1345*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Name::AppendName(aHostName, *message));
1346*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(message->Append(record));
1347*cfb92d14SAndroid Build Coastguard Worker 
1348*cfb92d14SAndroid Build Coastguard Worker         Log(" - %s, ttl:%lu", aAddrAndTtls[index].mAddress.ToString().AsCString(), ToUlong(aAddrAndTtls[index].mTtl));
1349*cfb92d14SAndroid Build Coastguard Worker     }
1350*cfb92d14SAndroid Build Coastguard Worker 
1351*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1352*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1353*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1354*cfb92d14SAndroid Build Coastguard Worker 
1355*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1356*cfb92d14SAndroid Build Coastguard Worker }
1357*cfb92d14SAndroid Build Coastguard Worker 
SendResponseWithEmptyKey(const char * aName,Section aSection)1358*cfb92d14SAndroid Build Coastguard Worker static void SendResponseWithEmptyKey(const char *aName, Section aSection)
1359*cfb92d14SAndroid Build Coastguard Worker {
1360*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1361*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1362*cfb92d14SAndroid Build Coastguard Worker     ResourceRecord    record;
1363*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1364*cfb92d14SAndroid Build Coastguard Worker 
1365*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1366*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1367*cfb92d14SAndroid Build Coastguard Worker 
1368*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1369*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeResponse);
1370*cfb92d14SAndroid Build Coastguard Worker 
1371*cfb92d14SAndroid Build Coastguard Worker     switch (aSection)
1372*cfb92d14SAndroid Build Coastguard Worker     {
1373*cfb92d14SAndroid Build Coastguard Worker     case kInAnswerSection:
1374*cfb92d14SAndroid Build Coastguard Worker         header.SetAnswerCount(1);
1375*cfb92d14SAndroid Build Coastguard Worker         break;
1376*cfb92d14SAndroid Build Coastguard Worker     case kInAdditionalSection:
1377*cfb92d14SAndroid Build Coastguard Worker         header.SetAdditionalRecordCount(1);
1378*cfb92d14SAndroid Build Coastguard Worker         break;
1379*cfb92d14SAndroid Build Coastguard Worker     }
1380*cfb92d14SAndroid Build Coastguard Worker 
1381*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1382*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName, *message));
1383*cfb92d14SAndroid Build Coastguard Worker 
1384*cfb92d14SAndroid Build Coastguard Worker     record.Init(ResourceRecord::kTypeKey);
1385*cfb92d14SAndroid Build Coastguard Worker     record.SetTtl(4500);
1386*cfb92d14SAndroid Build Coastguard Worker     record.SetLength(0);
1387*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(record));
1388*cfb92d14SAndroid Build Coastguard Worker 
1389*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1390*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1391*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1392*cfb92d14SAndroid Build Coastguard Worker 
1393*cfb92d14SAndroid Build Coastguard Worker     Log("Sending response with empty key for %s", aName);
1394*cfb92d14SAndroid Build Coastguard Worker 
1395*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1396*cfb92d14SAndroid Build Coastguard Worker }
1397*cfb92d14SAndroid Build Coastguard Worker 
1398*cfb92d14SAndroid Build Coastguard Worker struct KnownAnswer
1399*cfb92d14SAndroid Build Coastguard Worker {
1400*cfb92d14SAndroid Build Coastguard Worker     const char *mPtrAnswer;
1401*cfb92d14SAndroid Build Coastguard Worker     uint32_t    mTtl;
1402*cfb92d14SAndroid Build Coastguard Worker };
1403*cfb92d14SAndroid Build Coastguard Worker 
SendPtrQueryWithKnownAnswers(const char * aName,const KnownAnswer * aKnownAnswers,uint16_t aNumAnswers)1404*cfb92d14SAndroid Build Coastguard Worker static void SendPtrQueryWithKnownAnswers(const char *aName, const KnownAnswer *aKnownAnswers, uint16_t aNumAnswers)
1405*cfb92d14SAndroid Build Coastguard Worker {
1406*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1407*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1408*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1409*cfb92d14SAndroid Build Coastguard Worker     uint16_t          nameOffset;
1410*cfb92d14SAndroid Build Coastguard Worker 
1411*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1412*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1413*cfb92d14SAndroid Build Coastguard Worker 
1414*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1415*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeQuery);
1416*cfb92d14SAndroid Build Coastguard Worker     header.SetQuestionCount(1);
1417*cfb92d14SAndroid Build Coastguard Worker     header.SetAnswerCount(aNumAnswers);
1418*cfb92d14SAndroid Build Coastguard Worker 
1419*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1420*cfb92d14SAndroid Build Coastguard Worker     nameOffset = message->GetLength();
1421*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(Name::AppendName(aName, *message));
1422*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(Question(ResourceRecord::kTypePtr, ResourceRecord::kClassInternet)));
1423*cfb92d14SAndroid Build Coastguard Worker 
1424*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0; index < aNumAnswers; index++)
1425*cfb92d14SAndroid Build Coastguard Worker     {
1426*cfb92d14SAndroid Build Coastguard Worker         PtrRecord ptr;
1427*cfb92d14SAndroid Build Coastguard Worker 
1428*cfb92d14SAndroid Build Coastguard Worker         ptr.Init();
1429*cfb92d14SAndroid Build Coastguard Worker         ptr.SetTtl(aKnownAnswers[index].mTtl);
1430*cfb92d14SAndroid Build Coastguard Worker         ptr.SetLength(StringLength(aKnownAnswers[index].mPtrAnswer, Name::kMaxNameSize) + 1);
1431*cfb92d14SAndroid Build Coastguard Worker 
1432*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Name::AppendPointerLabel(nameOffset, *message));
1433*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(message->Append(ptr));
1434*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Name::AppendName(aKnownAnswers[index].mPtrAnswer, *message));
1435*cfb92d14SAndroid Build Coastguard Worker     }
1436*cfb92d14SAndroid Build Coastguard Worker 
1437*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1438*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1439*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1440*cfb92d14SAndroid Build Coastguard Worker 
1441*cfb92d14SAndroid Build Coastguard Worker     Log("Sending query for %s PTR with %u known-answers", aName, aNumAnswers);
1442*cfb92d14SAndroid Build Coastguard Worker 
1443*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1444*cfb92d14SAndroid Build Coastguard Worker }
1445*cfb92d14SAndroid Build Coastguard Worker 
SendEmtryPtrQueryWithKnownAnswers(const char * aName,const KnownAnswer * aKnownAnswers,uint16_t aNumAnswers)1446*cfb92d14SAndroid Build Coastguard Worker static void SendEmtryPtrQueryWithKnownAnswers(const char *aName, const KnownAnswer *aKnownAnswers, uint16_t aNumAnswers)
1447*cfb92d14SAndroid Build Coastguard Worker {
1448*cfb92d14SAndroid Build Coastguard Worker     Message          *message;
1449*cfb92d14SAndroid Build Coastguard Worker     Header            header;
1450*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1451*cfb92d14SAndroid Build Coastguard Worker     uint16_t          nameOffset = 0;
1452*cfb92d14SAndroid Build Coastguard Worker 
1453*cfb92d14SAndroid Build Coastguard Worker     message = sInstance->Get<MessagePool>().Allocate(Message::kTypeOther);
1454*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr);
1455*cfb92d14SAndroid Build Coastguard Worker 
1456*cfb92d14SAndroid Build Coastguard Worker     header.Clear();
1457*cfb92d14SAndroid Build Coastguard Worker     header.SetType(Header::kTypeQuery);
1458*cfb92d14SAndroid Build Coastguard Worker     header.SetAnswerCount(aNumAnswers);
1459*cfb92d14SAndroid Build Coastguard Worker 
1460*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->Append(header));
1461*cfb92d14SAndroid Build Coastguard Worker 
1462*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0; index < aNumAnswers; index++)
1463*cfb92d14SAndroid Build Coastguard Worker     {
1464*cfb92d14SAndroid Build Coastguard Worker         PtrRecord ptr;
1465*cfb92d14SAndroid Build Coastguard Worker 
1466*cfb92d14SAndroid Build Coastguard Worker         ptr.Init();
1467*cfb92d14SAndroid Build Coastguard Worker         ptr.SetTtl(aKnownAnswers[index].mTtl);
1468*cfb92d14SAndroid Build Coastguard Worker         ptr.SetLength(StringLength(aKnownAnswers[index].mPtrAnswer, Name::kMaxNameSize) + 1);
1469*cfb92d14SAndroid Build Coastguard Worker 
1470*cfb92d14SAndroid Build Coastguard Worker         if (nameOffset == 0)
1471*cfb92d14SAndroid Build Coastguard Worker         {
1472*cfb92d14SAndroid Build Coastguard Worker             nameOffset = message->GetLength();
1473*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(Name::AppendName(aName, *message));
1474*cfb92d14SAndroid Build Coastguard Worker         }
1475*cfb92d14SAndroid Build Coastguard Worker         else
1476*cfb92d14SAndroid Build Coastguard Worker         {
1477*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(Name::AppendPointerLabel(nameOffset, *message));
1478*cfb92d14SAndroid Build Coastguard Worker         }
1479*cfb92d14SAndroid Build Coastguard Worker 
1480*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(message->Append(ptr));
1481*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Name::AppendName(aKnownAnswers[index].mPtrAnswer, *message));
1482*cfb92d14SAndroid Build Coastguard Worker     }
1483*cfb92d14SAndroid Build Coastguard Worker 
1484*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1485*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1486*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1487*cfb92d14SAndroid Build Coastguard Worker 
1488*cfb92d14SAndroid Build Coastguard Worker     Log("Sending empty query with %u known-answers for %s", aNumAnswers, aName);
1489*cfb92d14SAndroid Build Coastguard Worker 
1490*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
1491*cfb92d14SAndroid Build Coastguard Worker }
1492*cfb92d14SAndroid Build Coastguard Worker 
1493*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1494*cfb92d14SAndroid Build Coastguard Worker // `otPlatLog`
1495*cfb92d14SAndroid Build Coastguard Worker 
1496*cfb92d14SAndroid Build Coastguard Worker extern "C" {
1497*cfb92d14SAndroid Build Coastguard Worker 
1498*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)1499*cfb92d14SAndroid Build Coastguard Worker void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
1500*cfb92d14SAndroid Build Coastguard Worker {
1501*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aLogLevel);
1502*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aLogRegion);
1503*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aFormat);
1504*cfb92d14SAndroid Build Coastguard Worker 
1505*cfb92d14SAndroid Build Coastguard Worker #if ENABLE_TEST_LOG
1506*cfb92d14SAndroid Build Coastguard Worker     va_list args;
1507*cfb92d14SAndroid Build Coastguard Worker 
1508*cfb92d14SAndroid Build Coastguard Worker     printf("   ");
1509*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
1510*cfb92d14SAndroid Build Coastguard Worker     vprintf(aFormat, args);
1511*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
1512*cfb92d14SAndroid Build Coastguard Worker 
1513*cfb92d14SAndroid Build Coastguard Worker     printf("\n");
1514*cfb92d14SAndroid Build Coastguard Worker #endif
1515*cfb92d14SAndroid Build Coastguard Worker }
1516*cfb92d14SAndroid Build Coastguard Worker 
1517*cfb92d14SAndroid Build Coastguard Worker #endif
1518*cfb92d14SAndroid Build Coastguard Worker 
1519*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1520*cfb92d14SAndroid Build Coastguard Worker // `otPlatAlarm`
1521*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStop(otInstance *)1522*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStop(otInstance *) { sAlarmOn = false; }
1523*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliStartAt(otInstance *,uint32_t aT0,uint32_t aDt)1524*cfb92d14SAndroid Build Coastguard Worker void otPlatAlarmMilliStartAt(otInstance *, uint32_t aT0, uint32_t aDt)
1525*cfb92d14SAndroid Build Coastguard Worker {
1526*cfb92d14SAndroid Build Coastguard Worker     sAlarmOn   = true;
1527*cfb92d14SAndroid Build Coastguard Worker     sAlarmTime = aT0 + aDt;
1528*cfb92d14SAndroid Build Coastguard Worker }
1529*cfb92d14SAndroid Build Coastguard Worker 
otPlatAlarmMilliGetNow(void)1530*cfb92d14SAndroid Build Coastguard Worker uint32_t otPlatAlarmMilliGetNow(void) { return sNow; }
1531*cfb92d14SAndroid Build Coastguard Worker 
1532*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1533*cfb92d14SAndroid Build Coastguard Worker // Heap allocation
1534*cfb92d14SAndroid Build Coastguard Worker 
1535*cfb92d14SAndroid Build Coastguard Worker Array<void *, 500> sHeapAllocatedPtrs;
1536*cfb92d14SAndroid Build Coastguard Worker 
1537*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
1538*cfb92d14SAndroid Build Coastguard Worker 
otPlatCAlloc(size_t aNum,size_t aSize)1539*cfb92d14SAndroid Build Coastguard Worker void *otPlatCAlloc(size_t aNum, size_t aSize)
1540*cfb92d14SAndroid Build Coastguard Worker {
1541*cfb92d14SAndroid Build Coastguard Worker     void *ptr = calloc(aNum, aSize);
1542*cfb92d14SAndroid Build Coastguard Worker 
1543*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(sHeapAllocatedPtrs.PushBack(ptr));
1544*cfb92d14SAndroid Build Coastguard Worker 
1545*cfb92d14SAndroid Build Coastguard Worker     return ptr;
1546*cfb92d14SAndroid Build Coastguard Worker }
1547*cfb92d14SAndroid Build Coastguard Worker 
otPlatFree(void * aPtr)1548*cfb92d14SAndroid Build Coastguard Worker void otPlatFree(void *aPtr)
1549*cfb92d14SAndroid Build Coastguard Worker {
1550*cfb92d14SAndroid Build Coastguard Worker     if (aPtr != nullptr)
1551*cfb92d14SAndroid Build Coastguard Worker     {
1552*cfb92d14SAndroid Build Coastguard Worker         void **entry = sHeapAllocatedPtrs.Find(aPtr);
1553*cfb92d14SAndroid Build Coastguard Worker 
1554*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(entry != nullptr, "A heap allocated item is freed twice");
1555*cfb92d14SAndroid Build Coastguard Worker         sHeapAllocatedPtrs.Remove(*entry);
1556*cfb92d14SAndroid Build Coastguard Worker     }
1557*cfb92d14SAndroid Build Coastguard Worker 
1558*cfb92d14SAndroid Build Coastguard Worker     free(aPtr);
1559*cfb92d14SAndroid Build Coastguard Worker }
1560*cfb92d14SAndroid Build Coastguard Worker 
1561*cfb92d14SAndroid Build Coastguard Worker #endif
1562*cfb92d14SAndroid Build Coastguard Worker 
1563*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1564*cfb92d14SAndroid Build Coastguard Worker // `otPlatMdns`
1565*cfb92d14SAndroid Build Coastguard Worker 
otPlatMdnsSetListeningEnabled(otInstance * aInstance,bool aEnable,uint32_t aInfraIfIndex)1566*cfb92d14SAndroid Build Coastguard Worker otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
1567*cfb92d14SAndroid Build Coastguard Worker {
1568*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
1569*cfb92d14SAndroid Build Coastguard Worker     sInfraIfIndex = aInfraIfIndex;
1570*cfb92d14SAndroid Build Coastguard Worker 
1571*cfb92d14SAndroid Build Coastguard Worker     Log("otPlatMdnsSetListeningEnabled(%s)", aEnable ? "true" : "false");
1572*cfb92d14SAndroid Build Coastguard Worker 
1573*cfb92d14SAndroid Build Coastguard Worker     return kErrorNone;
1574*cfb92d14SAndroid Build Coastguard Worker }
1575*cfb92d14SAndroid Build Coastguard Worker 
otPlatMdnsSendMulticast(otInstance * aInstance,otMessage * aMessage,uint32_t aInfraIfIndex)1576*cfb92d14SAndroid Build Coastguard Worker void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
1577*cfb92d14SAndroid Build Coastguard Worker {
1578*cfb92d14SAndroid Build Coastguard Worker     Message          &message = AsCoreType(aMessage);
1579*cfb92d14SAndroid Build Coastguard Worker     Core::AddressInfo senderAddrInfo;
1580*cfb92d14SAndroid Build Coastguard Worker 
1581*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInfraIfIndex == sInfraIfIndex);
1582*cfb92d14SAndroid Build Coastguard Worker 
1583*cfb92d14SAndroid Build Coastguard Worker     Log("otPlatMdnsSendMulticast(msg-len:%u)", message.GetLength());
1584*cfb92d14SAndroid Build Coastguard Worker     ParseMessage(message, nullptr);
1585*cfb92d14SAndroid Build Coastguard Worker 
1586*cfb92d14SAndroid Build Coastguard Worker     // Pass the multicast message back.
1587*cfb92d14SAndroid Build Coastguard Worker 
1588*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1589*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mPort         = kMdnsPort;
1590*cfb92d14SAndroid Build Coastguard Worker     senderAddrInfo.mInfraIfIndex = 0;
1591*cfb92d14SAndroid Build Coastguard Worker 
1592*cfb92d14SAndroid Build Coastguard Worker     otPlatMdnsHandleReceive(sInstance, aMessage, /* aIsUnicast */ false, &senderAddrInfo);
1593*cfb92d14SAndroid Build Coastguard Worker }
1594*cfb92d14SAndroid Build Coastguard Worker 
otPlatMdnsSendUnicast(otInstance * aInstance,otMessage * aMessage,const otPlatMdnsAddressInfo * aAddress)1595*cfb92d14SAndroid Build Coastguard Worker void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
1596*cfb92d14SAndroid Build Coastguard Worker {
1597*cfb92d14SAndroid Build Coastguard Worker     Message                 &message = AsCoreType(aMessage);
1598*cfb92d14SAndroid Build Coastguard Worker     const Core::AddressInfo &address = AsCoreType(aAddress);
1599*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address             deviceAddress;
1600*cfb92d14SAndroid Build Coastguard Worker 
1601*cfb92d14SAndroid Build Coastguard Worker     Log("otPlatMdnsSendUnicast() - [%s]:%u", address.GetAddress().ToString().AsCString(), address.mPort);
1602*cfb92d14SAndroid Build Coastguard Worker     ParseMessage(message, AsCoreTypePtr(aAddress));
1603*cfb92d14SAndroid Build Coastguard Worker 
1604*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(deviceAddress.FromString(kDeviceIp6Address));
1605*cfb92d14SAndroid Build Coastguard Worker 
1606*cfb92d14SAndroid Build Coastguard Worker     if ((address.GetAddress() == deviceAddress) && (address.mPort == kMdnsPort))
1607*cfb92d14SAndroid Build Coastguard Worker     {
1608*cfb92d14SAndroid Build Coastguard Worker         Core::AddressInfo senderAddrInfo;
1609*cfb92d14SAndroid Build Coastguard Worker 
1610*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
1611*cfb92d14SAndroid Build Coastguard Worker         senderAddrInfo.mPort         = kMdnsPort;
1612*cfb92d14SAndroid Build Coastguard Worker         senderAddrInfo.mInfraIfIndex = 0;
1613*cfb92d14SAndroid Build Coastguard Worker 
1614*cfb92d14SAndroid Build Coastguard Worker         Log("otPlatMdnsSendUnicast() - unicast msg matches this device address, passing it back");
1615*cfb92d14SAndroid Build Coastguard Worker         otPlatMdnsHandleReceive(sInstance, &message, /* aIsUnicast */ true, &senderAddrInfo);
1616*cfb92d14SAndroid Build Coastguard Worker     }
1617*cfb92d14SAndroid Build Coastguard Worker     else
1618*cfb92d14SAndroid Build Coastguard Worker     {
1619*cfb92d14SAndroid Build Coastguard Worker         message.Free();
1620*cfb92d14SAndroid Build Coastguard Worker     }
1621*cfb92d14SAndroid Build Coastguard Worker }
1622*cfb92d14SAndroid Build Coastguard Worker 
1623*cfb92d14SAndroid Build Coastguard Worker } // extern "C"
1624*cfb92d14SAndroid Build Coastguard Worker 
1625*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
1626*cfb92d14SAndroid Build Coastguard Worker 
ProcessTasklets(void)1627*cfb92d14SAndroid Build Coastguard Worker void ProcessTasklets(void)
1628*cfb92d14SAndroid Build Coastguard Worker {
1629*cfb92d14SAndroid Build Coastguard Worker     while (otTaskletsArePending(sInstance))
1630*cfb92d14SAndroid Build Coastguard Worker     {
1631*cfb92d14SAndroid Build Coastguard Worker         otTaskletsProcess(sInstance);
1632*cfb92d14SAndroid Build Coastguard Worker     }
1633*cfb92d14SAndroid Build Coastguard Worker }
1634*cfb92d14SAndroid Build Coastguard Worker 
AdvanceTime(uint32_t aDuration)1635*cfb92d14SAndroid Build Coastguard Worker void AdvanceTime(uint32_t aDuration)
1636*cfb92d14SAndroid Build Coastguard Worker {
1637*cfb92d14SAndroid Build Coastguard Worker     uint32_t time = sNow + aDuration;
1638*cfb92d14SAndroid Build Coastguard Worker 
1639*cfb92d14SAndroid Build Coastguard Worker     Log("AdvanceTime for %u.%03u", aDuration / 1000, aDuration % 1000);
1640*cfb92d14SAndroid Build Coastguard Worker 
1641*cfb92d14SAndroid Build Coastguard Worker     while (TimeMilli(sAlarmTime) <= TimeMilli(time))
1642*cfb92d14SAndroid Build Coastguard Worker     {
1643*cfb92d14SAndroid Build Coastguard Worker         ProcessTasklets();
1644*cfb92d14SAndroid Build Coastguard Worker         sNow = sAlarmTime;
1645*cfb92d14SAndroid Build Coastguard Worker         otPlatAlarmMilliFired(sInstance);
1646*cfb92d14SAndroid Build Coastguard Worker     }
1647*cfb92d14SAndroid Build Coastguard Worker 
1648*cfb92d14SAndroid Build Coastguard Worker     ProcessTasklets();
1649*cfb92d14SAndroid Build Coastguard Worker     sNow = time;
1650*cfb92d14SAndroid Build Coastguard Worker }
1651*cfb92d14SAndroid Build Coastguard Worker 
InitTest(void)1652*cfb92d14SAndroid Build Coastguard Worker Core *InitTest(void)
1653*cfb92d14SAndroid Build Coastguard Worker {
1654*cfb92d14SAndroid Build Coastguard Worker     sNow     = 0;
1655*cfb92d14SAndroid Build Coastguard Worker     sAlarmOn = false;
1656*cfb92d14SAndroid Build Coastguard Worker 
1657*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1658*cfb92d14SAndroid Build Coastguard Worker 
1659*cfb92d14SAndroid Build Coastguard Worker     for (RegCallback &regCallbck : sRegCallbacks)
1660*cfb92d14SAndroid Build Coastguard Worker     {
1661*cfb92d14SAndroid Build Coastguard Worker         regCallbck.Reset();
1662*cfb92d14SAndroid Build Coastguard Worker     }
1663*cfb92d14SAndroid Build Coastguard Worker 
1664*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
1665*cfb92d14SAndroid Build Coastguard Worker 
1666*cfb92d14SAndroid Build Coastguard Worker     sInstance = testInitInstance();
1667*cfb92d14SAndroid Build Coastguard Worker 
1668*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sInstance != nullptr);
1669*cfb92d14SAndroid Build Coastguard Worker 
1670*cfb92d14SAndroid Build Coastguard Worker     return &sInstance->Get<Core>();
1671*cfb92d14SAndroid Build Coastguard Worker }
1672*cfb92d14SAndroid Build Coastguard Worker 
1673*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
1674*cfb92d14SAndroid Build Coastguard Worker 
1675*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kKey1[]         = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
1676*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kKey2[]         = {0x12, 0x34, 0x56};
1677*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kTxtData1[]     = {3, 'a', '=', '1', 0};
1678*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kTxtData2[]     = {1, 'b', 0};
1679*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kEmptyTxtData[] = {0};
1680*cfb92d14SAndroid Build Coastguard Worker 
1681*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
1682*cfb92d14SAndroid Build Coastguard Worker 
TestHostReg(void)1683*cfb92d14SAndroid Build Coastguard Worker void TestHostReg(void)
1684*cfb92d14SAndroid Build Coastguard Worker {
1685*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
1686*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
1687*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[3];
1688*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
1689*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
1690*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     hostFullName;
1691*cfb92d14SAndroid Build Coastguard Worker 
1692*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
1693*cfb92d14SAndroid Build Coastguard Worker     Log("TestHostReg");
1694*cfb92d14SAndroid Build Coastguard Worker 
1695*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
1696*cfb92d14SAndroid Build Coastguard Worker 
1697*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
1698*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
1699*cfb92d14SAndroid Build Coastguard Worker 
1700*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::aaaa"));
1701*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::bbbb"));
1702*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[2].FromString("fd00::cccc"));
1703*cfb92d14SAndroid Build Coastguard Worker 
1704*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
1705*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
1706*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 3;
1707*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
1708*cfb92d14SAndroid Build Coastguard Worker 
1709*cfb92d14SAndroid Build Coastguard Worker     hostFullName.Append("%s.local.", host.mHostName);
1710*cfb92d14SAndroid Build Coastguard Worker 
1711*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1712*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `HostEntry`, check probes and announcements");
1713*cfb92d14SAndroid Build Coastguard Worker 
1714*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1715*cfb92d14SAndroid Build Coastguard Worker 
1716*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
1717*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
1718*cfb92d14SAndroid Build Coastguard Worker 
1719*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
1720*cfb92d14SAndroid Build Coastguard Worker     {
1721*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1722*cfb92d14SAndroid Build Coastguard Worker 
1723*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
1724*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
1725*cfb92d14SAndroid Build Coastguard Worker 
1726*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1727*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1728*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 3, /* Addnl */ 0);
1729*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ (probeCount == 0));
1730*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1731*cfb92d14SAndroid Build Coastguard Worker     }
1732*cfb92d14SAndroid Build Coastguard Worker 
1733*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1734*cfb92d14SAndroid Build Coastguard Worker     {
1735*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1736*cfb92d14SAndroid Build Coastguard Worker 
1737*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
1738*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
1739*cfb92d14SAndroid Build Coastguard Worker 
1740*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1741*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1742*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
1743*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
1744*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1745*cfb92d14SAndroid Build Coastguard Worker     }
1746*cfb92d14SAndroid Build Coastguard Worker 
1747*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1748*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for AAAA record and validate the response");
1749*cfb92d14SAndroid Build Coastguard Worker 
1750*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1751*cfb92d14SAndroid Build Coastguard Worker 
1752*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1753*cfb92d14SAndroid Build Coastguard Worker     SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeAaaa);
1754*cfb92d14SAndroid Build Coastguard Worker 
1755*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
1756*cfb92d14SAndroid Build Coastguard Worker 
1757*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
1758*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
1759*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
1760*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAnswerSection);
1761*cfb92d14SAndroid Build Coastguard Worker 
1762*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1763*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for ANY record and validate the response");
1764*cfb92d14SAndroid Build Coastguard Worker 
1765*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1766*cfb92d14SAndroid Build Coastguard Worker 
1767*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1768*cfb92d14SAndroid Build Coastguard Worker     SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeAny);
1769*cfb92d14SAndroid Build Coastguard Worker 
1770*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
1771*cfb92d14SAndroid Build Coastguard Worker 
1772*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
1773*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
1774*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
1775*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAnswerSection);
1776*cfb92d14SAndroid Build Coastguard Worker 
1777*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1778*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for non-existing record and validate the response with NSEC");
1779*cfb92d14SAndroid Build Coastguard Worker 
1780*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1781*cfb92d14SAndroid Build Coastguard Worker 
1782*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1783*cfb92d14SAndroid Build Coastguard Worker     SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeA);
1784*cfb92d14SAndroid Build Coastguard Worker 
1785*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
1786*cfb92d14SAndroid Build Coastguard Worker 
1787*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
1788*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
1789*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 1);
1790*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->mAdditionalRecords.ContainsNsec(hostFullName, ResourceRecord::kTypeAaaa));
1791*cfb92d14SAndroid Build Coastguard Worker 
1792*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1793*cfb92d14SAndroid Build Coastguard Worker     Log("Update number of host addresses and validate new announcements");
1794*cfb92d14SAndroid Build Coastguard Worker 
1795*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 2;
1796*cfb92d14SAndroid Build Coastguard Worker 
1797*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
1798*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1799*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 1, HandleSuccessCallback));
1800*cfb92d14SAndroid Build Coastguard Worker 
1801*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1802*cfb92d14SAndroid Build Coastguard Worker     {
1803*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
1804*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
1805*cfb92d14SAndroid Build Coastguard Worker 
1806*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1807*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1808*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
1809*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
1810*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1811*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1812*cfb92d14SAndroid Build Coastguard Worker     }
1813*cfb92d14SAndroid Build Coastguard Worker 
1814*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1815*cfb92d14SAndroid Build Coastguard Worker     Log("Change the addresses and validate the first announce");
1816*cfb92d14SAndroid Build Coastguard Worker 
1817*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 3;
1818*cfb92d14SAndroid Build Coastguard Worker 
1819*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
1820*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1821*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
1822*cfb92d14SAndroid Build Coastguard Worker 
1823*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(300);
1824*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[0].mWasCalled);
1825*cfb92d14SAndroid Build Coastguard Worker 
1826*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
1827*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
1828*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
1829*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAnswerSection);
1830*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1831*cfb92d14SAndroid Build Coastguard Worker 
1832*cfb92d14SAndroid Build Coastguard Worker     Log("Change the address list again before second announce");
1833*cfb92d14SAndroid Build Coastguard Worker 
1834*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 1;
1835*cfb92d14SAndroid Build Coastguard Worker 
1836*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
1837*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1838*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 1, HandleSuccessCallback));
1839*cfb92d14SAndroid Build Coastguard Worker 
1840*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1841*cfb92d14SAndroid Build Coastguard Worker     {
1842*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
1843*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
1844*cfb92d14SAndroid Build Coastguard Worker 
1845*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1846*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1847*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
1848*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
1849*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1850*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1851*cfb92d14SAndroid Build Coastguard Worker     }
1852*cfb92d14SAndroid Build Coastguard Worker 
1853*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1854*cfb92d14SAndroid Build Coastguard Worker     Log("Change `HostEntry` TTL and validate announcements");
1855*cfb92d14SAndroid Build Coastguard Worker 
1856*cfb92d14SAndroid Build Coastguard Worker     host.mTtl = 120;
1857*cfb92d14SAndroid Build Coastguard Worker 
1858*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
1859*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1860*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 1, HandleSuccessCallback));
1861*cfb92d14SAndroid Build Coastguard Worker 
1862*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1863*cfb92d14SAndroid Build Coastguard Worker     {
1864*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
1865*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
1866*cfb92d14SAndroid Build Coastguard Worker 
1867*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1868*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1869*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
1870*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
1871*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1872*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1873*cfb92d14SAndroid Build Coastguard Worker     }
1874*cfb92d14SAndroid Build Coastguard Worker 
1875*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1876*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for AAAA record and validate the response");
1877*cfb92d14SAndroid Build Coastguard Worker 
1878*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
1879*cfb92d14SAndroid Build Coastguard Worker 
1880*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1881*cfb92d14SAndroid Build Coastguard Worker     SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeAaaa);
1882*cfb92d14SAndroid Build Coastguard Worker 
1883*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
1884*cfb92d14SAndroid Build Coastguard Worker 
1885*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
1886*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
1887*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
1888*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAnswerSection);
1889*cfb92d14SAndroid Build Coastguard Worker 
1890*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1891*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister the host and validate the goodbye announces");
1892*cfb92d14SAndroid Build Coastguard Worker 
1893*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1894*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterHost(host));
1895*cfb92d14SAndroid Build Coastguard Worker 
1896*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1897*cfb92d14SAndroid Build Coastguard Worker     {
1898*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
1899*cfb92d14SAndroid Build Coastguard Worker 
1900*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1901*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1902*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
1903*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection, kGoodBye);
1904*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1905*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1906*cfb92d14SAndroid Build Coastguard Worker     }
1907*cfb92d14SAndroid Build Coastguard Worker 
1908*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
1909*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
1910*cfb92d14SAndroid Build Coastguard Worker 
1911*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1912*cfb92d14SAndroid Build Coastguard Worker     Log("Register a host with no address (first time)");
1913*cfb92d14SAndroid Build Coastguard Worker 
1914*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "newhost";
1915*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = nullptr;
1916*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 0;
1917*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
1918*cfb92d14SAndroid Build Coastguard Worker 
1919*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[2].Reset();
1920*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 2, HandleSuccessCallback));
1921*cfb92d14SAndroid Build Coastguard Worker 
1922*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
1923*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[2].mWasCalled);
1924*cfb92d14SAndroid Build Coastguard Worker 
1925*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1926*cfb92d14SAndroid Build Coastguard Worker     Log("Register the same host now with an address");
1927*cfb92d14SAndroid Build Coastguard Worker 
1928*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = &hostAddresses[0];
1929*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 1;
1930*cfb92d14SAndroid Build Coastguard Worker 
1931*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[3].Reset();
1932*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 3, HandleSuccessCallback));
1933*cfb92d14SAndroid Build Coastguard Worker 
1934*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
1935*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[3].mWasCalled);
1936*cfb92d14SAndroid Build Coastguard Worker 
1937*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1938*cfb92d14SAndroid Build Coastguard Worker     Log("Register the same host again now with no address");
1939*cfb92d14SAndroid Build Coastguard Worker 
1940*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 0;
1941*cfb92d14SAndroid Build Coastguard Worker 
1942*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[4].Reset();
1943*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
1944*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 4, HandleSuccessCallback));
1945*cfb92d14SAndroid Build Coastguard Worker 
1946*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
1947*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[4].mWasCalled);
1948*cfb92d14SAndroid Build Coastguard Worker 
1949*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
1950*cfb92d14SAndroid Build Coastguard Worker     {
1951*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
1952*cfb92d14SAndroid Build Coastguard Worker 
1953*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
1954*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
1955*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
1956*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection, kGoodBye);
1957*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
1958*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
1959*cfb92d14SAndroid Build Coastguard Worker     }
1960*cfb92d14SAndroid Build Coastguard Worker 
1961*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1962*cfb92d14SAndroid Build Coastguard Worker     Log("Register the same host again now adding an address");
1963*cfb92d14SAndroid Build Coastguard Worker 
1964*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = &hostAddresses[1];
1965*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 1;
1966*cfb92d14SAndroid Build Coastguard Worker 
1967*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[5].Reset();
1968*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 5, HandleSuccessCallback));
1969*cfb92d14SAndroid Build Coastguard Worker 
1970*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
1971*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[5].mWasCalled);
1972*cfb92d14SAndroid Build Coastguard Worker 
1973*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
1974*cfb92d14SAndroid Build Coastguard Worker 
1975*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
1976*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
1977*cfb92d14SAndroid Build Coastguard Worker 
1978*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
1979*cfb92d14SAndroid Build Coastguard Worker 
1980*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
1981*cfb92d14SAndroid Build Coastguard Worker }
1982*cfb92d14SAndroid Build Coastguard Worker 
1983*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
1984*cfb92d14SAndroid Build Coastguard Worker 
TestKeyReg(void)1985*cfb92d14SAndroid Build Coastguard Worker void TestKeyReg(void)
1986*cfb92d14SAndroid Build Coastguard Worker {
1987*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
1988*cfb92d14SAndroid Build Coastguard Worker     Core::Key         key;
1989*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
1990*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
1991*cfb92d14SAndroid Build Coastguard Worker 
1992*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
1993*cfb92d14SAndroid Build Coastguard Worker     Log("TestKeyReg");
1994*cfb92d14SAndroid Build Coastguard Worker 
1995*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
1996*cfb92d14SAndroid Build Coastguard Worker 
1997*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
1998*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
1999*cfb92d14SAndroid Build Coastguard Worker 
2000*cfb92d14SAndroid Build Coastguard Worker     // Run all tests twice. first with key for a host name, followed
2001*cfb92d14SAndroid Build Coastguard Worker     // by key for service instance name.
2002*cfb92d14SAndroid Build Coastguard Worker 
2003*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
2004*cfb92d14SAndroid Build Coastguard Worker     {
2005*cfb92d14SAndroid Build Coastguard Worker         DnsNameString fullName;
2006*cfb92d14SAndroid Build Coastguard Worker 
2007*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
2008*cfb92d14SAndroid Build Coastguard Worker         {
2009*cfb92d14SAndroid Build Coastguard Worker             Log("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
2010*cfb92d14SAndroid Build Coastguard Worker             Log("Registering key for 'myhost' host name");
2011*cfb92d14SAndroid Build Coastguard Worker             key.mName        = "myhost";
2012*cfb92d14SAndroid Build Coastguard Worker             key.mServiceType = nullptr;
2013*cfb92d14SAndroid Build Coastguard Worker 
2014*cfb92d14SAndroid Build Coastguard Worker             fullName.Append("%s.local.", key.mName);
2015*cfb92d14SAndroid Build Coastguard Worker         }
2016*cfb92d14SAndroid Build Coastguard Worker         else
2017*cfb92d14SAndroid Build Coastguard Worker         {
2018*cfb92d14SAndroid Build Coastguard Worker             Log("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
2019*cfb92d14SAndroid Build Coastguard Worker             Log("Registering key for 'mysrv._srv._udo' service name");
2020*cfb92d14SAndroid Build Coastguard Worker 
2021*cfb92d14SAndroid Build Coastguard Worker             key.mName        = "mysrv";
2022*cfb92d14SAndroid Build Coastguard Worker             key.mServiceType = "_srv._udp";
2023*cfb92d14SAndroid Build Coastguard Worker 
2024*cfb92d14SAndroid Build Coastguard Worker             fullName.Append("%s.%s.local.", key.mName, key.mServiceType);
2025*cfb92d14SAndroid Build Coastguard Worker         }
2026*cfb92d14SAndroid Build Coastguard Worker 
2027*cfb92d14SAndroid Build Coastguard Worker         key.mKeyData       = kKey1;
2028*cfb92d14SAndroid Build Coastguard Worker         key.mKeyDataLength = sizeof(kKey1);
2029*cfb92d14SAndroid Build Coastguard Worker         key.mTtl           = 8000;
2030*cfb92d14SAndroid Build Coastguard Worker 
2031*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2032*cfb92d14SAndroid Build Coastguard Worker         Log("Register a key record and check probes and announcements");
2033*cfb92d14SAndroid Build Coastguard Worker 
2034*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2035*cfb92d14SAndroid Build Coastguard Worker 
2036*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[0].Reset();
2037*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterKey(key, 0, HandleSuccessCallback));
2038*cfb92d14SAndroid Build Coastguard Worker 
2039*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
2040*cfb92d14SAndroid Build Coastguard Worker         {
2041*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2042*cfb92d14SAndroid Build Coastguard Worker 
2043*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2044*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(250);
2045*cfb92d14SAndroid Build Coastguard Worker 
2046*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2047*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2048*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 1, /* Addnl */ 0);
2049*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateAsProbeFor(key, /* aUnicastRequest */ (probeCount == 0));
2050*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2051*cfb92d14SAndroid Build Coastguard Worker         }
2052*cfb92d14SAndroid Build Coastguard Worker 
2053*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2054*cfb92d14SAndroid Build Coastguard Worker         {
2055*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2056*cfb92d14SAndroid Build Coastguard Worker 
2057*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
2058*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[0].mWasCalled);
2059*cfb92d14SAndroid Build Coastguard Worker 
2060*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2061*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2062*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2063*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection);
2064*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2065*cfb92d14SAndroid Build Coastguard Worker         }
2066*cfb92d14SAndroid Build Coastguard Worker 
2067*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2068*cfb92d14SAndroid Build Coastguard Worker         Log("Send a query for KEY record and validate the response");
2069*cfb92d14SAndroid Build Coastguard Worker 
2070*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2000);
2071*cfb92d14SAndroid Build Coastguard Worker 
2072*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2073*cfb92d14SAndroid Build Coastguard Worker         SendQuery(fullName.AsCString(), ResourceRecord::kTypeKey);
2074*cfb92d14SAndroid Build Coastguard Worker 
2075*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1000);
2076*cfb92d14SAndroid Build Coastguard Worker 
2077*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2078*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
2079*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2080*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(key, kInAnswerSection);
2081*cfb92d14SAndroid Build Coastguard Worker 
2082*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2083*cfb92d14SAndroid Build Coastguard Worker         Log("Send a query for ANY record and validate the response");
2084*cfb92d14SAndroid Build Coastguard Worker 
2085*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2000);
2086*cfb92d14SAndroid Build Coastguard Worker 
2087*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2088*cfb92d14SAndroid Build Coastguard Worker         SendQuery(fullName.AsCString(), ResourceRecord::kTypeAny);
2089*cfb92d14SAndroid Build Coastguard Worker 
2090*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1000);
2091*cfb92d14SAndroid Build Coastguard Worker 
2092*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2093*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
2094*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2095*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(key, kInAnswerSection);
2096*cfb92d14SAndroid Build Coastguard Worker 
2097*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2098*cfb92d14SAndroid Build Coastguard Worker         Log("Send a query for non-existing record and validate the response with NSEC");
2099*cfb92d14SAndroid Build Coastguard Worker 
2100*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2000);
2101*cfb92d14SAndroid Build Coastguard Worker 
2102*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2103*cfb92d14SAndroid Build Coastguard Worker         SendQuery(fullName.AsCString(), ResourceRecord::kTypeA);
2104*cfb92d14SAndroid Build Coastguard Worker 
2105*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1000);
2106*cfb92d14SAndroid Build Coastguard Worker 
2107*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2108*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
2109*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 1);
2110*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->mAdditionalRecords.ContainsNsec(fullName, ResourceRecord::kTypeKey));
2111*cfb92d14SAndroid Build Coastguard Worker 
2112*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2113*cfb92d14SAndroid Build Coastguard Worker         Log("Change the TTL");
2114*cfb92d14SAndroid Build Coastguard Worker 
2115*cfb92d14SAndroid Build Coastguard Worker         key.mTtl = 0; // Use default
2116*cfb92d14SAndroid Build Coastguard Worker 
2117*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[1].Reset();
2118*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2119*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterKey(key, 1, HandleSuccessCallback));
2120*cfb92d14SAndroid Build Coastguard Worker 
2121*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2122*cfb92d14SAndroid Build Coastguard Worker         {
2123*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2124*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2125*cfb92d14SAndroid Build Coastguard Worker 
2126*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2127*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2128*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2129*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection);
2130*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2131*cfb92d14SAndroid Build Coastguard Worker 
2132*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2133*cfb92d14SAndroid Build Coastguard Worker         }
2134*cfb92d14SAndroid Build Coastguard Worker 
2135*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2136*cfb92d14SAndroid Build Coastguard Worker         Log("Change the key");
2137*cfb92d14SAndroid Build Coastguard Worker 
2138*cfb92d14SAndroid Build Coastguard Worker         key.mKeyData       = kKey2;
2139*cfb92d14SAndroid Build Coastguard Worker         key.mKeyDataLength = sizeof(kKey2);
2140*cfb92d14SAndroid Build Coastguard Worker 
2141*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[1].Reset();
2142*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2143*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterKey(key, 1, HandleSuccessCallback));
2144*cfb92d14SAndroid Build Coastguard Worker 
2145*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2146*cfb92d14SAndroid Build Coastguard Worker         {
2147*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2148*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2149*cfb92d14SAndroid Build Coastguard Worker 
2150*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2151*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2152*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2153*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection);
2154*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2155*cfb92d14SAndroid Build Coastguard Worker 
2156*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2157*cfb92d14SAndroid Build Coastguard Worker         }
2158*cfb92d14SAndroid Build Coastguard Worker 
2159*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2160*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister the key and validate the goodbye announces");
2161*cfb92d14SAndroid Build Coastguard Worker 
2162*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2163*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->UnregisterKey(key));
2164*cfb92d14SAndroid Build Coastguard Worker 
2165*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2166*cfb92d14SAndroid Build Coastguard Worker         {
2167*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2168*cfb92d14SAndroid Build Coastguard Worker 
2169*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2170*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2171*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
2172*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection, kGoodBye);
2173*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2174*cfb92d14SAndroid Build Coastguard Worker 
2175*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2176*cfb92d14SAndroid Build Coastguard Worker         }
2177*cfb92d14SAndroid Build Coastguard Worker     }
2178*cfb92d14SAndroid Build Coastguard Worker 
2179*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
2180*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
2181*cfb92d14SAndroid Build Coastguard Worker 
2182*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
2183*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
2184*cfb92d14SAndroid Build Coastguard Worker 
2185*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
2186*cfb92d14SAndroid Build Coastguard Worker 
2187*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
2188*cfb92d14SAndroid Build Coastguard Worker }
2189*cfb92d14SAndroid Build Coastguard Worker 
2190*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
2191*cfb92d14SAndroid Build Coastguard Worker 
TestServiceReg(void)2192*cfb92d14SAndroid Build Coastguard Worker void TestServiceReg(void)
2193*cfb92d14SAndroid Build Coastguard Worker {
2194*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
2195*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
2196*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
2197*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
2198*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceName;
2199*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceType;
2200*cfb92d14SAndroid Build Coastguard Worker 
2201*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
2202*cfb92d14SAndroid Build Coastguard Worker     Log("TestServiceReg");
2203*cfb92d14SAndroid Build Coastguard Worker 
2204*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
2205*cfb92d14SAndroid Build Coastguard Worker 
2206*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
2207*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
2208*cfb92d14SAndroid Build Coastguard Worker 
2209*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "myhost";
2210*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "myservice";
2211*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
2212*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
2213*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
2214*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
2215*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
2216*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
2217*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
2218*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
2219*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1000;
2220*cfb92d14SAndroid Build Coastguard Worker 
2221*cfb92d14SAndroid Build Coastguard Worker     fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
2222*cfb92d14SAndroid Build Coastguard Worker     fullServiceType.Append("%s.local.", service.mServiceType);
2223*cfb92d14SAndroid Build Coastguard Worker 
2224*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2225*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `ServiceEntry`, check probes and announcements");
2226*cfb92d14SAndroid Build Coastguard Worker 
2227*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2228*cfb92d14SAndroid Build Coastguard Worker 
2229*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
2230*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
2231*cfb92d14SAndroid Build Coastguard Worker 
2232*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
2233*cfb92d14SAndroid Build Coastguard Worker     {
2234*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2235*cfb92d14SAndroid Build Coastguard Worker 
2236*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2237*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
2238*cfb92d14SAndroid Build Coastguard Worker 
2239*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2240*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2241*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
2242*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
2243*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2244*cfb92d14SAndroid Build Coastguard Worker     }
2245*cfb92d14SAndroid Build Coastguard Worker 
2246*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2247*cfb92d14SAndroid Build Coastguard Worker     {
2248*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2249*cfb92d14SAndroid Build Coastguard Worker 
2250*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
2251*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
2252*cfb92d14SAndroid Build Coastguard Worker 
2253*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2254*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2255*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 1);
2256*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
2257*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2258*cfb92d14SAndroid Build Coastguard Worker     }
2259*cfb92d14SAndroid Build Coastguard Worker 
2260*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2261*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for SRV record and validate the response");
2262*cfb92d14SAndroid Build Coastguard Worker 
2263*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2264*cfb92d14SAndroid Build Coastguard Worker 
2265*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2266*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeSrv);
2267*cfb92d14SAndroid Build Coastguard Worker 
2268*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2269*cfb92d14SAndroid Build Coastguard Worker 
2270*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2271*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2272*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2273*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
2274*cfb92d14SAndroid Build Coastguard Worker 
2275*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2276*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for TXT record and validate the response");
2277*cfb92d14SAndroid Build Coastguard Worker 
2278*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2279*cfb92d14SAndroid Build Coastguard Worker 
2280*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2281*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeTxt);
2282*cfb92d14SAndroid Build Coastguard Worker 
2283*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2284*cfb92d14SAndroid Build Coastguard Worker 
2285*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2286*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2287*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2288*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckTxt);
2289*cfb92d14SAndroid Build Coastguard Worker 
2290*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2291*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for ANY record and validate the response");
2292*cfb92d14SAndroid Build Coastguard Worker 
2293*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2294*cfb92d14SAndroid Build Coastguard Worker 
2295*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2296*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeAny);
2297*cfb92d14SAndroid Build Coastguard Worker 
2298*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2299*cfb92d14SAndroid Build Coastguard Worker 
2300*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2301*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2302*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
2303*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt);
2304*cfb92d14SAndroid Build Coastguard Worker 
2305*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2306*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for service type and validate the response");
2307*cfb92d14SAndroid Build Coastguard Worker 
2308*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2309*cfb92d14SAndroid Build Coastguard Worker 
2310*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2311*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr);
2312*cfb92d14SAndroid Build Coastguard Worker 
2313*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2314*cfb92d14SAndroid Build Coastguard Worker 
2315*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2316*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2317*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
2318*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
2319*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
2320*cfb92d14SAndroid Build Coastguard Worker 
2321*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2322*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for `services._dns-sd` and validate the response");
2323*cfb92d14SAndroid Build Coastguard Worker 
2324*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2325*cfb92d14SAndroid Build Coastguard Worker 
2326*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2327*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_services._dns-sd._udp.local.", ResourceRecord::kTypePtr);
2328*cfb92d14SAndroid Build Coastguard Worker 
2329*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2330*cfb92d14SAndroid Build Coastguard Worker 
2331*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2332*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2333*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
2334*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckServicesPtr);
2335*cfb92d14SAndroid Build Coastguard Worker 
2336*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2337*cfb92d14SAndroid Build Coastguard Worker     Log("Update service port number and validate new announcements of SRV record");
2338*cfb92d14SAndroid Build Coastguard Worker 
2339*cfb92d14SAndroid Build Coastguard Worker     service.mPort = 4567;
2340*cfb92d14SAndroid Build Coastguard Worker 
2341*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2342*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2343*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2344*cfb92d14SAndroid Build Coastguard Worker 
2345*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2346*cfb92d14SAndroid Build Coastguard Worker     {
2347*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2348*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2349*cfb92d14SAndroid Build Coastguard Worker 
2350*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2351*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2352*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2353*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
2354*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2355*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2356*cfb92d14SAndroid Build Coastguard Worker     }
2357*cfb92d14SAndroid Build Coastguard Worker 
2358*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2359*cfb92d14SAndroid Build Coastguard Worker     Log("Update TXT data and validate new announcements of TXT record");
2360*cfb92d14SAndroid Build Coastguard Worker 
2361*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData       = nullptr;
2362*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength = 0;
2363*cfb92d14SAndroid Build Coastguard Worker 
2364*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2365*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2366*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2367*cfb92d14SAndroid Build Coastguard Worker 
2368*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2369*cfb92d14SAndroid Build Coastguard Worker     {
2370*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2371*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2372*cfb92d14SAndroid Build Coastguard Worker 
2373*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2374*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2375*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2376*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckTxt);
2377*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2378*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2379*cfb92d14SAndroid Build Coastguard Worker     }
2380*cfb92d14SAndroid Build Coastguard Worker 
2381*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2382*cfb92d14SAndroid Build Coastguard Worker     Log("Update both service and TXT data and validate new announcements of both records");
2383*cfb92d14SAndroid Build Coastguard Worker 
2384*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData       = kTxtData2;
2385*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength = sizeof(kTxtData2);
2386*cfb92d14SAndroid Build Coastguard Worker     service.mWeight        = 0;
2387*cfb92d14SAndroid Build Coastguard Worker 
2388*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2389*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2390*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2391*cfb92d14SAndroid Build Coastguard Worker 
2392*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2393*cfb92d14SAndroid Build Coastguard Worker     {
2394*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2395*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2396*cfb92d14SAndroid Build Coastguard Worker 
2397*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2398*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2399*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
2400*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt);
2401*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2402*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2403*cfb92d14SAndroid Build Coastguard Worker     }
2404*cfb92d14SAndroid Build Coastguard Worker 
2405*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2406*cfb92d14SAndroid Build Coastguard Worker     Log("Update service host name and validate new announcements of SRV record");
2407*cfb92d14SAndroid Build Coastguard Worker 
2408*cfb92d14SAndroid Build Coastguard Worker     service.mHostName = "newhost";
2409*cfb92d14SAndroid Build Coastguard Worker 
2410*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2411*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2412*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2413*cfb92d14SAndroid Build Coastguard Worker 
2414*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2415*cfb92d14SAndroid Build Coastguard Worker     {
2416*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2417*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2418*cfb92d14SAndroid Build Coastguard Worker 
2419*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2420*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2421*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2422*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
2423*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2424*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2425*cfb92d14SAndroid Build Coastguard Worker     }
2426*cfb92d14SAndroid Build Coastguard Worker 
2427*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2428*cfb92d14SAndroid Build Coastguard Worker     Log("Update TTL and validate new announcements of SRV, TXT and PTR records");
2429*cfb92d14SAndroid Build Coastguard Worker 
2430*cfb92d14SAndroid Build Coastguard Worker     service.mTtl = 0;
2431*cfb92d14SAndroid Build Coastguard Worker 
2432*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2433*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2434*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2435*cfb92d14SAndroid Build Coastguard Worker 
2436*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2437*cfb92d14SAndroid Build Coastguard Worker     {
2438*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2439*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2440*cfb92d14SAndroid Build Coastguard Worker 
2441*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2442*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2443*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
2444*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr);
2445*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2446*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2447*cfb92d14SAndroid Build Coastguard Worker     }
2448*cfb92d14SAndroid Build Coastguard Worker 
2449*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2450*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister the service and validate the goodbye announces");
2451*cfb92d14SAndroid Build Coastguard Worker 
2452*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2453*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterService(service));
2454*cfb92d14SAndroid Build Coastguard Worker 
2455*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2456*cfb92d14SAndroid Build Coastguard Worker     {
2457*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2458*cfb92d14SAndroid Build Coastguard Worker 
2459*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2460*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2461*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 0);
2462*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
2463*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2464*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2465*cfb92d14SAndroid Build Coastguard Worker     }
2466*cfb92d14SAndroid Build Coastguard Worker 
2467*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
2468*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
2469*cfb92d14SAndroid Build Coastguard Worker 
2470*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
2471*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
2472*cfb92d14SAndroid Build Coastguard Worker 
2473*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
2474*cfb92d14SAndroid Build Coastguard Worker 
2475*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
2476*cfb92d14SAndroid Build Coastguard Worker }
2477*cfb92d14SAndroid Build Coastguard Worker 
2478*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
2479*cfb92d14SAndroid Build Coastguard Worker 
TestUnregisterBeforeProbeFinished(void)2480*cfb92d14SAndroid Build Coastguard Worker void TestUnregisterBeforeProbeFinished(void)
2481*cfb92d14SAndroid Build Coastguard Worker {
2482*cfb92d14SAndroid Build Coastguard Worker     const uint8_t kKey1[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
2483*cfb92d14SAndroid Build Coastguard Worker 
2484*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
2485*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
2486*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
2487*cfb92d14SAndroid Build Coastguard Worker     Core::Key         key;
2488*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[3];
2489*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
2490*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
2491*cfb92d14SAndroid Build Coastguard Worker 
2492*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
2493*cfb92d14SAndroid Build Coastguard Worker     Log("TestUnregisterBeforeProbeFinished");
2494*cfb92d14SAndroid Build Coastguard Worker 
2495*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
2496*cfb92d14SAndroid Build Coastguard Worker 
2497*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
2498*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
2499*cfb92d14SAndroid Build Coastguard Worker 
2500*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::aaaa"));
2501*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::bbbb"));
2502*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[2].FromString("fd00::cccc"));
2503*cfb92d14SAndroid Build Coastguard Worker 
2504*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
2505*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
2506*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 3;
2507*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
2508*cfb92d14SAndroid Build Coastguard Worker 
2509*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "myhost";
2510*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "myservice";
2511*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
2512*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
2513*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
2514*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
2515*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
2516*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
2517*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
2518*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
2519*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1000;
2520*cfb92d14SAndroid Build Coastguard Worker 
2521*cfb92d14SAndroid Build Coastguard Worker     key.mName          = "mysrv";
2522*cfb92d14SAndroid Build Coastguard Worker     key.mServiceType   = "_srv._udp";
2523*cfb92d14SAndroid Build Coastguard Worker     key.mKeyData       = kKey1;
2524*cfb92d14SAndroid Build Coastguard Worker     key.mKeyDataLength = sizeof(kKey1);
2525*cfb92d14SAndroid Build Coastguard Worker     key.mTtl           = 8000;
2526*cfb92d14SAndroid Build Coastguard Worker 
2527*cfb92d14SAndroid Build Coastguard Worker     // Repeat the same test 3 times for host and service and key registration.
2528*cfb92d14SAndroid Build Coastguard Worker 
2529*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 3; iter++)
2530*cfb92d14SAndroid Build Coastguard Worker     {
2531*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2532*cfb92d14SAndroid Build Coastguard Worker         Log("Register an entry, check for the first two probes");
2533*cfb92d14SAndroid Build Coastguard Worker 
2534*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2535*cfb92d14SAndroid Build Coastguard Worker 
2536*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[0].Reset();
2537*cfb92d14SAndroid Build Coastguard Worker 
2538*cfb92d14SAndroid Build Coastguard Worker         switch (iter)
2539*cfb92d14SAndroid Build Coastguard Worker         {
2540*cfb92d14SAndroid Build Coastguard Worker         case 0:
2541*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
2542*cfb92d14SAndroid Build Coastguard Worker             break;
2543*cfb92d14SAndroid Build Coastguard Worker         case 1:
2544*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
2545*cfb92d14SAndroid Build Coastguard Worker             break;
2546*cfb92d14SAndroid Build Coastguard Worker         case 2:
2547*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterKey(key, 0, HandleSuccessCallback));
2548*cfb92d14SAndroid Build Coastguard Worker             break;
2549*cfb92d14SAndroid Build Coastguard Worker         }
2550*cfb92d14SAndroid Build Coastguard Worker 
2551*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t probeCount = 0; probeCount < 2; probeCount++)
2552*cfb92d14SAndroid Build Coastguard Worker         {
2553*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
2554*cfb92d14SAndroid Build Coastguard Worker 
2555*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2556*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(250);
2557*cfb92d14SAndroid Build Coastguard Worker 
2558*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
2559*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
2560*cfb92d14SAndroid Build Coastguard Worker 
2561*cfb92d14SAndroid Build Coastguard Worker             switch (iter)
2562*cfb92d14SAndroid Build Coastguard Worker             {
2563*cfb92d14SAndroid Build Coastguard Worker             case 0:
2564*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 3, /* Addnl */ 0);
2565*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ (probeCount == 0));
2566*cfb92d14SAndroid Build Coastguard Worker                 break;
2567*cfb92d14SAndroid Build Coastguard Worker             case 1:
2568*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
2569*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
2570*cfb92d14SAndroid Build Coastguard Worker                 break;
2571*cfb92d14SAndroid Build Coastguard Worker             case 2:
2572*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 1, /* Addnl */ 0);
2573*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateAsProbeFor(key, /* aUnicastRequest */ (probeCount == 0));
2574*cfb92d14SAndroid Build Coastguard Worker                 break;
2575*cfb92d14SAndroid Build Coastguard Worker             }
2576*cfb92d14SAndroid Build Coastguard Worker 
2577*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2578*cfb92d14SAndroid Build Coastguard Worker         }
2579*cfb92d14SAndroid Build Coastguard Worker 
2580*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2581*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2582*cfb92d14SAndroid Build Coastguard Worker 
2583*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2584*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister the entry before the last probe and make sure probing stops");
2585*cfb92d14SAndroid Build Coastguard Worker 
2586*cfb92d14SAndroid Build Coastguard Worker         switch (iter)
2587*cfb92d14SAndroid Build Coastguard Worker         {
2588*cfb92d14SAndroid Build Coastguard Worker         case 0:
2589*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterHost(host));
2590*cfb92d14SAndroid Build Coastguard Worker             break;
2591*cfb92d14SAndroid Build Coastguard Worker         case 1:
2592*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterService(service));
2593*cfb92d14SAndroid Build Coastguard Worker             break;
2594*cfb92d14SAndroid Build Coastguard Worker         case 2:
2595*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterKey(key));
2596*cfb92d14SAndroid Build Coastguard Worker             break;
2597*cfb92d14SAndroid Build Coastguard Worker         }
2598*cfb92d14SAndroid Build Coastguard Worker 
2599*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(20 * 1000);
2600*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2601*cfb92d14SAndroid Build Coastguard Worker 
2602*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
2603*cfb92d14SAndroid Build Coastguard Worker     }
2604*cfb92d14SAndroid Build Coastguard Worker 
2605*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
2606*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
2607*cfb92d14SAndroid Build Coastguard Worker 
2608*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
2609*cfb92d14SAndroid Build Coastguard Worker 
2610*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
2611*cfb92d14SAndroid Build Coastguard Worker }
2612*cfb92d14SAndroid Build Coastguard Worker 
2613*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
2614*cfb92d14SAndroid Build Coastguard Worker 
TestServiceSubTypeReg(void)2615*cfb92d14SAndroid Build Coastguard Worker void TestServiceSubTypeReg(void)
2616*cfb92d14SAndroid Build Coastguard Worker {
2617*cfb92d14SAndroid Build Coastguard Worker     static const char *const kSubTypes1[] = {"_s1", "_r2", "_vXy", "_last"};
2618*cfb92d14SAndroid Build Coastguard Worker     static const char *const kSubTypes2[] = {"_vxy", "_r1", "_r2", "_zzz"};
2619*cfb92d14SAndroid Build Coastguard Worker 
2620*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
2621*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
2622*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
2623*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
2624*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceName;
2625*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceType;
2626*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullSubServiceType;
2627*cfb92d14SAndroid Build Coastguard Worker 
2628*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
2629*cfb92d14SAndroid Build Coastguard Worker     Log("TestServiceSubTypeReg");
2630*cfb92d14SAndroid Build Coastguard Worker 
2631*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
2632*cfb92d14SAndroid Build Coastguard Worker 
2633*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
2634*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
2635*cfb92d14SAndroid Build Coastguard Worker 
2636*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "tarnished";
2637*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "elden";
2638*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_ring._udp";
2639*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = kSubTypes1;
2640*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 3;
2641*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
2642*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
2643*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
2644*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
2645*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
2646*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 6000;
2647*cfb92d14SAndroid Build Coastguard Worker 
2648*cfb92d14SAndroid Build Coastguard Worker     fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
2649*cfb92d14SAndroid Build Coastguard Worker     fullServiceType.Append("%s.local.", service.mServiceType);
2650*cfb92d14SAndroid Build Coastguard Worker 
2651*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2652*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `ServiceEntry` with sub-types, check probes and announcements");
2653*cfb92d14SAndroid Build Coastguard Worker 
2654*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2655*cfb92d14SAndroid Build Coastguard Worker 
2656*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
2657*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
2658*cfb92d14SAndroid Build Coastguard Worker 
2659*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
2660*cfb92d14SAndroid Build Coastguard Worker     {
2661*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2662*cfb92d14SAndroid Build Coastguard Worker 
2663*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
2664*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
2665*cfb92d14SAndroid Build Coastguard Worker 
2666*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2667*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2668*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
2669*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
2670*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2671*cfb92d14SAndroid Build Coastguard Worker     }
2672*cfb92d14SAndroid Build Coastguard Worker 
2673*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2674*cfb92d14SAndroid Build Coastguard Worker     {
2675*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2676*cfb92d14SAndroid Build Coastguard Worker 
2677*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
2678*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
2679*cfb92d14SAndroid Build Coastguard Worker 
2680*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2681*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2682*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 7, /* Auth */ 0, /* Addnl */ 1);
2683*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
2684*cfb92d14SAndroid Build Coastguard Worker 
2685*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service.mSubTypeLabelsLength; index++)
2686*cfb92d14SAndroid Build Coastguard Worker         {
2687*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service);
2688*cfb92d14SAndroid Build Coastguard Worker         }
2689*cfb92d14SAndroid Build Coastguard Worker 
2690*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2691*cfb92d14SAndroid Build Coastguard Worker     }
2692*cfb92d14SAndroid Build Coastguard Worker 
2693*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2694*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for SRV record and validate the response");
2695*cfb92d14SAndroid Build Coastguard Worker 
2696*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2697*cfb92d14SAndroid Build Coastguard Worker 
2698*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2699*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeSrv);
2700*cfb92d14SAndroid Build Coastguard Worker 
2701*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2702*cfb92d14SAndroid Build Coastguard Worker 
2703*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2704*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2705*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2706*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
2707*cfb92d14SAndroid Build Coastguard Worker 
2708*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2709*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for TXT record and validate the response");
2710*cfb92d14SAndroid Build Coastguard Worker 
2711*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2712*cfb92d14SAndroid Build Coastguard Worker 
2713*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2714*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeTxt);
2715*cfb92d14SAndroid Build Coastguard Worker 
2716*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2717*cfb92d14SAndroid Build Coastguard Worker 
2718*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2719*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2720*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
2721*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckTxt);
2722*cfb92d14SAndroid Build Coastguard Worker 
2723*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2724*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for ANY record and validate the response");
2725*cfb92d14SAndroid Build Coastguard Worker 
2726*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2727*cfb92d14SAndroid Build Coastguard Worker 
2728*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2729*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeAny);
2730*cfb92d14SAndroid Build Coastguard Worker 
2731*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2732*cfb92d14SAndroid Build Coastguard Worker 
2733*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2734*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2735*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
2736*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt);
2737*cfb92d14SAndroid Build Coastguard Worker 
2738*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2739*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for service type and validate the response");
2740*cfb92d14SAndroid Build Coastguard Worker 
2741*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2742*cfb92d14SAndroid Build Coastguard Worker 
2743*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2744*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr);
2745*cfb92d14SAndroid Build Coastguard Worker 
2746*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2747*cfb92d14SAndroid Build Coastguard Worker 
2748*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2749*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2750*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
2751*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
2752*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
2753*cfb92d14SAndroid Build Coastguard Worker 
2754*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2755*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for `services._dns-sd` and validate the response");
2756*cfb92d14SAndroid Build Coastguard Worker 
2757*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2758*cfb92d14SAndroid Build Coastguard Worker 
2759*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2760*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_services._dns-sd._udp.local.", ResourceRecord::kTypePtr);
2761*cfb92d14SAndroid Build Coastguard Worker 
2762*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
2763*cfb92d14SAndroid Build Coastguard Worker 
2764*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
2765*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
2766*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
2767*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckServicesPtr);
2768*cfb92d14SAndroid Build Coastguard Worker 
2769*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0; index < service.mSubTypeLabelsLength; index++)
2770*cfb92d14SAndroid Build Coastguard Worker     {
2771*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2772*cfb92d14SAndroid Build Coastguard Worker         Log("Send a PTR query for sub-type `%s` and validate the response", service.mSubTypeLabels[index]);
2773*cfb92d14SAndroid Build Coastguard Worker 
2774*cfb92d14SAndroid Build Coastguard Worker         fullSubServiceType.Clear();
2775*cfb92d14SAndroid Build Coastguard Worker         fullSubServiceType.Append("%s._sub.%s", service.mSubTypeLabels[index], fullServiceType.AsCString());
2776*cfb92d14SAndroid Build Coastguard Worker 
2777*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2000);
2778*cfb92d14SAndroid Build Coastguard Worker 
2779*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2780*cfb92d14SAndroid Build Coastguard Worker         SendQuery(fullSubServiceType.AsCString(), ResourceRecord::kTypePtr);
2781*cfb92d14SAndroid Build Coastguard Worker 
2782*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1000);
2783*cfb92d14SAndroid Build Coastguard Worker 
2784*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2785*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
2786*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
2787*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service);
2788*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
2789*cfb92d14SAndroid Build Coastguard Worker     }
2790*cfb92d14SAndroid Build Coastguard Worker 
2791*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2792*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query for non-existing sub-type and validate there is no response");
2793*cfb92d14SAndroid Build Coastguard Worker 
2794*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2795*cfb92d14SAndroid Build Coastguard Worker 
2796*cfb92d14SAndroid Build Coastguard Worker     fullSubServiceType.Clear();
2797*cfb92d14SAndroid Build Coastguard Worker     fullSubServiceType.Append("_none._sub.%s", fullServiceType.AsCString());
2798*cfb92d14SAndroid Build Coastguard Worker 
2799*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2800*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullSubServiceType.AsCString(), ResourceRecord::kTypePtr);
2801*cfb92d14SAndroid Build Coastguard Worker 
2802*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
2803*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
2804*cfb92d14SAndroid Build Coastguard Worker 
2805*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2806*cfb92d14SAndroid Build Coastguard Worker     Log("Register a new sub-type and validate announcements of PTR record for it");
2807*cfb92d14SAndroid Build Coastguard Worker 
2808*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 4;
2809*cfb92d14SAndroid Build Coastguard Worker 
2810*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2811*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2812*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2813*cfb92d14SAndroid Build Coastguard Worker 
2814*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2815*cfb92d14SAndroid Build Coastguard Worker     {
2816*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2817*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2818*cfb92d14SAndroid Build Coastguard Worker 
2819*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2820*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2821*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
2822*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(service.mSubTypeLabels[3], service);
2823*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
2824*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2825*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2826*cfb92d14SAndroid Build Coastguard Worker     }
2827*cfb92d14SAndroid Build Coastguard Worker 
2828*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2829*cfb92d14SAndroid Build Coastguard Worker     Log("Remove a previous sub-type and validate announcements of its removal");
2830*cfb92d14SAndroid Build Coastguard Worker 
2831*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels++;
2832*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 3;
2833*cfb92d14SAndroid Build Coastguard Worker 
2834*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2835*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2836*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2837*cfb92d14SAndroid Build Coastguard Worker 
2838*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2839*cfb92d14SAndroid Build Coastguard Worker     {
2840*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2841*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2842*cfb92d14SAndroid Build Coastguard Worker 
2843*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2844*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2845*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
2846*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(kSubTypes1[0], service, kGoodBye);
2847*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2848*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2849*cfb92d14SAndroid Build Coastguard Worker     }
2850*cfb92d14SAndroid Build Coastguard Worker 
2851*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2852*cfb92d14SAndroid Build Coastguard Worker     Log("Update TTL and validate announcement of all records");
2853*cfb92d14SAndroid Build Coastguard Worker 
2854*cfb92d14SAndroid Build Coastguard Worker     service.mTtl = 0;
2855*cfb92d14SAndroid Build Coastguard Worker 
2856*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2857*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2858*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2859*cfb92d14SAndroid Build Coastguard Worker 
2860*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2861*cfb92d14SAndroid Build Coastguard Worker     {
2862*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2863*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2864*cfb92d14SAndroid Build Coastguard Worker 
2865*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2866*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2867*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 6, /* Auth */ 0, /* Addnl */ 1);
2868*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr);
2869*cfb92d14SAndroid Build Coastguard Worker 
2870*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service.mSubTypeLabelsLength; index++)
2871*cfb92d14SAndroid Build Coastguard Worker         {
2872*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service);
2873*cfb92d14SAndroid Build Coastguard Worker         }
2874*cfb92d14SAndroid Build Coastguard Worker 
2875*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2876*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2877*cfb92d14SAndroid Build Coastguard Worker     }
2878*cfb92d14SAndroid Build Coastguard Worker 
2879*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2880*cfb92d14SAndroid Build Coastguard Worker     Log("Add and remove sub-types at the same time and check proper announcements");
2881*cfb92d14SAndroid Build Coastguard Worker 
2882*cfb92d14SAndroid Build Coastguard Worker     // Registered sub-types: _r2, _vXy, _last
2883*cfb92d14SAndroid Build Coastguard Worker     // New sub-types list  : _vxy, _r1, _r2, _zzz
2884*cfb92d14SAndroid Build Coastguard Worker     //
2885*cfb92d14SAndroid Build Coastguard Worker     // Should announce removal of `_last` and addition of
2886*cfb92d14SAndroid Build Coastguard Worker     // `_r1` and `_zzz`. The `_vxy` should match with `_vXy`.
2887*cfb92d14SAndroid Build Coastguard Worker 
2888*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = kSubTypes2;
2889*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 4;
2890*cfb92d14SAndroid Build Coastguard Worker 
2891*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
2892*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2893*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
2894*cfb92d14SAndroid Build Coastguard Worker 
2895*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2896*cfb92d14SAndroid Build Coastguard Worker     {
2897*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2898*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[1].mWasCalled);
2899*cfb92d14SAndroid Build Coastguard Worker 
2900*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2901*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2902*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 2);
2903*cfb92d14SAndroid Build Coastguard Worker 
2904*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(kSubTypes1[3], service, kGoodBye);
2905*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(kSubTypes2[1], service);
2906*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(kSubTypes2[3], service);
2907*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
2908*cfb92d14SAndroid Build Coastguard Worker 
2909*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2910*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2911*cfb92d14SAndroid Build Coastguard Worker     }
2912*cfb92d14SAndroid Build Coastguard Worker 
2913*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
2914*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister the service and validate the goodbye announces for service and its sub-types");
2915*cfb92d14SAndroid Build Coastguard Worker 
2916*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
2917*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterService(service));
2918*cfb92d14SAndroid Build Coastguard Worker 
2919*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
2920*cfb92d14SAndroid Build Coastguard Worker     {
2921*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
2922*cfb92d14SAndroid Build Coastguard Worker 
2923*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
2924*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
2925*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 7, /* Auth */ 0, /* Addnl */ 0);
2926*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
2927*cfb92d14SAndroid Build Coastguard Worker 
2928*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service.mSubTypeLabelsLength; index++)
2929*cfb92d14SAndroid Build Coastguard Worker         {
2930*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service, kGoodBye);
2931*cfb92d14SAndroid Build Coastguard Worker         }
2932*cfb92d14SAndroid Build Coastguard Worker 
2933*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
2934*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
2935*cfb92d14SAndroid Build Coastguard Worker     }
2936*cfb92d14SAndroid Build Coastguard Worker 
2937*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
2938*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
2939*cfb92d14SAndroid Build Coastguard Worker 
2940*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
2941*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
2942*cfb92d14SAndroid Build Coastguard Worker 
2943*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
2944*cfb92d14SAndroid Build Coastguard Worker 
2945*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
2946*cfb92d14SAndroid Build Coastguard Worker }
2947*cfb92d14SAndroid Build Coastguard Worker 
TestHostOrServiceAndKeyReg(void)2948*cfb92d14SAndroid Build Coastguard Worker void TestHostOrServiceAndKeyReg(void)
2949*cfb92d14SAndroid Build Coastguard Worker {
2950*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
2951*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
2952*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
2953*cfb92d14SAndroid Build Coastguard Worker     Core::Key         key;
2954*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[2];
2955*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
2956*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
2957*cfb92d14SAndroid Build Coastguard Worker 
2958*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
2959*cfb92d14SAndroid Build Coastguard Worker     Log("TestHostOrServiceAndKeyReg");
2960*cfb92d14SAndroid Build Coastguard Worker 
2961*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
2962*cfb92d14SAndroid Build Coastguard Worker 
2963*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
2964*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
2965*cfb92d14SAndroid Build Coastguard Worker 
2966*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::1"));
2967*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::2"));
2968*cfb92d14SAndroid Build Coastguard Worker 
2969*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
2970*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
2971*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 2;
2972*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 5000;
2973*cfb92d14SAndroid Build Coastguard Worker 
2974*cfb92d14SAndroid Build Coastguard Worker     key.mKeyData       = kKey1;
2975*cfb92d14SAndroid Build Coastguard Worker     key.mKeyDataLength = sizeof(kKey1);
2976*cfb92d14SAndroid Build Coastguard Worker     key.mTtl           = 80000;
2977*cfb92d14SAndroid Build Coastguard Worker 
2978*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "myhost";
2979*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "myservice";
2980*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
2981*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
2982*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
2983*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
2984*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
2985*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
2986*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
2987*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
2988*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1000;
2989*cfb92d14SAndroid Build Coastguard Worker 
2990*cfb92d14SAndroid Build Coastguard Worker     // Run all test step twice, first time registering host and key,
2991*cfb92d14SAndroid Build Coastguard Worker     // second time registering service and key.
2992*cfb92d14SAndroid Build Coastguard Worker 
2993*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
2994*cfb92d14SAndroid Build Coastguard Worker     {
2995*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
2996*cfb92d14SAndroid Build Coastguard Worker         {
2997*cfb92d14SAndroid Build Coastguard Worker             key.mName        = host.mHostName;
2998*cfb92d14SAndroid Build Coastguard Worker             key.mServiceType = nullptr;
2999*cfb92d14SAndroid Build Coastguard Worker         }
3000*cfb92d14SAndroid Build Coastguard Worker         else
3001*cfb92d14SAndroid Build Coastguard Worker         {
3002*cfb92d14SAndroid Build Coastguard Worker             key.mName        = service.mServiceInstance;
3003*cfb92d14SAndroid Build Coastguard Worker             key.mServiceType = service.mServiceType;
3004*cfb92d14SAndroid Build Coastguard Worker         }
3005*cfb92d14SAndroid Build Coastguard Worker 
3006*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3007*cfb92d14SAndroid Build Coastguard Worker         Log("Register a %s entry, check the first probe is sent", iter == 0 ? "host" : "service");
3008*cfb92d14SAndroid Build Coastguard Worker 
3009*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3010*cfb92d14SAndroid Build Coastguard Worker 
3011*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[0].Reset();
3012*cfb92d14SAndroid Build Coastguard Worker 
3013*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
3014*cfb92d14SAndroid Build Coastguard Worker         {
3015*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
3016*cfb92d14SAndroid Build Coastguard Worker         }
3017*cfb92d14SAndroid Build Coastguard Worker         else
3018*cfb92d14SAndroid Build Coastguard Worker         {
3019*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
3020*cfb92d14SAndroid Build Coastguard Worker         }
3021*cfb92d14SAndroid Build Coastguard Worker 
3022*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3023*cfb92d14SAndroid Build Coastguard Worker 
3024*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
3025*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
3026*cfb92d14SAndroid Build Coastguard Worker 
3027*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
3028*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3029*cfb92d14SAndroid Build Coastguard Worker 
3030*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
3031*cfb92d14SAndroid Build Coastguard Worker 
3032*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
3033*cfb92d14SAndroid Build Coastguard Worker         {
3034*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ true);
3035*cfb92d14SAndroid Build Coastguard Worker         }
3036*cfb92d14SAndroid Build Coastguard Worker         else
3037*cfb92d14SAndroid Build Coastguard Worker         {
3038*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ true);
3039*cfb92d14SAndroid Build Coastguard Worker         }
3040*cfb92d14SAndroid Build Coastguard Worker 
3041*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3042*cfb92d14SAndroid Build Coastguard Worker 
3043*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3044*cfb92d14SAndroid Build Coastguard Worker         Log("Register a `KeyEntry` for same name, check that probes continue");
3045*cfb92d14SAndroid Build Coastguard Worker 
3046*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[1].Reset();
3047*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterKey(key, 1, HandleSuccessCallback));
3048*cfb92d14SAndroid Build Coastguard Worker 
3049*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t probeCount = 1; probeCount < 3; probeCount++)
3050*cfb92d14SAndroid Build Coastguard Worker         {
3051*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3052*cfb92d14SAndroid Build Coastguard Worker 
3053*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
3054*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[1].mWasCalled);
3055*cfb92d14SAndroid Build Coastguard Worker 
3056*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(250);
3057*cfb92d14SAndroid Build Coastguard Worker 
3058*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3059*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3060*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 3, /* Addnl */ 0);
3061*cfb92d14SAndroid Build Coastguard Worker 
3062*cfb92d14SAndroid Build Coastguard Worker             if (iter == 0)
3063*cfb92d14SAndroid Build Coastguard Worker             {
3064*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ false);
3065*cfb92d14SAndroid Build Coastguard Worker             }
3066*cfb92d14SAndroid Build Coastguard Worker             else
3067*cfb92d14SAndroid Build Coastguard Worker             {
3068*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ false);
3069*cfb92d14SAndroid Build Coastguard Worker             }
3070*cfb92d14SAndroid Build Coastguard Worker 
3071*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateAsProbeFor(key, /* aUnicastRequest */ (probeCount == 0));
3072*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3073*cfb92d14SAndroid Build Coastguard Worker         }
3074*cfb92d14SAndroid Build Coastguard Worker 
3075*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3076*cfb92d14SAndroid Build Coastguard Worker         Log("Validate Announces for both entry and key");
3077*cfb92d14SAndroid Build Coastguard Worker 
3078*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3079*cfb92d14SAndroid Build Coastguard Worker         {
3080*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3081*cfb92d14SAndroid Build Coastguard Worker 
3082*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3083*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[0].mWasCalled);
3084*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[1].mWasCalled);
3085*cfb92d14SAndroid Build Coastguard Worker 
3086*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3087*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3088*cfb92d14SAndroid Build Coastguard Worker 
3089*cfb92d14SAndroid Build Coastguard Worker             if (iter == 0)
3090*cfb92d14SAndroid Build Coastguard Worker             {
3091*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
3092*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(host, kInAnswerSection);
3093*cfb92d14SAndroid Build Coastguard Worker             }
3094*cfb92d14SAndroid Build Coastguard Worker             else
3095*cfb92d14SAndroid Build Coastguard Worker             {
3096*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 5, /* Auth */ 0, /* Addnl */ 1);
3097*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3098*cfb92d14SAndroid Build Coastguard Worker             }
3099*cfb92d14SAndroid Build Coastguard Worker 
3100*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection);
3101*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3102*cfb92d14SAndroid Build Coastguard Worker         }
3103*cfb92d14SAndroid Build Coastguard Worker 
3104*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3105*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister the entry and validate its goodbye announces");
3106*cfb92d14SAndroid Build Coastguard Worker 
3107*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3108*cfb92d14SAndroid Build Coastguard Worker 
3109*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
3110*cfb92d14SAndroid Build Coastguard Worker         {
3111*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterHost(host));
3112*cfb92d14SAndroid Build Coastguard Worker         }
3113*cfb92d14SAndroid Build Coastguard Worker         else
3114*cfb92d14SAndroid Build Coastguard Worker         {
3115*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterService(service));
3116*cfb92d14SAndroid Build Coastguard Worker         }
3117*cfb92d14SAndroid Build Coastguard Worker 
3118*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3119*cfb92d14SAndroid Build Coastguard Worker         {
3120*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
3121*cfb92d14SAndroid Build Coastguard Worker 
3122*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3123*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3124*cfb92d14SAndroid Build Coastguard Worker 
3125*cfb92d14SAndroid Build Coastguard Worker             if (iter == 0)
3126*cfb92d14SAndroid Build Coastguard Worker             {
3127*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
3128*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(host, kInAnswerSection, kGoodBye);
3129*cfb92d14SAndroid Build Coastguard Worker             }
3130*cfb92d14SAndroid Build Coastguard Worker             else
3131*cfb92d14SAndroid Build Coastguard Worker             {
3132*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 1);
3133*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
3134*cfb92d14SAndroid Build Coastguard Worker             }
3135*cfb92d14SAndroid Build Coastguard Worker 
3136*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3137*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3138*cfb92d14SAndroid Build Coastguard Worker         }
3139*cfb92d14SAndroid Build Coastguard Worker 
3140*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
3141*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
3142*cfb92d14SAndroid Build Coastguard Worker 
3143*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3144*cfb92d14SAndroid Build Coastguard Worker         Log("Register the entry again, validate its announcements");
3145*cfb92d14SAndroid Build Coastguard Worker 
3146*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3147*cfb92d14SAndroid Build Coastguard Worker 
3148*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[2].Reset();
3149*cfb92d14SAndroid Build Coastguard Worker 
3150*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
3151*cfb92d14SAndroid Build Coastguard Worker         {
3152*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterHost(host, 2, HandleSuccessCallback));
3153*cfb92d14SAndroid Build Coastguard Worker         }
3154*cfb92d14SAndroid Build Coastguard Worker         else
3155*cfb92d14SAndroid Build Coastguard Worker         {
3156*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->RegisterService(service, 2, HandleSuccessCallback));
3157*cfb92d14SAndroid Build Coastguard Worker         }
3158*cfb92d14SAndroid Build Coastguard Worker 
3159*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3160*cfb92d14SAndroid Build Coastguard Worker         {
3161*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3162*cfb92d14SAndroid Build Coastguard Worker 
3163*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3164*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[2].mWasCalled);
3165*cfb92d14SAndroid Build Coastguard Worker 
3166*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3167*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3168*cfb92d14SAndroid Build Coastguard Worker 
3169*cfb92d14SAndroid Build Coastguard Worker             if (iter == 0)
3170*cfb92d14SAndroid Build Coastguard Worker             {
3171*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
3172*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(host, kInAnswerSection);
3173*cfb92d14SAndroid Build Coastguard Worker             }
3174*cfb92d14SAndroid Build Coastguard Worker             else
3175*cfb92d14SAndroid Build Coastguard Worker             {
3176*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 1);
3177*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3178*cfb92d14SAndroid Build Coastguard Worker             }
3179*cfb92d14SAndroid Build Coastguard Worker 
3180*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3181*cfb92d14SAndroid Build Coastguard Worker         }
3182*cfb92d14SAndroid Build Coastguard Worker 
3183*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3184*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister the key and validate its goodbye announcements");
3185*cfb92d14SAndroid Build Coastguard Worker 
3186*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3187*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->UnregisterKey(key));
3188*cfb92d14SAndroid Build Coastguard Worker 
3189*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3190*cfb92d14SAndroid Build Coastguard Worker         {
3191*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
3192*cfb92d14SAndroid Build Coastguard Worker 
3193*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3194*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3195*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
3196*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection, kGoodBye);
3197*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3198*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3199*cfb92d14SAndroid Build Coastguard Worker         }
3200*cfb92d14SAndroid Build Coastguard Worker 
3201*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3202*cfb92d14SAndroid Build Coastguard Worker         Log("Register the key again, validate its announcements");
3203*cfb92d14SAndroid Build Coastguard Worker 
3204*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3205*cfb92d14SAndroid Build Coastguard Worker 
3206*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[3].Reset();
3207*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterKey(key, 3, HandleSuccessCallback));
3208*cfb92d14SAndroid Build Coastguard Worker 
3209*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3210*cfb92d14SAndroid Build Coastguard Worker         {
3211*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3212*cfb92d14SAndroid Build Coastguard Worker 
3213*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3214*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[3].mWasCalled);
3215*cfb92d14SAndroid Build Coastguard Worker 
3216*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3217*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3218*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
3219*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection);
3220*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3221*cfb92d14SAndroid Build Coastguard Worker         }
3222*cfb92d14SAndroid Build Coastguard Worker 
3223*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3224*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
3225*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
3226*cfb92d14SAndroid Build Coastguard Worker 
3227*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3228*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister key first, validate two of its goodbye announcements");
3229*cfb92d14SAndroid Build Coastguard Worker 
3230*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3231*cfb92d14SAndroid Build Coastguard Worker 
3232*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->UnregisterKey(key));
3233*cfb92d14SAndroid Build Coastguard Worker 
3234*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t anncCount = 0; anncCount < 2; anncCount++)
3235*cfb92d14SAndroid Build Coastguard Worker         {
3236*cfb92d14SAndroid Build Coastguard Worker             sDnsMessages.Clear();
3237*cfb92d14SAndroid Build Coastguard Worker 
3238*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime((anncCount == 0) ? 1 : (1U << (anncCount - 1)) * 1000);
3239*cfb92d14SAndroid Build Coastguard Worker 
3240*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sDnsMessages.IsEmpty());
3241*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = sDnsMessages.GetHead();
3242*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
3243*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->Validate(key, kInAnswerSection, kGoodBye);
3244*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3245*cfb92d14SAndroid Build Coastguard Worker         }
3246*cfb92d14SAndroid Build Coastguard Worker 
3247*cfb92d14SAndroid Build Coastguard Worker         Log("Unregister entry as well");
3248*cfb92d14SAndroid Build Coastguard Worker 
3249*cfb92d14SAndroid Build Coastguard Worker         if (iter == 0)
3250*cfb92d14SAndroid Build Coastguard Worker         {
3251*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterHost(host));
3252*cfb92d14SAndroid Build Coastguard Worker         }
3253*cfb92d14SAndroid Build Coastguard Worker         else
3254*cfb92d14SAndroid Build Coastguard Worker         {
3255*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(mdns->UnregisterService(service));
3256*cfb92d14SAndroid Build Coastguard Worker         }
3257*cfb92d14SAndroid Build Coastguard Worker 
3258*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
3259*cfb92d14SAndroid Build Coastguard Worker 
3260*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t anncCount = 0; anncCount < 4; anncCount++)
3261*cfb92d14SAndroid Build Coastguard Worker         {
3262*cfb92d14SAndroid Build Coastguard Worker             dnsMsg = dnsMsg->GetNext();
3263*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(dnsMsg != nullptr);
3264*cfb92d14SAndroid Build Coastguard Worker 
3265*cfb92d14SAndroid Build Coastguard Worker             if (anncCount == 2)
3266*cfb92d14SAndroid Build Coastguard Worker             {
3267*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
3268*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(key, kInAnswerSection, kGoodBye);
3269*cfb92d14SAndroid Build Coastguard Worker             }
3270*cfb92d14SAndroid Build Coastguard Worker             else if (iter == 0)
3271*cfb92d14SAndroid Build Coastguard Worker             {
3272*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 0);
3273*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(host, kInAnswerSection, kGoodBye);
3274*cfb92d14SAndroid Build Coastguard Worker             }
3275*cfb92d14SAndroid Build Coastguard Worker             else
3276*cfb92d14SAndroid Build Coastguard Worker             {
3277*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 0);
3278*cfb92d14SAndroid Build Coastguard Worker                 dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
3279*cfb92d14SAndroid Build Coastguard Worker             }
3280*cfb92d14SAndroid Build Coastguard Worker         }
3281*cfb92d14SAndroid Build Coastguard Worker 
3282*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3283*cfb92d14SAndroid Build Coastguard Worker 
3284*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3285*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
3286*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
3287*cfb92d14SAndroid Build Coastguard Worker     }
3288*cfb92d14SAndroid Build Coastguard Worker 
3289*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
3290*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
3291*cfb92d14SAndroid Build Coastguard Worker 
3292*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
3293*cfb92d14SAndroid Build Coastguard Worker 
3294*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
3295*cfb92d14SAndroid Build Coastguard Worker }
3296*cfb92d14SAndroid Build Coastguard Worker 
3297*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
3298*cfb92d14SAndroid Build Coastguard Worker 
TestQuery(void)3299*cfb92d14SAndroid Build Coastguard Worker void TestQuery(void)
3300*cfb92d14SAndroid Build Coastguard Worker {
3301*cfb92d14SAndroid Build Coastguard Worker     static const char *const kSubTypes[] = {"_s", "_r"};
3302*cfb92d14SAndroid Build Coastguard Worker 
3303*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
3304*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host1;
3305*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host2;
3306*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service1;
3307*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service2;
3308*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service3;
3309*cfb92d14SAndroid Build Coastguard Worker     Core::Key         key1;
3310*cfb92d14SAndroid Build Coastguard Worker     Core::Key         key2;
3311*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      host1Addresses[3];
3312*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      host2Addresses[2];
3313*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
3314*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
3315*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     host1FullName;
3316*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     host2FullName;
3317*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     service1FullName;
3318*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     service2FullName;
3319*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     service3FullName;
3320*cfb92d14SAndroid Build Coastguard Worker     KnownAnswer       knownAnswers[2];
3321*cfb92d14SAndroid Build Coastguard Worker 
3322*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
3323*cfb92d14SAndroid Build Coastguard Worker     Log("TestQuery");
3324*cfb92d14SAndroid Build Coastguard Worker 
3325*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
3326*cfb92d14SAndroid Build Coastguard Worker 
3327*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
3328*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
3329*cfb92d14SAndroid Build Coastguard Worker 
3330*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[0].FromString("fd00::1:aaaa"));
3331*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[1].FromString("fd00::1:bbbb"));
3332*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[2].FromString("fd00::1:cccc"));
3333*cfb92d14SAndroid Build Coastguard Worker     host1.mHostName        = "host1";
3334*cfb92d14SAndroid Build Coastguard Worker     host1.mAddresses       = host1Addresses;
3335*cfb92d14SAndroid Build Coastguard Worker     host1.mAddressesLength = 3;
3336*cfb92d14SAndroid Build Coastguard Worker     host1.mTtl             = 1500;
3337*cfb92d14SAndroid Build Coastguard Worker     host1FullName.Append("%s.local.", host1.mHostName);
3338*cfb92d14SAndroid Build Coastguard Worker 
3339*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host2Addresses[0].FromString("fd00::2:eeee"));
3340*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host2Addresses[1].FromString("fd00::2:ffff"));
3341*cfb92d14SAndroid Build Coastguard Worker     host2.mHostName        = "host2";
3342*cfb92d14SAndroid Build Coastguard Worker     host2.mAddresses       = host2Addresses;
3343*cfb92d14SAndroid Build Coastguard Worker     host2.mAddressesLength = 2;
3344*cfb92d14SAndroid Build Coastguard Worker     host2.mTtl             = 1500;
3345*cfb92d14SAndroid Build Coastguard Worker     host2FullName.Append("%s.local.", host2.mHostName);
3346*cfb92d14SAndroid Build Coastguard Worker 
3347*cfb92d14SAndroid Build Coastguard Worker     service1.mHostName            = host1.mHostName;
3348*cfb92d14SAndroid Build Coastguard Worker     service1.mServiceInstance     = "srv1";
3349*cfb92d14SAndroid Build Coastguard Worker     service1.mServiceType         = "_srv._udp";
3350*cfb92d14SAndroid Build Coastguard Worker     service1.mSubTypeLabels       = kSubTypes;
3351*cfb92d14SAndroid Build Coastguard Worker     service1.mSubTypeLabelsLength = 2;
3352*cfb92d14SAndroid Build Coastguard Worker     service1.mTxtData             = kTxtData1;
3353*cfb92d14SAndroid Build Coastguard Worker     service1.mTxtDataLength       = sizeof(kTxtData1);
3354*cfb92d14SAndroid Build Coastguard Worker     service1.mPort                = 1111;
3355*cfb92d14SAndroid Build Coastguard Worker     service1.mPriority            = 0;
3356*cfb92d14SAndroid Build Coastguard Worker     service1.mWeight              = 0;
3357*cfb92d14SAndroid Build Coastguard Worker     service1.mTtl                 = 1500;
3358*cfb92d14SAndroid Build Coastguard Worker     service1FullName.Append("%s.%s.local.", service1.mServiceInstance, service1.mServiceType);
3359*cfb92d14SAndroid Build Coastguard Worker 
3360*cfb92d14SAndroid Build Coastguard Worker     service2.mHostName            = host1.mHostName;
3361*cfb92d14SAndroid Build Coastguard Worker     service2.mServiceInstance     = "srv2";
3362*cfb92d14SAndroid Build Coastguard Worker     service2.mServiceType         = "_tst._tcp";
3363*cfb92d14SAndroid Build Coastguard Worker     service2.mSubTypeLabels       = nullptr;
3364*cfb92d14SAndroid Build Coastguard Worker     service2.mSubTypeLabelsLength = 0;
3365*cfb92d14SAndroid Build Coastguard Worker     service2.mTxtData             = nullptr;
3366*cfb92d14SAndroid Build Coastguard Worker     service2.mTxtDataLength       = 0;
3367*cfb92d14SAndroid Build Coastguard Worker     service2.mPort                = 2222;
3368*cfb92d14SAndroid Build Coastguard Worker     service2.mPriority            = 2;
3369*cfb92d14SAndroid Build Coastguard Worker     service2.mWeight              = 2;
3370*cfb92d14SAndroid Build Coastguard Worker     service2.mTtl                 = 1500;
3371*cfb92d14SAndroid Build Coastguard Worker     service2FullName.Append("%s.%s.local.", service2.mServiceInstance, service2.mServiceType);
3372*cfb92d14SAndroid Build Coastguard Worker 
3373*cfb92d14SAndroid Build Coastguard Worker     service3.mHostName            = host2.mHostName;
3374*cfb92d14SAndroid Build Coastguard Worker     service3.mServiceInstance     = "srv3";
3375*cfb92d14SAndroid Build Coastguard Worker     service3.mServiceType         = "_srv._udp";
3376*cfb92d14SAndroid Build Coastguard Worker     service3.mSubTypeLabels       = kSubTypes;
3377*cfb92d14SAndroid Build Coastguard Worker     service3.mSubTypeLabelsLength = 1;
3378*cfb92d14SAndroid Build Coastguard Worker     service3.mTxtData             = kTxtData2;
3379*cfb92d14SAndroid Build Coastguard Worker     service3.mTxtDataLength       = sizeof(kTxtData2);
3380*cfb92d14SAndroid Build Coastguard Worker     service3.mPort                = 3333;
3381*cfb92d14SAndroid Build Coastguard Worker     service3.mPriority            = 3;
3382*cfb92d14SAndroid Build Coastguard Worker     service3.mWeight              = 3;
3383*cfb92d14SAndroid Build Coastguard Worker     service3.mTtl                 = 1500;
3384*cfb92d14SAndroid Build Coastguard Worker     service3FullName.Append("%s.%s.local.", service3.mServiceInstance, service3.mServiceType);
3385*cfb92d14SAndroid Build Coastguard Worker 
3386*cfb92d14SAndroid Build Coastguard Worker     key1.mName          = host2.mHostName;
3387*cfb92d14SAndroid Build Coastguard Worker     key1.mServiceType   = nullptr;
3388*cfb92d14SAndroid Build Coastguard Worker     key1.mKeyData       = kKey1;
3389*cfb92d14SAndroid Build Coastguard Worker     key1.mKeyDataLength = sizeof(kKey1);
3390*cfb92d14SAndroid Build Coastguard Worker     key1.mTtl           = 8000;
3391*cfb92d14SAndroid Build Coastguard Worker 
3392*cfb92d14SAndroid Build Coastguard Worker     key2.mName          = service3.mServiceInstance;
3393*cfb92d14SAndroid Build Coastguard Worker     key2.mServiceType   = service3.mServiceType;
3394*cfb92d14SAndroid Build Coastguard Worker     key2.mKeyData       = kKey1;
3395*cfb92d14SAndroid Build Coastguard Worker     key2.mKeyDataLength = sizeof(kKey1);
3396*cfb92d14SAndroid Build Coastguard Worker     key2.mTtl           = 8000;
3397*cfb92d14SAndroid Build Coastguard Worker 
3398*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3399*cfb92d14SAndroid Build Coastguard Worker     Log("Register 2 hosts and 3 services and 2 keys");
3400*cfb92d14SAndroid Build Coastguard Worker 
3401*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3402*cfb92d14SAndroid Build Coastguard Worker 
3403*cfb92d14SAndroid Build Coastguard Worker     for (RegCallback &regCallbck : sRegCallbacks)
3404*cfb92d14SAndroid Build Coastguard Worker     {
3405*cfb92d14SAndroid Build Coastguard Worker         regCallbck.Reset();
3406*cfb92d14SAndroid Build Coastguard Worker     }
3407*cfb92d14SAndroid Build Coastguard Worker 
3408*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host1, 0, HandleSuccessCallback));
3409*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host2, 1, HandleSuccessCallback));
3410*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service1, 2, HandleSuccessCallback));
3411*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service2, 3, HandleSuccessCallback));
3412*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service3, 4, HandleSuccessCallback));
3413*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterKey(key1, 5, HandleSuccessCallback));
3414*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterKey(key2, 6, HandleSuccessCallback));
3415*cfb92d14SAndroid Build Coastguard Worker 
3416*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3417*cfb92d14SAndroid Build Coastguard Worker     Log("Validate probes for all entries");
3418*cfb92d14SAndroid Build Coastguard Worker 
3419*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
3420*cfb92d14SAndroid Build Coastguard Worker     {
3421*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3422*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
3423*cfb92d14SAndroid Build Coastguard Worker 
3424*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
3425*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3426*cfb92d14SAndroid Build Coastguard Worker 
3427*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < 7; index++)
3428*cfb92d14SAndroid Build Coastguard Worker         {
3429*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[index].mWasCalled);
3430*cfb92d14SAndroid Build Coastguard Worker         }
3431*cfb92d14SAndroid Build Coastguard Worker 
3432*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 5, /* Ans */ 0, /* Auth */ 13, /* Addnl */ 0);
3433*cfb92d14SAndroid Build Coastguard Worker 
3434*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host1, /* aUnicastRequest */ (probeCount == 0));
3435*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host2, /* aUnicastRequest */ (probeCount == 0));
3436*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service1, /* aUnicastRequest */ (probeCount == 0));
3437*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service2, /* aUnicastRequest */ (probeCount == 0));
3438*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service3, /* aUnicastRequest */ (probeCount == 0));
3439*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(key1, /* aUnicastRequest */ (probeCount == 0));
3440*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(key2, /* aUnicastRequest */ (probeCount == 0));
3441*cfb92d14SAndroid Build Coastguard Worker 
3442*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3443*cfb92d14SAndroid Build Coastguard Worker     }
3444*cfb92d14SAndroid Build Coastguard Worker 
3445*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3446*cfb92d14SAndroid Build Coastguard Worker     Log("Validate announcements for all entries");
3447*cfb92d14SAndroid Build Coastguard Worker 
3448*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3449*cfb92d14SAndroid Build Coastguard Worker     {
3450*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3451*cfb92d14SAndroid Build Coastguard Worker 
3452*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3453*cfb92d14SAndroid Build Coastguard Worker 
3454*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < 7; index++)
3455*cfb92d14SAndroid Build Coastguard Worker         {
3456*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[index].mWasCalled);
3457*cfb92d14SAndroid Build Coastguard Worker         }
3458*cfb92d14SAndroid Build Coastguard Worker 
3459*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
3460*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3461*cfb92d14SAndroid Build Coastguard Worker 
3462*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 21, /* Auth */ 0, /* Addnl */ 5);
3463*cfb92d14SAndroid Build Coastguard Worker 
3464*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host1, kInAnswerSection);
3465*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host2, kInAnswerSection);
3466*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service1, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3467*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service2, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3468*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service2, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3469*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(key1, kInAnswerSection);
3470*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(key2, kInAnswerSection);
3471*cfb92d14SAndroid Build Coastguard Worker 
3472*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service1.mSubTypeLabelsLength; index++)
3473*cfb92d14SAndroid Build Coastguard Worker         {
3474*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service1.mSubTypeLabels[index], service1);
3475*cfb92d14SAndroid Build Coastguard Worker         }
3476*cfb92d14SAndroid Build Coastguard Worker 
3477*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service3.mSubTypeLabelsLength; index++)
3478*cfb92d14SAndroid Build Coastguard Worker         {
3479*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service3.mSubTypeLabels[index], service3);
3480*cfb92d14SAndroid Build Coastguard Worker         }
3481*cfb92d14SAndroid Build Coastguard Worker 
3482*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3483*cfb92d14SAndroid Build Coastguard Worker     }
3484*cfb92d14SAndroid Build Coastguard Worker 
3485*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3486*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
3487*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3488*cfb92d14SAndroid Build Coastguard Worker 
3489*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3490*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query (browse) for `_srv._udp` and validate two answers and additional data");
3491*cfb92d14SAndroid Build Coastguard Worker 
3492*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3493*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3494*cfb92d14SAndroid Build Coastguard Worker 
3495*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_srv._udp.local.", ResourceRecord::kTypePtr);
3496*cfb92d14SAndroid Build Coastguard Worker 
3497*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3498*cfb92d14SAndroid Build Coastguard Worker 
3499*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3500*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3501*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3502*cfb92d14SAndroid Build Coastguard Worker 
3503*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 9);
3504*cfb92d14SAndroid Build Coastguard Worker 
3505*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckPtr);
3506*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3507*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt);
3508*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3509*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3510*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3511*cfb92d14SAndroid Build Coastguard Worker 
3512*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3513*cfb92d14SAndroid Build Coastguard Worker     Log("Resend the same query but request a unicast response, validate the response");
3514*cfb92d14SAndroid Build Coastguard Worker 
3515*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3516*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_srv._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassInternet | kClassQueryUnicastFlag);
3517*cfb92d14SAndroid Build Coastguard Worker 
3518*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3519*cfb92d14SAndroid Build Coastguard Worker 
3520*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3521*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3522*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3523*cfb92d14SAndroid Build Coastguard Worker 
3524*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kUnicastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 9);
3525*cfb92d14SAndroid Build Coastguard Worker 
3526*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckPtr);
3527*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3528*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt);
3529*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3530*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3531*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3532*cfb92d14SAndroid Build Coastguard Worker 
3533*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3534*cfb92d14SAndroid Build Coastguard Worker     Log("Resend the same multicast query and validate that response is not emitted (rate limit)");
3535*cfb92d14SAndroid Build Coastguard Worker 
3536*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3537*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_srv._udp.local.", ResourceRecord::kTypePtr);
3538*cfb92d14SAndroid Build Coastguard Worker 
3539*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3540*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3541*cfb92d14SAndroid Build Coastguard Worker 
3542*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3543*cfb92d14SAndroid Build Coastguard Worker     Log("Wait for > 1 second and resend the query and validate that now a response is emitted");
3544*cfb92d14SAndroid Build Coastguard Worker 
3545*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_srv._udp.local.", ResourceRecord::kTypePtr);
3546*cfb92d14SAndroid Build Coastguard Worker 
3547*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3548*cfb92d14SAndroid Build Coastguard Worker 
3549*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3550*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3551*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3552*cfb92d14SAndroid Build Coastguard Worker 
3553*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 9);
3554*cfb92d14SAndroid Build Coastguard Worker 
3555*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckPtr);
3556*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3557*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt);
3558*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3559*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3560*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3561*cfb92d14SAndroid Build Coastguard Worker 
3562*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3563*cfb92d14SAndroid Build Coastguard Worker     Log("Browse for sub-type `_s._sub._srv._udp` and validate two answers");
3564*cfb92d14SAndroid Build Coastguard Worker 
3565*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3566*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_s._sub._srv._udp.local.", ResourceRecord::kTypePtr);
3567*cfb92d14SAndroid Build Coastguard Worker 
3568*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3569*cfb92d14SAndroid Build Coastguard Worker 
3570*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3571*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3572*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3573*cfb92d14SAndroid Build Coastguard Worker 
3574*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 9);
3575*cfb92d14SAndroid Build Coastguard Worker 
3576*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateSubType("_s", service1);
3577*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateSubType("_s", service3);
3578*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt);
3579*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3580*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3581*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3582*cfb92d14SAndroid Build Coastguard Worker 
3583*cfb92d14SAndroid Build Coastguard Worker     // Send same query again and make sure it is ignored (rate limit).
3584*cfb92d14SAndroid Build Coastguard Worker 
3585*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3586*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_s._sub._srv._udp.local.", ResourceRecord::kTypePtr);
3587*cfb92d14SAndroid Build Coastguard Worker 
3588*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3589*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3590*cfb92d14SAndroid Build Coastguard Worker 
3591*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3592*cfb92d14SAndroid Build Coastguard Worker     Log("Validate that query with `ANY class` instead of `IN class` is responded");
3593*cfb92d14SAndroid Build Coastguard Worker 
3594*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3595*cfb92d14SAndroid Build Coastguard Worker 
3596*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3597*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_r._sub._srv._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassAny);
3598*cfb92d14SAndroid Build Coastguard Worker 
3599*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3600*cfb92d14SAndroid Build Coastguard Worker 
3601*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3602*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3603*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3604*cfb92d14SAndroid Build Coastguard Worker 
3605*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 5);
3606*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateSubType("_r", service1);
3607*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt);
3608*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3609*cfb92d14SAndroid Build Coastguard Worker 
3610*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3611*cfb92d14SAndroid Build Coastguard Worker     Log("Validate that query with other `class` is ignored");
3612*cfb92d14SAndroid Build Coastguard Worker 
3613*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3614*cfb92d14SAndroid Build Coastguard Worker 
3615*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3616*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_r._sub._srv._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassNone);
3617*cfb92d14SAndroid Build Coastguard Worker 
3618*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3619*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3620*cfb92d14SAndroid Build Coastguard Worker 
3621*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3622*cfb92d14SAndroid Build Coastguard Worker     Log("Validate that query for non-registered name is ignored");
3623*cfb92d14SAndroid Build Coastguard Worker 
3624*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3625*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_u._sub._srv._udp.local.", ResourceRecord::kTypeAny);
3626*cfb92d14SAndroid Build Coastguard Worker     SendQuery("host3.local.", ResourceRecord::kTypeAny);
3627*cfb92d14SAndroid Build Coastguard Worker 
3628*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3629*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3630*cfb92d14SAndroid Build Coastguard Worker 
3631*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3632*cfb92d14SAndroid Build Coastguard Worker     Log("Query for SRV for `srv1._srv._udp` and validate answer and additional data");
3633*cfb92d14SAndroid Build Coastguard Worker 
3634*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3635*cfb92d14SAndroid Build Coastguard Worker 
3636*cfb92d14SAndroid Build Coastguard Worker     SendQuery("srv1._srv._udp.local.", ResourceRecord::kTypeSrv);
3637*cfb92d14SAndroid Build Coastguard Worker 
3638*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3639*cfb92d14SAndroid Build Coastguard Worker 
3640*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3641*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3642*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3643*cfb92d14SAndroid Build Coastguard Worker 
3644*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
3645*cfb92d14SAndroid Build Coastguard Worker 
3646*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckSrv);
3647*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAdditionalSection);
3648*cfb92d14SAndroid Build Coastguard Worker 
3649*cfb92d14SAndroid Build Coastguard Worker     //--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
3650*cfb92d14SAndroid Build Coastguard Worker     // Query with multiple questions
3651*cfb92d14SAndroid Build Coastguard Worker 
3652*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3653*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query with two questions (SRV for service1 and AAAA for host1). Validate response");
3654*cfb92d14SAndroid Build Coastguard Worker 
3655*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3656*cfb92d14SAndroid Build Coastguard Worker 
3657*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3658*cfb92d14SAndroid Build Coastguard Worker     SendQueryForTwo("srv1._srv._udp.local.", ResourceRecord::kTypeSrv, "host1.local.", ResourceRecord::kTypeAaaa);
3659*cfb92d14SAndroid Build Coastguard Worker 
3660*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3661*cfb92d14SAndroid Build Coastguard Worker 
3662*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3663*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3664*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3665*cfb92d14SAndroid Build Coastguard Worker 
3666*cfb92d14SAndroid Build Coastguard Worker     // Since AAAA record are already present in Answer they should not be appended
3667*cfb92d14SAndroid Build Coastguard Worker     // in Additional anymore (for the SRV query).
3668*cfb92d14SAndroid Build Coastguard Worker 
3669*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 2);
3670*cfb92d14SAndroid Build Coastguard Worker 
3671*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckSrv);
3672*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host1, kInAnswerSection);
3673*cfb92d14SAndroid Build Coastguard Worker 
3674*cfb92d14SAndroid Build Coastguard Worker     //--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
3675*cfb92d14SAndroid Build Coastguard Worker     // Known-answer suppression
3676*cfb92d14SAndroid Build Coastguard Worker 
3677*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3678*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query for `_srv._udp` and include `srv1` as known-answer and validate response");
3679*cfb92d14SAndroid Build Coastguard Worker 
3680*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mPtrAnswer = "srv1._srv._udp.local.";
3681*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mTtl       = 1500;
3682*cfb92d14SAndroid Build Coastguard Worker 
3683*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3684*cfb92d14SAndroid Build Coastguard Worker 
3685*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3686*cfb92d14SAndroid Build Coastguard Worker     SendPtrQueryWithKnownAnswers("_srv._udp.local.", knownAnswers, 1);
3687*cfb92d14SAndroid Build Coastguard Worker 
3688*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3689*cfb92d14SAndroid Build Coastguard Worker 
3690*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3691*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3692*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3693*cfb92d14SAndroid Build Coastguard Worker 
3694*cfb92d14SAndroid Build Coastguard Worker     // Response should include `service3` only
3695*cfb92d14SAndroid Build Coastguard Worker 
3696*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
3697*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3698*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3699*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3700*cfb92d14SAndroid Build Coastguard Worker 
3701*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3702*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query again with both services as known-answer, validate no response is emitted");
3703*cfb92d14SAndroid Build Coastguard Worker 
3704*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mPtrAnswer = "srv3._srv._udp.local.";
3705*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mTtl       = 1500;
3706*cfb92d14SAndroid Build Coastguard Worker 
3707*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3708*cfb92d14SAndroid Build Coastguard Worker 
3709*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3710*cfb92d14SAndroid Build Coastguard Worker     SendPtrQueryWithKnownAnswers("_srv._udp.local.", knownAnswers, 2);
3711*cfb92d14SAndroid Build Coastguard Worker 
3712*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3713*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3714*cfb92d14SAndroid Build Coastguard Worker 
3715*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3716*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query for `_srv._udp` and include `srv1` as known-answer and validate response");
3717*cfb92d14SAndroid Build Coastguard Worker 
3718*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mPtrAnswer = "srv1._srv._udp.local.";
3719*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mTtl       = 1500;
3720*cfb92d14SAndroid Build Coastguard Worker 
3721*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3722*cfb92d14SAndroid Build Coastguard Worker 
3723*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3724*cfb92d14SAndroid Build Coastguard Worker     SendPtrQueryWithKnownAnswers("_srv._udp.local.", knownAnswers, 1);
3725*cfb92d14SAndroid Build Coastguard Worker 
3726*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3727*cfb92d14SAndroid Build Coastguard Worker 
3728*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3729*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3730*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3731*cfb92d14SAndroid Build Coastguard Worker 
3732*cfb92d14SAndroid Build Coastguard Worker     // Response should include `service3` only
3733*cfb92d14SAndroid Build Coastguard Worker 
3734*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
3735*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3736*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3737*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3738*cfb92d14SAndroid Build Coastguard Worker 
3739*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3740*cfb92d14SAndroid Build Coastguard Worker     Log("Change the TTL for known-answer to less than half of record TTL and validate response");
3741*cfb92d14SAndroid Build Coastguard Worker 
3742*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mTtl = 1500 / 2 - 1;
3743*cfb92d14SAndroid Build Coastguard Worker 
3744*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3745*cfb92d14SAndroid Build Coastguard Worker 
3746*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3747*cfb92d14SAndroid Build Coastguard Worker     SendPtrQueryWithKnownAnswers("_srv._udp.local.", knownAnswers, 2);
3748*cfb92d14SAndroid Build Coastguard Worker 
3749*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3750*cfb92d14SAndroid Build Coastguard Worker 
3751*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3752*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3753*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3754*cfb92d14SAndroid Build Coastguard Worker 
3755*cfb92d14SAndroid Build Coastguard Worker     // Response should include `service3` only since anwer TTL
3756*cfb92d14SAndroid Build Coastguard Worker     // is less than half of registered TTL
3757*cfb92d14SAndroid Build Coastguard Worker 
3758*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
3759*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAnswerSection, kCheckPtr);
3760*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt);
3761*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host2, kInAdditionalSection);
3762*cfb92d14SAndroid Build Coastguard Worker 
3763*cfb92d14SAndroid Build Coastguard Worker     //--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
3764*cfb92d14SAndroid Build Coastguard Worker     // Query during Goodbye announcements
3765*cfb92d14SAndroid Build Coastguard Worker 
3766*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3767*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister `service1` and wait for its two announcements and validate them");
3768*cfb92d14SAndroid Build Coastguard Worker 
3769*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3770*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterService(service1));
3771*cfb92d14SAndroid Build Coastguard Worker 
3772*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces - 1; anncCount++)
3773*cfb92d14SAndroid Build Coastguard Worker     {
3774*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3775*cfb92d14SAndroid Build Coastguard Worker 
3776*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3777*cfb92d14SAndroid Build Coastguard Worker 
3778*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3779*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
3780*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3781*cfb92d14SAndroid Build Coastguard Worker 
3782*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 5, /* Auth */ 0, /* Addnl */ 0);
3783*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service1, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
3784*cfb92d14SAndroid Build Coastguard Worker 
3785*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service1.mSubTypeLabelsLength; index++)
3786*cfb92d14SAndroid Build Coastguard Worker         {
3787*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service1.mSubTypeLabels[index], service1, kGoodBye);
3788*cfb92d14SAndroid Build Coastguard Worker         }
3789*cfb92d14SAndroid Build Coastguard Worker     }
3790*cfb92d14SAndroid Build Coastguard Worker 
3791*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3792*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for removed `service1` before its final announcement, validate no response");
3793*cfb92d14SAndroid Build Coastguard Worker 
3794*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3795*cfb92d14SAndroid Build Coastguard Worker 
3796*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1100);
3797*cfb92d14SAndroid Build Coastguard Worker     SendQuery("srv1._srv._udp.local.", ResourceRecord::kTypeSrv);
3798*cfb92d14SAndroid Build Coastguard Worker 
3799*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
3800*cfb92d14SAndroid Build Coastguard Worker 
3801*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3802*cfb92d14SAndroid Build Coastguard Worker 
3803*cfb92d14SAndroid Build Coastguard Worker     // Wait for final announcement and validate it
3804*cfb92d14SAndroid Build Coastguard Worker 
3805*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3806*cfb92d14SAndroid Build Coastguard Worker 
3807*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3808*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3809*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3810*cfb92d14SAndroid Build Coastguard Worker 
3811*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 5, /* Auth */ 0, /* Addnl */ 0);
3812*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service1, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr, kGoodBye);
3813*cfb92d14SAndroid Build Coastguard Worker 
3814*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0; index < service1.mSubTypeLabelsLength; index++)
3815*cfb92d14SAndroid Build Coastguard Worker     {
3816*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateSubType(service1.mSubTypeLabels[index], service1, kGoodBye);
3817*cfb92d14SAndroid Build Coastguard Worker     }
3818*cfb92d14SAndroid Build Coastguard Worker 
3819*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
3820*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
3821*cfb92d14SAndroid Build Coastguard Worker 
3822*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
3823*cfb92d14SAndroid Build Coastguard Worker 
3824*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
3825*cfb92d14SAndroid Build Coastguard Worker }
3826*cfb92d14SAndroid Build Coastguard Worker 
3827*cfb92d14SAndroid Build Coastguard Worker //----------------------------------------------------------------------------------------------------------------------
3828*cfb92d14SAndroid Build Coastguard Worker 
TestMultiPacket(void)3829*cfb92d14SAndroid Build Coastguard Worker void TestMultiPacket(void)
3830*cfb92d14SAndroid Build Coastguard Worker {
3831*cfb92d14SAndroid Build Coastguard Worker     static const char *const kSubTypes[] = {"_s1", "_r2", "vxy"};
3832*cfb92d14SAndroid Build Coastguard Worker 
3833*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
3834*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
3835*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
3836*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
3837*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceName;
3838*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceType;
3839*cfb92d14SAndroid Build Coastguard Worker     KnownAnswer       knownAnswers[2];
3840*cfb92d14SAndroid Build Coastguard Worker 
3841*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
3842*cfb92d14SAndroid Build Coastguard Worker     Log("TestMultiPacket");
3843*cfb92d14SAndroid Build Coastguard Worker 
3844*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
3845*cfb92d14SAndroid Build Coastguard Worker 
3846*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
3847*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
3848*cfb92d14SAndroid Build Coastguard Worker 
3849*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "myhost";
3850*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "mysrv";
3851*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_tst._udp";
3852*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = kSubTypes;
3853*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 3;
3854*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
3855*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
3856*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 2222;
3857*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 3;
3858*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 4;
3859*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 2000;
3860*cfb92d14SAndroid Build Coastguard Worker 
3861*cfb92d14SAndroid Build Coastguard Worker     fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
3862*cfb92d14SAndroid Build Coastguard Worker     fullServiceType.Append("%s.local.", service.mServiceType);
3863*cfb92d14SAndroid Build Coastguard Worker 
3864*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3865*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `ServiceEntry` with sub-types, check probes and announcements");
3866*cfb92d14SAndroid Build Coastguard Worker 
3867*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3868*cfb92d14SAndroid Build Coastguard Worker 
3869*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
3870*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
3871*cfb92d14SAndroid Build Coastguard Worker 
3872*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
3873*cfb92d14SAndroid Build Coastguard Worker     {
3874*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3875*cfb92d14SAndroid Build Coastguard Worker 
3876*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
3877*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
3878*cfb92d14SAndroid Build Coastguard Worker 
3879*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
3880*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3881*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
3882*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
3883*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3884*cfb92d14SAndroid Build Coastguard Worker     }
3885*cfb92d14SAndroid Build Coastguard Worker 
3886*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
3887*cfb92d14SAndroid Build Coastguard Worker     {
3888*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
3889*cfb92d14SAndroid Build Coastguard Worker 
3890*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
3891*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
3892*cfb92d14SAndroid Build Coastguard Worker 
3893*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
3894*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
3895*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 7, /* Auth */ 0, /* Addnl */ 1);
3896*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
3897*cfb92d14SAndroid Build Coastguard Worker 
3898*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < service.mSubTypeLabelsLength; index++)
3899*cfb92d14SAndroid Build Coastguard Worker         {
3900*cfb92d14SAndroid Build Coastguard Worker             dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service);
3901*cfb92d14SAndroid Build Coastguard Worker         }
3902*cfb92d14SAndroid Build Coastguard Worker 
3903*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
3904*cfb92d14SAndroid Build Coastguard Worker     }
3905*cfb92d14SAndroid Build Coastguard Worker 
3906*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3907*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for service type and validate the response");
3908*cfb92d14SAndroid Build Coastguard Worker 
3909*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3910*cfb92d14SAndroid Build Coastguard Worker 
3911*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3912*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr);
3913*cfb92d14SAndroid Build Coastguard Worker 
3914*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3915*cfb92d14SAndroid Build Coastguard Worker 
3916*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3917*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3918*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
3919*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
3920*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
3921*cfb92d14SAndroid Build Coastguard Worker 
3922*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3923*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query again but mark it as truncated");
3924*cfb92d14SAndroid Build Coastguard Worker 
3925*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3926*cfb92d14SAndroid Build Coastguard Worker 
3927*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3928*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
3929*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
3930*cfb92d14SAndroid Build Coastguard Worker 
3931*cfb92d14SAndroid Build Coastguard Worker     Log("Since message is marked as `truncated`, mDNS should wait at least 400 msec");
3932*cfb92d14SAndroid Build Coastguard Worker 
3933*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(400);
3934*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3935*cfb92d14SAndroid Build Coastguard Worker 
3936*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3937*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3938*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3939*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
3940*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
3941*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
3942*cfb92d14SAndroid Build Coastguard Worker 
3943*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3944*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query again as truncated followed-up by a non-matching answer");
3945*cfb92d14SAndroid Build Coastguard Worker 
3946*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3947*cfb92d14SAndroid Build Coastguard Worker 
3948*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3949*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
3950*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
3951*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
3952*cfb92d14SAndroid Build Coastguard Worker 
3953*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mPtrAnswer = "other._tst._udp.local.";
3954*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mTtl       = 1500;
3955*cfb92d14SAndroid Build Coastguard Worker 
3956*cfb92d14SAndroid Build Coastguard Worker     SendEmtryPtrQueryWithKnownAnswers(fullServiceType.AsCString(), knownAnswers, 1);
3957*cfb92d14SAndroid Build Coastguard Worker 
3958*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3959*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3960*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3961*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2);
3962*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
3963*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
3964*cfb92d14SAndroid Build Coastguard Worker 
3965*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3966*cfb92d14SAndroid Build Coastguard Worker     Log("Send a PTR query again as truncated now followed-up by matching known-answer");
3967*cfb92d14SAndroid Build Coastguard Worker 
3968*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3969*cfb92d14SAndroid Build Coastguard Worker 
3970*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3971*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
3972*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
3973*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
3974*cfb92d14SAndroid Build Coastguard Worker 
3975*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mPtrAnswer = "mysrv._tst._udp.local.";
3976*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mTtl       = 1500;
3977*cfb92d14SAndroid Build Coastguard Worker 
3978*cfb92d14SAndroid Build Coastguard Worker     SendEmtryPtrQueryWithKnownAnswers(fullServiceType.AsCString(), knownAnswers, 2);
3979*cfb92d14SAndroid Build Coastguard Worker 
3980*cfb92d14SAndroid Build Coastguard Worker     Log("We expect no response since the followed-up message contains a matching known-answer");
3981*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
3982*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
3983*cfb92d14SAndroid Build Coastguard Worker 
3984*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
3985*cfb92d14SAndroid Build Coastguard Worker     Log("Send a truncated query for PTR record for `services._dns-sd`");
3986*cfb92d14SAndroid Build Coastguard Worker 
3987*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
3988*cfb92d14SAndroid Build Coastguard Worker 
3989*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
3990*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_services._dns-sd._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
3991*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
3992*cfb92d14SAndroid Build Coastguard Worker 
3993*cfb92d14SAndroid Build Coastguard Worker     Log("Response should be sent after longer wait time");
3994*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
3995*cfb92d14SAndroid Build Coastguard Worker 
3996*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
3997*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
3998*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
3999*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckServicesPtr);
4000*cfb92d14SAndroid Build Coastguard Worker 
4001*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4002*cfb92d14SAndroid Build Coastguard Worker     Log("Send a truncated query for PTR record for `services._dns-sd` folloed by known-aswer");
4003*cfb92d14SAndroid Build Coastguard Worker 
4004*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
4005*cfb92d14SAndroid Build Coastguard Worker 
4006*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4007*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_services._dns-sd._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
4008*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
4009*cfb92d14SAndroid Build Coastguard Worker 
4010*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20);
4011*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mPtrAnswer = "_other._udp.local.";
4012*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[0].mTtl       = 4500;
4013*cfb92d14SAndroid Build Coastguard Worker 
4014*cfb92d14SAndroid Build Coastguard Worker     SendEmtryPtrQueryWithKnownAnswers("_services._dns-sd._udp.local.", knownAnswers, 1);
4015*cfb92d14SAndroid Build Coastguard Worker 
4016*cfb92d14SAndroid Build Coastguard Worker     Log("Response should be sent again due to answer not matching");
4017*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
4018*cfb92d14SAndroid Build Coastguard Worker 
4019*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
4020*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
4021*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
4022*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckServicesPtr);
4023*cfb92d14SAndroid Build Coastguard Worker 
4024*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4025*cfb92d14SAndroid Build Coastguard Worker     Log("Send the same truncated query again but follow-up with a matching known-answer message");
4026*cfb92d14SAndroid Build Coastguard Worker 
4027*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
4028*cfb92d14SAndroid Build Coastguard Worker 
4029*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4030*cfb92d14SAndroid Build Coastguard Worker     SendQuery("_services._dns-sd._udp.local.", ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
4031*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ true);
4032*cfb92d14SAndroid Build Coastguard Worker 
4033*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20);
4034*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mPtrAnswer = "_tst._udp.local.";
4035*cfb92d14SAndroid Build Coastguard Worker     knownAnswers[1].mTtl       = 4500;
4036*cfb92d14SAndroid Build Coastguard Worker 
4037*cfb92d14SAndroid Build Coastguard Worker     SendEmtryPtrQueryWithKnownAnswers("_services._dns-sd._udp.local.", knownAnswers, 2);
4038*cfb92d14SAndroid Build Coastguard Worker 
4039*cfb92d14SAndroid Build Coastguard Worker     Log("We expect no response since the followed-up message contains a matching known-answer");
4040*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
4041*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4042*cfb92d14SAndroid Build Coastguard Worker 
4043*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
4044*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4045*cfb92d14SAndroid Build Coastguard Worker 
4046*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
4047*cfb92d14SAndroid Build Coastguard Worker 
4048*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
4049*cfb92d14SAndroid Build Coastguard Worker }
4050*cfb92d14SAndroid Build Coastguard Worker 
4051*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
4052*cfb92d14SAndroid Build Coastguard Worker 
TestQuestionUnicastDisallowed(void)4053*cfb92d14SAndroid Build Coastguard Worker void TestQuestionUnicastDisallowed(void)
4054*cfb92d14SAndroid Build Coastguard Worker {
4055*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
4056*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
4057*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[1];
4058*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
4059*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
4060*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     hostFullName;
4061*cfb92d14SAndroid Build Coastguard Worker 
4062*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
4063*cfb92d14SAndroid Build Coastguard Worker     Log("TestQuestionUnicastDisallowed");
4064*cfb92d14SAndroid Build Coastguard Worker 
4065*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4066*cfb92d14SAndroid Build Coastguard Worker 
4067*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
4068*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
4069*cfb92d14SAndroid Build Coastguard Worker 
4070*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::1234"));
4071*cfb92d14SAndroid Build Coastguard Worker 
4072*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
4073*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
4074*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 1;
4075*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
4076*cfb92d14SAndroid Build Coastguard Worker 
4077*cfb92d14SAndroid Build Coastguard Worker     mdns->SetQuestionUnicastAllowed(false);
4078*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!mdns->IsQuestionUnicastAllowed());
4079*cfb92d14SAndroid Build Coastguard Worker 
4080*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4081*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `HostEntry`, check probes and announcements");
4082*cfb92d14SAndroid Build Coastguard Worker 
4083*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4084*cfb92d14SAndroid Build Coastguard Worker 
4085*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
4086*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
4087*cfb92d14SAndroid Build Coastguard Worker 
4088*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
4089*cfb92d14SAndroid Build Coastguard Worker     {
4090*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4091*cfb92d14SAndroid Build Coastguard Worker 
4092*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4093*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4094*cfb92d14SAndroid Build Coastguard Worker 
4095*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4096*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4097*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 1, /* Addnl */ 0);
4098*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ false);
4099*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4100*cfb92d14SAndroid Build Coastguard Worker     }
4101*cfb92d14SAndroid Build Coastguard Worker 
4102*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
4103*cfb92d14SAndroid Build Coastguard Worker     {
4104*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4105*cfb92d14SAndroid Build Coastguard Worker 
4106*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
4107*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4108*cfb92d14SAndroid Build Coastguard Worker 
4109*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4110*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4111*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
4112*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
4113*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4114*cfb92d14SAndroid Build Coastguard Worker     }
4115*cfb92d14SAndroid Build Coastguard Worker 
4116*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4117*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
4118*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4119*cfb92d14SAndroid Build Coastguard Worker 
4120*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
4121*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4122*cfb92d14SAndroid Build Coastguard Worker 
4123*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
4124*cfb92d14SAndroid Build Coastguard Worker 
4125*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
4126*cfb92d14SAndroid Build Coastguard Worker }
4127*cfb92d14SAndroid Build Coastguard Worker 
4128*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
4129*cfb92d14SAndroid Build Coastguard Worker 
TestTxMessageSizeLimit(void)4130*cfb92d14SAndroid Build Coastguard Worker void TestTxMessageSizeLimit(void)
4131*cfb92d14SAndroid Build Coastguard Worker {
4132*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
4133*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
4134*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
4135*cfb92d14SAndroid Build Coastguard Worker     Core::Key         hostKey;
4136*cfb92d14SAndroid Build Coastguard Worker     Core::Key         serviceKey;
4137*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[3];
4138*cfb92d14SAndroid Build Coastguard Worker     uint8_t           keyData[300];
4139*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
4140*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
4141*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     hostFullName;
4142*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     serviceFullName;
4143*cfb92d14SAndroid Build Coastguard Worker 
4144*cfb92d14SAndroid Build Coastguard Worker     memset(keyData, 1, sizeof(keyData));
4145*cfb92d14SAndroid Build Coastguard Worker 
4146*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
4147*cfb92d14SAndroid Build Coastguard Worker     Log("TestTxMessageSizeLimit");
4148*cfb92d14SAndroid Build Coastguard Worker 
4149*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4150*cfb92d14SAndroid Build Coastguard Worker 
4151*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
4152*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
4153*cfb92d14SAndroid Build Coastguard Worker 
4154*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::1:aaaa"));
4155*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::1:bbbb"));
4156*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[2].FromString("fd00::1:cccc"));
4157*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
4158*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
4159*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 3;
4160*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
4161*cfb92d14SAndroid Build Coastguard Worker     hostFullName.Append("%s.local.", host.mHostName);
4162*cfb92d14SAndroid Build Coastguard Worker 
4163*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = host.mHostName;
4164*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "mysrv";
4165*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
4166*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
4167*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
4168*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
4169*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
4170*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1111;
4171*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 0;
4172*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 0;
4173*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1500;
4174*cfb92d14SAndroid Build Coastguard Worker     serviceFullName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
4175*cfb92d14SAndroid Build Coastguard Worker 
4176*cfb92d14SAndroid Build Coastguard Worker     hostKey.mName          = host.mHostName;
4177*cfb92d14SAndroid Build Coastguard Worker     hostKey.mServiceType   = nullptr;
4178*cfb92d14SAndroid Build Coastguard Worker     hostKey.mKeyData       = keyData;
4179*cfb92d14SAndroid Build Coastguard Worker     hostKey.mKeyDataLength = 300;
4180*cfb92d14SAndroid Build Coastguard Worker     hostKey.mTtl           = 8000;
4181*cfb92d14SAndroid Build Coastguard Worker 
4182*cfb92d14SAndroid Build Coastguard Worker     serviceKey.mName          = service.mServiceInstance;
4183*cfb92d14SAndroid Build Coastguard Worker     serviceKey.mServiceType   = service.mServiceType;
4184*cfb92d14SAndroid Build Coastguard Worker     serviceKey.mKeyData       = keyData;
4185*cfb92d14SAndroid Build Coastguard Worker     serviceKey.mKeyDataLength = 300;
4186*cfb92d14SAndroid Build Coastguard Worker     serviceKey.mTtl           = 8000;
4187*cfb92d14SAndroid Build Coastguard Worker 
4188*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4189*cfb92d14SAndroid Build Coastguard Worker     Log("Set `MaxMessageSize` to 340 and use large key record data to trigger size limit behavior");
4190*cfb92d14SAndroid Build Coastguard Worker 
4191*cfb92d14SAndroid Build Coastguard Worker     mdns->SetMaxMessageSize(340);
4192*cfb92d14SAndroid Build Coastguard Worker 
4193*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4194*cfb92d14SAndroid Build Coastguard Worker     Log("Register host and service and keys for each");
4195*cfb92d14SAndroid Build Coastguard Worker 
4196*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4197*cfb92d14SAndroid Build Coastguard Worker 
4198*cfb92d14SAndroid Build Coastguard Worker     for (RegCallback &regCallbck : sRegCallbacks)
4199*cfb92d14SAndroid Build Coastguard Worker     {
4200*cfb92d14SAndroid Build Coastguard Worker         regCallbck.Reset();
4201*cfb92d14SAndroid Build Coastguard Worker     }
4202*cfb92d14SAndroid Build Coastguard Worker 
4203*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
4204*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
4205*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterKey(hostKey, 2, HandleSuccessCallback));
4206*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterKey(serviceKey, 3, HandleSuccessCallback));
4207*cfb92d14SAndroid Build Coastguard Worker 
4208*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4209*cfb92d14SAndroid Build Coastguard Worker     Log("Validate probes for all entries");
4210*cfb92d14SAndroid Build Coastguard Worker     Log("Probes for host and service should be broken into separate message due to size limit");
4211*cfb92d14SAndroid Build Coastguard Worker 
4212*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
4213*cfb92d14SAndroid Build Coastguard Worker     {
4214*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4215*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4216*cfb92d14SAndroid Build Coastguard Worker 
4217*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4218*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4219*cfb92d14SAndroid Build Coastguard Worker 
4220*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < 4; index++)
4221*cfb92d14SAndroid Build Coastguard Worker         {
4222*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!sRegCallbacks[index].mWasCalled);
4223*cfb92d14SAndroid Build Coastguard Worker         }
4224*cfb92d14SAndroid Build Coastguard Worker 
4225*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 4, /* Addnl */ 0);
4226*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ (probeCount == 0));
4227*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(hostKey, /* aUnicastRequest */ (probeCount == 0));
4228*cfb92d14SAndroid Build Coastguard Worker 
4229*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
4230*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
4231*cfb92d14SAndroid Build Coastguard Worker 
4232*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 3, /* Addnl */ 0);
4233*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
4234*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(serviceKey, /* aUnicastRequest */ (probeCount == 0));
4235*cfb92d14SAndroid Build Coastguard Worker 
4236*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4237*cfb92d14SAndroid Build Coastguard Worker     }
4238*cfb92d14SAndroid Build Coastguard Worker 
4239*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4240*cfb92d14SAndroid Build Coastguard Worker     Log("Validate announcements for all entries");
4241*cfb92d14SAndroid Build Coastguard Worker     Log("Announces should also be broken into separate message due to size limit");
4242*cfb92d14SAndroid Build Coastguard Worker 
4243*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
4244*cfb92d14SAndroid Build Coastguard Worker     {
4245*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4246*cfb92d14SAndroid Build Coastguard Worker 
4247*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
4248*cfb92d14SAndroid Build Coastguard Worker 
4249*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < 4; index++)
4250*cfb92d14SAndroid Build Coastguard Worker         {
4251*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(sRegCallbacks[index].mWasCalled);
4252*cfb92d14SAndroid Build Coastguard Worker         }
4253*cfb92d14SAndroid Build Coastguard Worker 
4254*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4255*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4256*cfb92d14SAndroid Build Coastguard Worker 
4257*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 1);
4258*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
4259*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(hostKey, kInAnswerSection);
4260*cfb92d14SAndroid Build Coastguard Worker 
4261*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
4262*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
4263*cfb92d14SAndroid Build Coastguard Worker 
4264*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 4);
4265*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr);
4266*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(serviceKey, kInAnswerSection);
4267*cfb92d14SAndroid Build Coastguard Worker 
4268*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
4269*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
4270*cfb92d14SAndroid Build Coastguard Worker 
4271*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
4272*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckServicesPtr);
4273*cfb92d14SAndroid Build Coastguard Worker 
4274*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4275*cfb92d14SAndroid Build Coastguard Worker     }
4276*cfb92d14SAndroid Build Coastguard Worker 
4277*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
4278*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4279*cfb92d14SAndroid Build Coastguard Worker 
4280*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
4281*cfb92d14SAndroid Build Coastguard Worker 
4282*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
4283*cfb92d14SAndroid Build Coastguard Worker }
4284*cfb92d14SAndroid Build Coastguard Worker 
4285*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
4286*cfb92d14SAndroid Build Coastguard Worker 
TestHostConflict(void)4287*cfb92d14SAndroid Build Coastguard Worker void TestHostConflict(void)
4288*cfb92d14SAndroid Build Coastguard Worker {
4289*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
4290*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
4291*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[2];
4292*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
4293*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
4294*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     hostFullName;
4295*cfb92d14SAndroid Build Coastguard Worker 
4296*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
4297*cfb92d14SAndroid Build Coastguard Worker     Log("TestHostConflict");
4298*cfb92d14SAndroid Build Coastguard Worker 
4299*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4300*cfb92d14SAndroid Build Coastguard Worker 
4301*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
4302*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
4303*cfb92d14SAndroid Build Coastguard Worker 
4304*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::1"));
4305*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::2"));
4306*cfb92d14SAndroid Build Coastguard Worker 
4307*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "myhost";
4308*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
4309*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 2;
4310*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
4311*cfb92d14SAndroid Build Coastguard Worker 
4312*cfb92d14SAndroid Build Coastguard Worker     hostFullName.Append("%s.local.", host.mHostName);
4313*cfb92d14SAndroid Build Coastguard Worker 
4314*cfb92d14SAndroid Build Coastguard Worker     // Run the test twice, first run send response with record in Answer section,
4315*cfb92d14SAndroid Build Coastguard Worker     // section run in Additional Data section.
4316*cfb92d14SAndroid Build Coastguard Worker 
4317*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4318*cfb92d14SAndroid Build Coastguard Worker     mdns->SetConflictCallback(HandleConflict);
4319*cfb92d14SAndroid Build Coastguard Worker 
4320*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
4321*cfb92d14SAndroid Build Coastguard Worker     {
4322*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4323*cfb92d14SAndroid Build Coastguard Worker         Log("Register a `HostEntry`, wait for first probe");
4324*cfb92d14SAndroid Build Coastguard Worker 
4325*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4326*cfb92d14SAndroid Build Coastguard Worker 
4327*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[0].Reset();
4328*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterHost(host, 0, HandleCallback));
4329*cfb92d14SAndroid Build Coastguard Worker 
4330*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4331*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4332*cfb92d14SAndroid Build Coastguard Worker 
4333*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4334*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4335*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
4336*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ true);
4337*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4338*cfb92d14SAndroid Build Coastguard Worker 
4339*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4340*cfb92d14SAndroid Build Coastguard Worker         Log("Send a response claiming the name with record in %s section", (iter == 0) ? "answer" : "additional");
4341*cfb92d14SAndroid Build Coastguard Worker 
4342*cfb92d14SAndroid Build Coastguard Worker         SendResponseWithEmptyKey(hostFullName.AsCString(), (iter == 0) ? kInAnswerSection : kInAdditionalSection);
4343*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1);
4344*cfb92d14SAndroid Build Coastguard Worker 
4345*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4346*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mError == kErrorDuplicated);
4347*cfb92d14SAndroid Build Coastguard Worker 
4348*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sConflictCallback.mWasCalled);
4349*cfb92d14SAndroid Build Coastguard Worker 
4350*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4351*cfb92d14SAndroid Build Coastguard Worker 
4352*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->UnregisterHost(host));
4353*cfb92d14SAndroid Build Coastguard Worker 
4354*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
4355*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
4356*cfb92d14SAndroid Build Coastguard Worker     }
4357*cfb92d14SAndroid Build Coastguard Worker 
4358*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4359*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `HostEntry` and respond to probe to trigger conflict");
4360*cfb92d14SAndroid Build Coastguard Worker 
4361*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
4362*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleCallback));
4363*cfb92d14SAndroid Build Coastguard Worker 
4364*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4365*cfb92d14SAndroid Build Coastguard Worker 
4366*cfb92d14SAndroid Build Coastguard Worker     SendResponseWithEmptyKey(hostFullName.AsCString(), kInAnswerSection);
4367*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4368*cfb92d14SAndroid Build Coastguard Worker 
4369*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4370*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[0].mError == kErrorDuplicated);
4371*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4372*cfb92d14SAndroid Build Coastguard Worker 
4373*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4374*cfb92d14SAndroid Build Coastguard Worker     Log("Register the conflicted `HostEntry` again, and make sure no probes are sent");
4375*cfb92d14SAndroid Build Coastguard Worker 
4376*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
4377*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4378*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4379*cfb92d14SAndroid Build Coastguard Worker 
4380*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 1, HandleCallback));
4381*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
4382*cfb92d14SAndroid Build Coastguard Worker 
4383*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[1].mWasCalled);
4384*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[1].mError == kErrorDuplicated);
4385*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4386*cfb92d14SAndroid Build Coastguard Worker 
4387*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4388*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister the conflicted host and register it again immediately, make sure we see probes");
4389*cfb92d14SAndroid Build Coastguard Worker 
4390*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterHost(host));
4391*cfb92d14SAndroid Build Coastguard Worker 
4392*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4393*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
4394*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
4395*cfb92d14SAndroid Build Coastguard Worker 
4396*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
4397*cfb92d14SAndroid Build Coastguard Worker     {
4398*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4399*cfb92d14SAndroid Build Coastguard Worker 
4400*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4401*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4402*cfb92d14SAndroid Build Coastguard Worker 
4403*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4404*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4405*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
4406*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(host, /* aUnicastRequest */ (probeCount == 0));
4407*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4408*cfb92d14SAndroid Build Coastguard Worker     }
4409*cfb92d14SAndroid Build Coastguard Worker 
4410*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
4411*cfb92d14SAndroid Build Coastguard Worker     {
4412*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4413*cfb92d14SAndroid Build Coastguard Worker 
4414*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
4415*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4416*cfb92d14SAndroid Build Coastguard Worker 
4417*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4418*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4419*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 1);
4420*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(host, kInAnswerSection);
4421*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4422*cfb92d14SAndroid Build Coastguard Worker     }
4423*cfb92d14SAndroid Build Coastguard Worker 
4424*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4425*cfb92d14SAndroid Build Coastguard Worker 
4426*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4427*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response for host name and validate that conflict is detected and callback is called");
4428*cfb92d14SAndroid Build Coastguard Worker 
4429*cfb92d14SAndroid Build Coastguard Worker     SendResponseWithEmptyKey(hostFullName.AsCString(), kInAnswerSection);
4430*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4431*cfb92d14SAndroid Build Coastguard Worker 
4432*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sConflictCallback.mWasCalled);
4433*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(StringMatch(sConflictCallback.mName.AsCString(), host.mHostName, kStringCaseInsensitiveMatch));
4434*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mHasServiceType);
4435*cfb92d14SAndroid Build Coastguard Worker 
4436*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
4437*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4438*cfb92d14SAndroid Build Coastguard Worker 
4439*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
4440*cfb92d14SAndroid Build Coastguard Worker 
4441*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
4442*cfb92d14SAndroid Build Coastguard Worker }
4443*cfb92d14SAndroid Build Coastguard Worker 
4444*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
4445*cfb92d14SAndroid Build Coastguard Worker 
TestServiceConflict(void)4446*cfb92d14SAndroid Build Coastguard Worker void TestServiceConflict(void)
4447*cfb92d14SAndroid Build Coastguard Worker {
4448*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
4449*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
4450*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
4451*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
4452*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceName;
4453*cfb92d14SAndroid Build Coastguard Worker 
4454*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
4455*cfb92d14SAndroid Build Coastguard Worker     Log("TestServiceConflict");
4456*cfb92d14SAndroid Build Coastguard Worker 
4457*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = "myhost";
4458*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "myservice";
4459*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
4460*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
4461*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
4462*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
4463*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
4464*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
4465*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
4466*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
4467*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1000;
4468*cfb92d14SAndroid Build Coastguard Worker 
4469*cfb92d14SAndroid Build Coastguard Worker     fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
4470*cfb92d14SAndroid Build Coastguard Worker 
4471*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4472*cfb92d14SAndroid Build Coastguard Worker 
4473*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
4474*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
4475*cfb92d14SAndroid Build Coastguard Worker 
4476*cfb92d14SAndroid Build Coastguard Worker     // Run the test twice, first run send response with record in Answer section,
4477*cfb92d14SAndroid Build Coastguard Worker     // section run in Additional Data section.
4478*cfb92d14SAndroid Build Coastguard Worker 
4479*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4480*cfb92d14SAndroid Build Coastguard Worker     mdns->SetConflictCallback(HandleConflict);
4481*cfb92d14SAndroid Build Coastguard Worker 
4482*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
4483*cfb92d14SAndroid Build Coastguard Worker     {
4484*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4485*cfb92d14SAndroid Build Coastguard Worker         Log("Register a `ServiceEntry`, wait for first probe");
4486*cfb92d14SAndroid Build Coastguard Worker 
4487*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4488*cfb92d14SAndroid Build Coastguard Worker 
4489*cfb92d14SAndroid Build Coastguard Worker         sRegCallbacks[0].Reset();
4490*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->RegisterService(service, 0, HandleCallback));
4491*cfb92d14SAndroid Build Coastguard Worker 
4492*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4493*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4494*cfb92d14SAndroid Build Coastguard Worker 
4495*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4496*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4497*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
4498*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ true);
4499*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4500*cfb92d14SAndroid Build Coastguard Worker 
4501*cfb92d14SAndroid Build Coastguard Worker         Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4502*cfb92d14SAndroid Build Coastguard Worker         Log("Send a response claiming the name with record in %s section", (iter == 0) ? "answer" : "additional");
4503*cfb92d14SAndroid Build Coastguard Worker 
4504*cfb92d14SAndroid Build Coastguard Worker         SendResponseWithEmptyKey(fullServiceName.AsCString(), (iter == 0) ? kInAnswerSection : kInAdditionalSection);
4505*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(1);
4506*cfb92d14SAndroid Build Coastguard Worker 
4507*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4508*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mError == kErrorDuplicated);
4509*cfb92d14SAndroid Build Coastguard Worker 
4510*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sConflictCallback.mWasCalled);
4511*cfb92d14SAndroid Build Coastguard Worker 
4512*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4513*cfb92d14SAndroid Build Coastguard Worker 
4514*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(mdns->UnregisterService(service));
4515*cfb92d14SAndroid Build Coastguard Worker 
4516*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(15000);
4517*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
4518*cfb92d14SAndroid Build Coastguard Worker     }
4519*cfb92d14SAndroid Build Coastguard Worker 
4520*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4521*cfb92d14SAndroid Build Coastguard Worker     Log("Register a `ServiceEntry` and respond to probe to trigger conflict");
4522*cfb92d14SAndroid Build Coastguard Worker 
4523*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
4524*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 0, HandleCallback));
4525*cfb92d14SAndroid Build Coastguard Worker 
4526*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4527*cfb92d14SAndroid Build Coastguard Worker 
4528*cfb92d14SAndroid Build Coastguard Worker     SendResponseWithEmptyKey(fullServiceName.AsCString(), kInAnswerSection);
4529*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4530*cfb92d14SAndroid Build Coastguard Worker 
4531*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4532*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[0].mError == kErrorDuplicated);
4533*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4534*cfb92d14SAndroid Build Coastguard Worker 
4535*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4536*cfb92d14SAndroid Build Coastguard Worker     Log("Register the conflicted `ServiceEntry` again, and make sure no probes are sent");
4537*cfb92d14SAndroid Build Coastguard Worker 
4538*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[1].Reset();
4539*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4540*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4541*cfb92d14SAndroid Build Coastguard Worker 
4542*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleCallback));
4543*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
4544*cfb92d14SAndroid Build Coastguard Worker 
4545*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[1].mWasCalled);
4546*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sRegCallbacks[1].mError == kErrorDuplicated);
4547*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4548*cfb92d14SAndroid Build Coastguard Worker 
4549*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4550*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister the conflicted host and register it again immediately, make sure we see probes");
4551*cfb92d14SAndroid Build Coastguard Worker 
4552*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterService(service));
4553*cfb92d14SAndroid Build Coastguard Worker 
4554*cfb92d14SAndroid Build Coastguard Worker     sConflictCallback.Reset();
4555*cfb92d14SAndroid Build Coastguard Worker     sRegCallbacks[0].Reset();
4556*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 0, HandleSuccessCallback));
4557*cfb92d14SAndroid Build Coastguard Worker 
4558*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t probeCount = 0; probeCount < 3; probeCount++)
4559*cfb92d14SAndroid Build Coastguard Worker     {
4560*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4561*cfb92d14SAndroid Build Coastguard Worker 
4562*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sRegCallbacks[0].mWasCalled);
4563*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(250);
4564*cfb92d14SAndroid Build Coastguard Worker 
4565*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4566*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4567*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 2, /* Addnl */ 0);
4568*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsProbeFor(service, /* aUnicastRequest */ (probeCount == 0));
4569*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4570*cfb92d14SAndroid Build Coastguard Worker     }
4571*cfb92d14SAndroid Build Coastguard Worker 
4572*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
4573*cfb92d14SAndroid Build Coastguard Worker     {
4574*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4575*cfb92d14SAndroid Build Coastguard Worker 
4576*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((anncCount == 0) ? 250 : (1U << (anncCount - 1)) * 1000);
4577*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sRegCallbacks[0].mWasCalled);
4578*cfb92d14SAndroid Build Coastguard Worker 
4579*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4580*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4581*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 4, /* Auth */ 0, /* Addnl */ 1);
4582*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt | kCheckPtr | kCheckServicesPtr);
4583*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4584*cfb92d14SAndroid Build Coastguard Worker     }
4585*cfb92d14SAndroid Build Coastguard Worker 
4586*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sConflictCallback.mWasCalled);
4587*cfb92d14SAndroid Build Coastguard Worker 
4588*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4589*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response for service name and validate that conflict is detected and callback is called");
4590*cfb92d14SAndroid Build Coastguard Worker 
4591*cfb92d14SAndroid Build Coastguard Worker     SendResponseWithEmptyKey(fullServiceName.AsCString(), kInAnswerSection);
4592*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4593*cfb92d14SAndroid Build Coastguard Worker 
4594*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sConflictCallback.mWasCalled);
4595*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(
4596*cfb92d14SAndroid Build Coastguard Worker         StringMatch(sConflictCallback.mName.AsCString(), service.mServiceInstance, kStringCaseInsensitiveMatch));
4597*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sConflictCallback.mHasServiceType);
4598*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(
4599*cfb92d14SAndroid Build Coastguard Worker         StringMatch(sConflictCallback.mServiceType.AsCString(), service.mServiceType, kStringCaseInsensitiveMatch));
4600*cfb92d14SAndroid Build Coastguard Worker 
4601*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4602*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20000);
4603*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4604*cfb92d14SAndroid Build Coastguard Worker 
4605*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
4606*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
4607*cfb92d14SAndroid Build Coastguard Worker 
4608*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
4609*cfb92d14SAndroid Build Coastguard Worker 
4610*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
4611*cfb92d14SAndroid Build Coastguard Worker }
4612*cfb92d14SAndroid Build Coastguard Worker 
4613*cfb92d14SAndroid Build Coastguard Worker //=====================================================================================================================
4614*cfb92d14SAndroid Build Coastguard Worker // Browser/Resolver tests
4615*cfb92d14SAndroid Build Coastguard Worker 
4616*cfb92d14SAndroid Build Coastguard Worker struct BrowseCallback : public Allocatable<BrowseCallback>, public LinkedListEntry<BrowseCallback>
4617*cfb92d14SAndroid Build Coastguard Worker {
4618*cfb92d14SAndroid Build Coastguard Worker     BrowseCallback *mNext;
4619*cfb92d14SAndroid Build Coastguard Worker     DnsName         mServiceType;
4620*cfb92d14SAndroid Build Coastguard Worker     DnsName         mSubTypeLabel;
4621*cfb92d14SAndroid Build Coastguard Worker     DnsName         mServiceInstance;
4622*cfb92d14SAndroid Build Coastguard Worker     uint32_t        mTtl;
4623*cfb92d14SAndroid Build Coastguard Worker     bool            mIsSubType;
4624*cfb92d14SAndroid Build Coastguard Worker };
4625*cfb92d14SAndroid Build Coastguard Worker 
4626*cfb92d14SAndroid Build Coastguard Worker struct SrvCallback : public Allocatable<SrvCallback>, public LinkedListEntry<SrvCallback>
4627*cfb92d14SAndroid Build Coastguard Worker {
4628*cfb92d14SAndroid Build Coastguard Worker     SrvCallback *mNext;
4629*cfb92d14SAndroid Build Coastguard Worker     DnsName      mServiceInstance;
4630*cfb92d14SAndroid Build Coastguard Worker     DnsName      mServiceType;
4631*cfb92d14SAndroid Build Coastguard Worker     DnsName      mHostName;
4632*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mPort;
4633*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mPriority;
4634*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mWeight;
4635*cfb92d14SAndroid Build Coastguard Worker     uint32_t     mTtl;
4636*cfb92d14SAndroid Build Coastguard Worker };
4637*cfb92d14SAndroid Build Coastguard Worker 
4638*cfb92d14SAndroid Build Coastguard Worker struct TxtCallback : public Allocatable<TxtCallback>, public LinkedListEntry<TxtCallback>
4639*cfb92d14SAndroid Build Coastguard Worker {
4640*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint16_t kMaxTxtDataLength = 100;
4641*cfb92d14SAndroid Build Coastguard Worker 
Matchesot::Dns::Multicast::TxtCallback4642*cfb92d14SAndroid Build Coastguard Worker     template <uint16_t kSize> bool Matches(const uint8_t (&aData)[kSize]) const
4643*cfb92d14SAndroid Build Coastguard Worker     {
4644*cfb92d14SAndroid Build Coastguard Worker         return (mTxtDataLength == kSize) && (memcmp(mTxtData, aData, kSize) == 0);
4645*cfb92d14SAndroid Build Coastguard Worker     }
4646*cfb92d14SAndroid Build Coastguard Worker 
4647*cfb92d14SAndroid Build Coastguard Worker     TxtCallback *mNext;
4648*cfb92d14SAndroid Build Coastguard Worker     DnsName      mServiceInstance;
4649*cfb92d14SAndroid Build Coastguard Worker     DnsName      mServiceType;
4650*cfb92d14SAndroid Build Coastguard Worker     uint8_t      mTxtData[kMaxTxtDataLength];
4651*cfb92d14SAndroid Build Coastguard Worker     uint16_t     mTxtDataLength;
4652*cfb92d14SAndroid Build Coastguard Worker     uint32_t     mTtl;
4653*cfb92d14SAndroid Build Coastguard Worker };
4654*cfb92d14SAndroid Build Coastguard Worker 
4655*cfb92d14SAndroid Build Coastguard Worker struct AddrCallback : public Allocatable<AddrCallback>, public LinkedListEntry<AddrCallback>
4656*cfb92d14SAndroid Build Coastguard Worker {
4657*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint16_t kMaxNumAddrs = 16;
4658*cfb92d14SAndroid Build Coastguard Worker 
Containsot::Dns::Multicast::AddrCallback4659*cfb92d14SAndroid Build Coastguard Worker     bool Contains(const AddrAndTtl &aAddrAndTtl) const
4660*cfb92d14SAndroid Build Coastguard Worker     {
4661*cfb92d14SAndroid Build Coastguard Worker         bool contains = false;
4662*cfb92d14SAndroid Build Coastguard Worker 
4663*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < mNumAddrs; index++)
4664*cfb92d14SAndroid Build Coastguard Worker         {
4665*cfb92d14SAndroid Build Coastguard Worker             if (mAddrAndTtls[index] == aAddrAndTtl)
4666*cfb92d14SAndroid Build Coastguard Worker             {
4667*cfb92d14SAndroid Build Coastguard Worker                 contains = true;
4668*cfb92d14SAndroid Build Coastguard Worker                 break;
4669*cfb92d14SAndroid Build Coastguard Worker             }
4670*cfb92d14SAndroid Build Coastguard Worker         }
4671*cfb92d14SAndroid Build Coastguard Worker 
4672*cfb92d14SAndroid Build Coastguard Worker         return contains;
4673*cfb92d14SAndroid Build Coastguard Worker     }
4674*cfb92d14SAndroid Build Coastguard Worker 
Matchesot::Dns::Multicast::AddrCallback4675*cfb92d14SAndroid Build Coastguard Worker     bool Matches(const AddrAndTtl *aAddrAndTtls, uint16_t aNumAddrs) const
4676*cfb92d14SAndroid Build Coastguard Worker     {
4677*cfb92d14SAndroid Build Coastguard Worker         bool matches = true;
4678*cfb92d14SAndroid Build Coastguard Worker 
4679*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aNumAddrs == mNumAddrs, matches = false);
4680*cfb92d14SAndroid Build Coastguard Worker 
4681*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t index = 0; index < mNumAddrs; index++)
4682*cfb92d14SAndroid Build Coastguard Worker         {
4683*cfb92d14SAndroid Build Coastguard Worker             if (!Contains(aAddrAndTtls[index]))
4684*cfb92d14SAndroid Build Coastguard Worker             {
4685*cfb92d14SAndroid Build Coastguard Worker                 ExitNow(matches = false);
4686*cfb92d14SAndroid Build Coastguard Worker             }
4687*cfb92d14SAndroid Build Coastguard Worker         }
4688*cfb92d14SAndroid Build Coastguard Worker 
4689*cfb92d14SAndroid Build Coastguard Worker     exit:
4690*cfb92d14SAndroid Build Coastguard Worker         return matches;
4691*cfb92d14SAndroid Build Coastguard Worker     }
4692*cfb92d14SAndroid Build Coastguard Worker 
4693*cfb92d14SAndroid Build Coastguard Worker     AddrCallback *mNext;
4694*cfb92d14SAndroid Build Coastguard Worker     DnsName       mHostName;
4695*cfb92d14SAndroid Build Coastguard Worker     AddrAndTtl    mAddrAndTtls[kMaxNumAddrs];
4696*cfb92d14SAndroid Build Coastguard Worker     uint16_t      mNumAddrs;
4697*cfb92d14SAndroid Build Coastguard Worker };
4698*cfb92d14SAndroid Build Coastguard Worker 
4699*cfb92d14SAndroid Build Coastguard Worker OwningList<BrowseCallback> sBrowseCallbacks;
4700*cfb92d14SAndroid Build Coastguard Worker OwningList<SrvCallback>    sSrvCallbacks;
4701*cfb92d14SAndroid Build Coastguard Worker OwningList<TxtCallback>    sTxtCallbacks;
4702*cfb92d14SAndroid Build Coastguard Worker OwningList<AddrCallback>   sAddrCallbacks;
4703*cfb92d14SAndroid Build Coastguard Worker 
HandleBrowseResult(otInstance * aInstance,const otMdnsBrowseResult * aResult)4704*cfb92d14SAndroid Build Coastguard Worker void HandleBrowseResult(otInstance *aInstance, const otMdnsBrowseResult *aResult)
4705*cfb92d14SAndroid Build Coastguard Worker {
4706*cfb92d14SAndroid Build Coastguard Worker     BrowseCallback *entry;
4707*cfb92d14SAndroid Build Coastguard Worker 
4708*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
4709*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult != nullptr);
4710*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceType != nullptr);
4711*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceInstance != nullptr);
4712*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mInfraIfIndex == kInfraIfIndex);
4713*cfb92d14SAndroid Build Coastguard Worker 
4714*cfb92d14SAndroid Build Coastguard Worker     Log("Browse callback: %s (subtype:%s) -> %s ttl:%lu", aResult->mServiceType,
4715*cfb92d14SAndroid Build Coastguard Worker         aResult->mSubTypeLabel == nullptr ? "(null)" : aResult->mSubTypeLabel, aResult->mServiceInstance,
4716*cfb92d14SAndroid Build Coastguard Worker         ToUlong(aResult->mTtl));
4717*cfb92d14SAndroid Build Coastguard Worker 
4718*cfb92d14SAndroid Build Coastguard Worker     entry = BrowseCallback::Allocate();
4719*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(entry != nullptr);
4720*cfb92d14SAndroid Build Coastguard Worker 
4721*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceType.CopyFrom(aResult->mServiceType);
4722*cfb92d14SAndroid Build Coastguard Worker     entry->mSubTypeLabel.CopyFrom(aResult->mSubTypeLabel);
4723*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceInstance.CopyFrom(aResult->mServiceInstance);
4724*cfb92d14SAndroid Build Coastguard Worker     entry->mTtl       = aResult->mTtl;
4725*cfb92d14SAndroid Build Coastguard Worker     entry->mIsSubType = (aResult->mSubTypeLabel != nullptr);
4726*cfb92d14SAndroid Build Coastguard Worker 
4727*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.PushAfterTail(*entry);
4728*cfb92d14SAndroid Build Coastguard Worker }
4729*cfb92d14SAndroid Build Coastguard Worker 
HandleBrowseResultAlternate(otInstance * aInstance,const otMdnsBrowseResult * aResult)4730*cfb92d14SAndroid Build Coastguard Worker void HandleBrowseResultAlternate(otInstance *aInstance, const otMdnsBrowseResult *aResult)
4731*cfb92d14SAndroid Build Coastguard Worker {
4732*cfb92d14SAndroid Build Coastguard Worker     Log("Alternate browse callback is called");
4733*cfb92d14SAndroid Build Coastguard Worker     HandleBrowseResult(aInstance, aResult);
4734*cfb92d14SAndroid Build Coastguard Worker }
4735*cfb92d14SAndroid Build Coastguard Worker 
HandleSrvResult(otInstance * aInstance,const otMdnsSrvResult * aResult)4736*cfb92d14SAndroid Build Coastguard Worker void HandleSrvResult(otInstance *aInstance, const otMdnsSrvResult *aResult)
4737*cfb92d14SAndroid Build Coastguard Worker {
4738*cfb92d14SAndroid Build Coastguard Worker     SrvCallback *entry;
4739*cfb92d14SAndroid Build Coastguard Worker 
4740*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
4741*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult != nullptr);
4742*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceInstance != nullptr);
4743*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceType != nullptr);
4744*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mInfraIfIndex == kInfraIfIndex);
4745*cfb92d14SAndroid Build Coastguard Worker 
4746*cfb92d14SAndroid Build Coastguard Worker     if (aResult->mTtl != 0)
4747*cfb92d14SAndroid Build Coastguard Worker     {
4748*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(aResult->mHostName != nullptr);
4749*cfb92d14SAndroid Build Coastguard Worker 
4750*cfb92d14SAndroid Build Coastguard Worker         Log("SRV callback: %s %s, host:%s port:%u, prio:%u, weight:%u, ttl:%lu", aResult->mServiceInstance,
4751*cfb92d14SAndroid Build Coastguard Worker             aResult->mServiceType, aResult->mHostName, aResult->mPort, aResult->mPriority, aResult->mWeight,
4752*cfb92d14SAndroid Build Coastguard Worker             ToUlong(aResult->mTtl));
4753*cfb92d14SAndroid Build Coastguard Worker     }
4754*cfb92d14SAndroid Build Coastguard Worker     else
4755*cfb92d14SAndroid Build Coastguard Worker     {
4756*cfb92d14SAndroid Build Coastguard Worker         Log("SRV callback: %s %s, ttl:%lu", aResult->mServiceInstance, aResult->mServiceType, ToUlong(aResult->mTtl));
4757*cfb92d14SAndroid Build Coastguard Worker     }
4758*cfb92d14SAndroid Build Coastguard Worker 
4759*cfb92d14SAndroid Build Coastguard Worker     entry = SrvCallback::Allocate();
4760*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(entry != nullptr);
4761*cfb92d14SAndroid Build Coastguard Worker 
4762*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceInstance.CopyFrom(aResult->mServiceInstance);
4763*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceType.CopyFrom(aResult->mServiceType);
4764*cfb92d14SAndroid Build Coastguard Worker     entry->mHostName.CopyFrom(aResult->mHostName);
4765*cfb92d14SAndroid Build Coastguard Worker     entry->mPort     = aResult->mPort;
4766*cfb92d14SAndroid Build Coastguard Worker     entry->mPriority = aResult->mPriority;
4767*cfb92d14SAndroid Build Coastguard Worker     entry->mWeight   = aResult->mWeight;
4768*cfb92d14SAndroid Build Coastguard Worker     entry->mTtl      = aResult->mTtl;
4769*cfb92d14SAndroid Build Coastguard Worker 
4770*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.PushAfterTail(*entry);
4771*cfb92d14SAndroid Build Coastguard Worker }
4772*cfb92d14SAndroid Build Coastguard Worker 
HandleSrvResultAlternate(otInstance * aInstance,const otMdnsSrvResult * aResult)4773*cfb92d14SAndroid Build Coastguard Worker void HandleSrvResultAlternate(otInstance *aInstance, const otMdnsSrvResult *aResult)
4774*cfb92d14SAndroid Build Coastguard Worker {
4775*cfb92d14SAndroid Build Coastguard Worker     Log("Alternate SRV callback is called");
4776*cfb92d14SAndroid Build Coastguard Worker     HandleSrvResult(aInstance, aResult);
4777*cfb92d14SAndroid Build Coastguard Worker }
4778*cfb92d14SAndroid Build Coastguard Worker 
HandleTxtResult(otInstance * aInstance,const otMdnsTxtResult * aResult)4779*cfb92d14SAndroid Build Coastguard Worker void HandleTxtResult(otInstance *aInstance, const otMdnsTxtResult *aResult)
4780*cfb92d14SAndroid Build Coastguard Worker {
4781*cfb92d14SAndroid Build Coastguard Worker     TxtCallback *entry;
4782*cfb92d14SAndroid Build Coastguard Worker 
4783*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
4784*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult != nullptr);
4785*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceInstance != nullptr);
4786*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mServiceType != nullptr);
4787*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mInfraIfIndex == kInfraIfIndex);
4788*cfb92d14SAndroid Build Coastguard Worker 
4789*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mTxtDataLength <= TxtCallback::kMaxTxtDataLength);
4790*cfb92d14SAndroid Build Coastguard Worker 
4791*cfb92d14SAndroid Build Coastguard Worker     if (aResult->mTtl != 0)
4792*cfb92d14SAndroid Build Coastguard Worker     {
4793*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(aResult->mTxtData != nullptr);
4794*cfb92d14SAndroid Build Coastguard Worker 
4795*cfb92d14SAndroid Build Coastguard Worker         Log("TXT callback: %s %s, len:%u, ttl:%lu", aResult->mServiceInstance, aResult->mServiceType,
4796*cfb92d14SAndroid Build Coastguard Worker             aResult->mTxtDataLength, ToUlong(aResult->mTtl));
4797*cfb92d14SAndroid Build Coastguard Worker     }
4798*cfb92d14SAndroid Build Coastguard Worker     else
4799*cfb92d14SAndroid Build Coastguard Worker     {
4800*cfb92d14SAndroid Build Coastguard Worker         Log("TXT callback: %s %s, ttl:%lu", aResult->mServiceInstance, aResult->mServiceType, ToUlong(aResult->mTtl));
4801*cfb92d14SAndroid Build Coastguard Worker     }
4802*cfb92d14SAndroid Build Coastguard Worker 
4803*cfb92d14SAndroid Build Coastguard Worker     entry = TxtCallback::Allocate();
4804*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(entry != nullptr);
4805*cfb92d14SAndroid Build Coastguard Worker 
4806*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceInstance.CopyFrom(aResult->mServiceInstance);
4807*cfb92d14SAndroid Build Coastguard Worker     entry->mServiceType.CopyFrom(aResult->mServiceType);
4808*cfb92d14SAndroid Build Coastguard Worker     entry->mTxtDataLength = aResult->mTxtDataLength;
4809*cfb92d14SAndroid Build Coastguard Worker     memcpy(entry->mTxtData, aResult->mTxtData, aResult->mTxtDataLength);
4810*cfb92d14SAndroid Build Coastguard Worker     entry->mTtl = aResult->mTtl;
4811*cfb92d14SAndroid Build Coastguard Worker 
4812*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.PushAfterTail(*entry);
4813*cfb92d14SAndroid Build Coastguard Worker }
4814*cfb92d14SAndroid Build Coastguard Worker 
HandleTxtResultAlternate(otInstance * aInstance,const otMdnsTxtResult * aResult)4815*cfb92d14SAndroid Build Coastguard Worker void HandleTxtResultAlternate(otInstance *aInstance, const otMdnsTxtResult *aResult)
4816*cfb92d14SAndroid Build Coastguard Worker {
4817*cfb92d14SAndroid Build Coastguard Worker     Log("Alternate TXT callback is called");
4818*cfb92d14SAndroid Build Coastguard Worker     HandleTxtResult(aInstance, aResult);
4819*cfb92d14SAndroid Build Coastguard Worker }
4820*cfb92d14SAndroid Build Coastguard Worker 
HandleAddrResult(otInstance * aInstance,const otMdnsAddressResult * aResult)4821*cfb92d14SAndroid Build Coastguard Worker void HandleAddrResult(otInstance *aInstance, const otMdnsAddressResult *aResult)
4822*cfb92d14SAndroid Build Coastguard Worker {
4823*cfb92d14SAndroid Build Coastguard Worker     AddrCallback *entry;
4824*cfb92d14SAndroid Build Coastguard Worker 
4825*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aInstance == sInstance);
4826*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult != nullptr);
4827*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mHostName != nullptr);
4828*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mInfraIfIndex == kInfraIfIndex);
4829*cfb92d14SAndroid Build Coastguard Worker 
4830*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aResult->mAddressesLength <= AddrCallback::kMaxNumAddrs);
4831*cfb92d14SAndroid Build Coastguard Worker 
4832*cfb92d14SAndroid Build Coastguard Worker     entry = AddrCallback::Allocate();
4833*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(entry != nullptr);
4834*cfb92d14SAndroid Build Coastguard Worker 
4835*cfb92d14SAndroid Build Coastguard Worker     entry->mHostName.CopyFrom(aResult->mHostName);
4836*cfb92d14SAndroid Build Coastguard Worker     entry->mNumAddrs = aResult->mAddressesLength;
4837*cfb92d14SAndroid Build Coastguard Worker 
4838*cfb92d14SAndroid Build Coastguard Worker     Log("Addr callback: %s, num:%u", aResult->mHostName, aResult->mAddressesLength);
4839*cfb92d14SAndroid Build Coastguard Worker 
4840*cfb92d14SAndroid Build Coastguard Worker     for (uint16_t index = 0; index < aResult->mAddressesLength; index++)
4841*cfb92d14SAndroid Build Coastguard Worker     {
4842*cfb92d14SAndroid Build Coastguard Worker         entry->mAddrAndTtls[index].mAddress = AsCoreType(&aResult->mAddresses[index].mAddress);
4843*cfb92d14SAndroid Build Coastguard Worker         entry->mAddrAndTtls[index].mTtl     = aResult->mAddresses[index].mTtl;
4844*cfb92d14SAndroid Build Coastguard Worker 
4845*cfb92d14SAndroid Build Coastguard Worker         Log(" - %s, ttl:%lu", entry->mAddrAndTtls[index].mAddress.ToString().AsCString(),
4846*cfb92d14SAndroid Build Coastguard Worker             ToUlong(entry->mAddrAndTtls[index].mTtl));
4847*cfb92d14SAndroid Build Coastguard Worker     }
4848*cfb92d14SAndroid Build Coastguard Worker 
4849*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.PushAfterTail(*entry);
4850*cfb92d14SAndroid Build Coastguard Worker }
4851*cfb92d14SAndroid Build Coastguard Worker 
HandleAddrResultAlternate(otInstance * aInstance,const otMdnsAddressResult * aResult)4852*cfb92d14SAndroid Build Coastguard Worker void HandleAddrResultAlternate(otInstance *aInstance, const otMdnsAddressResult *aResult)
4853*cfb92d14SAndroid Build Coastguard Worker {
4854*cfb92d14SAndroid Build Coastguard Worker     Log("Alternate addr callback is called");
4855*cfb92d14SAndroid Build Coastguard Worker     HandleAddrResult(aInstance, aResult);
4856*cfb92d14SAndroid Build Coastguard Worker }
4857*cfb92d14SAndroid Build Coastguard Worker 
4858*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
4859*cfb92d14SAndroid Build Coastguard Worker 
TestBrowser(void)4860*cfb92d14SAndroid Build Coastguard Worker void TestBrowser(void)
4861*cfb92d14SAndroid Build Coastguard Worker {
4862*cfb92d14SAndroid Build Coastguard Worker     Core                 *mdns = InitTest();
4863*cfb92d14SAndroid Build Coastguard Worker     Core::Browser         browser;
4864*cfb92d14SAndroid Build Coastguard Worker     Core::Browser         browser2;
4865*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage     *dnsMsg;
4866*cfb92d14SAndroid Build Coastguard Worker     const BrowseCallback *browseCallback;
4867*cfb92d14SAndroid Build Coastguard Worker     uint16_t              heapAllocations;
4868*cfb92d14SAndroid Build Coastguard Worker 
4869*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
4870*cfb92d14SAndroid Build Coastguard Worker     Log("TestBrowser");
4871*cfb92d14SAndroid Build Coastguard Worker 
4872*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4873*cfb92d14SAndroid Build Coastguard Worker 
4874*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
4875*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
4876*cfb92d14SAndroid Build Coastguard Worker 
4877*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4878*cfb92d14SAndroid Build Coastguard Worker     Log("Start a browser. Validate initial queries.");
4879*cfb92d14SAndroid Build Coastguard Worker 
4880*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(browser);
4881*cfb92d14SAndroid Build Coastguard Worker 
4882*cfb92d14SAndroid Build Coastguard Worker     browser.mServiceType  = "_srv._udp";
4883*cfb92d14SAndroid Build Coastguard Worker     browser.mSubTypeLabel = nullptr;
4884*cfb92d14SAndroid Build Coastguard Worker     browser.mInfraIfIndex = kInfraIfIndex;
4885*cfb92d14SAndroid Build Coastguard Worker     browser.mCallback     = HandleBrowseResult;
4886*cfb92d14SAndroid Build Coastguard Worker 
4887*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4888*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartBrowser(browser));
4889*cfb92d14SAndroid Build Coastguard Worker 
4890*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
4891*cfb92d14SAndroid Build Coastguard Worker     {
4892*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
4893*cfb92d14SAndroid Build Coastguard Worker 
4894*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((queryCount == 0) ? 125 : (1U << (queryCount - 1)) * 1000);
4895*cfb92d14SAndroid Build Coastguard Worker 
4896*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
4897*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
4898*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
4899*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(browser);
4900*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
4901*cfb92d14SAndroid Build Coastguard Worker     }
4902*cfb92d14SAndroid Build Coastguard Worker 
4903*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
4904*cfb92d14SAndroid Build Coastguard Worker 
4905*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20000);
4906*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4907*cfb92d14SAndroid Build Coastguard Worker 
4908*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4909*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response. Validate callback result.");
4910*cfb92d14SAndroid Build Coastguard Worker 
4911*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
4912*cfb92d14SAndroid Build Coastguard Worker 
4913*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "mysrv._srv._udp.local.", 120, kInAnswerSection);
4914*cfb92d14SAndroid Build Coastguard Worker 
4915*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4916*cfb92d14SAndroid Build Coastguard Worker 
4917*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sBrowseCallbacks.IsEmpty());
4918*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
4919*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
4920*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!browseCallback->mIsSubType);
4921*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("mysrv"));
4922*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 120);
4923*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
4924*cfb92d14SAndroid Build Coastguard Worker 
4925*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4926*cfb92d14SAndroid Build Coastguard Worker 
4927*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4928*cfb92d14SAndroid Build Coastguard Worker     Log("Send another response. Validate callback result.");
4929*cfb92d14SAndroid Build Coastguard Worker 
4930*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10000);
4931*cfb92d14SAndroid Build Coastguard Worker 
4932*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
4933*cfb92d14SAndroid Build Coastguard Worker 
4934*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "awesome._srv._udp.local.", 500, kInAnswerSection);
4935*cfb92d14SAndroid Build Coastguard Worker 
4936*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
4937*cfb92d14SAndroid Build Coastguard Worker 
4938*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sBrowseCallbacks.IsEmpty());
4939*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
4940*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
4941*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!browseCallback->mIsSubType);
4942*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("awesome"));
4943*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 500);
4944*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
4945*cfb92d14SAndroid Build Coastguard Worker 
4946*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4947*cfb92d14SAndroid Build Coastguard Worker 
4948*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4949*cfb92d14SAndroid Build Coastguard Worker     Log("Start another browser for the same service and different callback. Validate results.");
4950*cfb92d14SAndroid Build Coastguard Worker 
4951*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
4952*cfb92d14SAndroid Build Coastguard Worker 
4953*cfb92d14SAndroid Build Coastguard Worker     browser2.mServiceType  = "_srv._udp";
4954*cfb92d14SAndroid Build Coastguard Worker     browser2.mSubTypeLabel = nullptr;
4955*cfb92d14SAndroid Build Coastguard Worker     browser2.mInfraIfIndex = kInfraIfIndex;
4956*cfb92d14SAndroid Build Coastguard Worker     browser2.mCallback     = HandleBrowseResultAlternate;
4957*cfb92d14SAndroid Build Coastguard Worker 
4958*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
4959*cfb92d14SAndroid Build Coastguard Worker 
4960*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartBrowser(browser2));
4961*cfb92d14SAndroid Build Coastguard Worker 
4962*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
4963*cfb92d14SAndroid Build Coastguard Worker 
4964*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
4965*cfb92d14SAndroid Build Coastguard Worker     {
4966*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback != nullptr);
4967*cfb92d14SAndroid Build Coastguard Worker 
4968*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
4969*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!browseCallback->mIsSubType);
4970*cfb92d14SAndroid Build Coastguard Worker 
4971*cfb92d14SAndroid Build Coastguard Worker         if (browseCallback->mServiceInstance.Matches("awesome"))
4972*cfb92d14SAndroid Build Coastguard Worker         {
4973*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(browseCallback->mTtl == 500);
4974*cfb92d14SAndroid Build Coastguard Worker         }
4975*cfb92d14SAndroid Build Coastguard Worker         else if (browseCallback->mServiceInstance.Matches("mysrv"))
4976*cfb92d14SAndroid Build Coastguard Worker         {
4977*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(browseCallback->mTtl == 120);
4978*cfb92d14SAndroid Build Coastguard Worker         }
4979*cfb92d14SAndroid Build Coastguard Worker         else
4980*cfb92d14SAndroid Build Coastguard Worker         {
4981*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(false);
4982*cfb92d14SAndroid Build Coastguard Worker         }
4983*cfb92d14SAndroid Build Coastguard Worker 
4984*cfb92d14SAndroid Build Coastguard Worker         browseCallback = browseCallback->GetNext();
4985*cfb92d14SAndroid Build Coastguard Worker     }
4986*cfb92d14SAndroid Build Coastguard Worker 
4987*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback == nullptr);
4988*cfb92d14SAndroid Build Coastguard Worker 
4989*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
4990*cfb92d14SAndroid Build Coastguard Worker 
4991*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
4992*cfb92d14SAndroid Build Coastguard Worker 
4993*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
4994*cfb92d14SAndroid Build Coastguard Worker     Log("Start same browser again and check the returned error.");
4995*cfb92d14SAndroid Build Coastguard Worker 
4996*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
4997*cfb92d14SAndroid Build Coastguard Worker 
4998*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(mdns->StartBrowser(browser2) == kErrorAlready);
4999*cfb92d14SAndroid Build Coastguard Worker 
5000*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
5001*cfb92d14SAndroid Build Coastguard Worker 
5002*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5003*cfb92d14SAndroid Build Coastguard Worker 
5004*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5005*cfb92d14SAndroid Build Coastguard Worker     Log("Send a goodbye response. Validate result callback for both browsers.");
5006*cfb92d14SAndroid Build Coastguard Worker 
5007*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "awesome._srv._udp.local.", 0, kInAnswerSection);
5008*cfb92d14SAndroid Build Coastguard Worker 
5009*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5010*cfb92d14SAndroid Build Coastguard Worker 
5011*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
5012*cfb92d14SAndroid Build Coastguard Worker 
5013*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
5014*cfb92d14SAndroid Build Coastguard Worker     {
5015*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback != nullptr);
5016*cfb92d14SAndroid Build Coastguard Worker 
5017*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
5018*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!browseCallback->mIsSubType);
5019*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mServiceInstance.Matches("awesome"));
5020*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mTtl == 0);
5021*cfb92d14SAndroid Build Coastguard Worker 
5022*cfb92d14SAndroid Build Coastguard Worker         browseCallback = browseCallback->GetNext();
5023*cfb92d14SAndroid Build Coastguard Worker     }
5024*cfb92d14SAndroid Build Coastguard Worker 
5025*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback == nullptr);
5026*cfb92d14SAndroid Build Coastguard Worker 
5027*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5028*cfb92d14SAndroid Build Coastguard Worker 
5029*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5030*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response with no changes, validate that no callback is invoked.");
5031*cfb92d14SAndroid Build Coastguard Worker 
5032*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5033*cfb92d14SAndroid Build Coastguard Worker 
5034*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "mysrv._srv._udp.local.", 120, kInAnswerSection);
5035*cfb92d14SAndroid Build Coastguard Worker 
5036*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5037*cfb92d14SAndroid Build Coastguard Worker 
5038*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5039*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5040*cfb92d14SAndroid Build Coastguard Worker 
5041*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5042*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the second browser.");
5043*cfb92d14SAndroid Build Coastguard Worker 
5044*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5045*cfb92d14SAndroid Build Coastguard Worker 
5046*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopBrowser(browser2));
5047*cfb92d14SAndroid Build Coastguard Worker 
5048*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
5049*cfb92d14SAndroid Build Coastguard Worker 
5050*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5051*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5052*cfb92d14SAndroid Build Coastguard Worker 
5053*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5054*cfb92d14SAndroid Build Coastguard Worker     Log("Check query is sent at 80 percentage of TTL and then respond to it.");
5055*cfb92d14SAndroid Build Coastguard Worker 
5056*cfb92d14SAndroid Build Coastguard Worker     // First query should be sent at 80-82% of TTL of 120 second (96.0-98.4 sec).
5057*cfb92d14SAndroid Build Coastguard Worker     // We wait for 100 second. Note that 5 seconds already passed in the
5058*cfb92d14SAndroid Build Coastguard Worker     // previous step.
5059*cfb92d14SAndroid Build Coastguard Worker 
5060*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(91 * 1000 - 1);
5061*cfb92d14SAndroid Build Coastguard Worker 
5062*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5063*cfb92d14SAndroid Build Coastguard Worker 
5064*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(4 * 1000 + 1);
5065*cfb92d14SAndroid Build Coastguard Worker 
5066*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
5067*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
5068*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5069*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateAsQueryFor(browser);
5070*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5071*cfb92d14SAndroid Build Coastguard Worker 
5072*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5073*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5074*cfb92d14SAndroid Build Coastguard Worker 
5075*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
5076*cfb92d14SAndroid Build Coastguard Worker 
5077*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "mysrv._srv._udp.local.", 120, kInAnswerSection);
5078*cfb92d14SAndroid Build Coastguard Worker 
5079*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5080*cfb92d14SAndroid Build Coastguard Worker     Log("Check queries are sent at 80, 85, 90, 95 percentages of TTL.");
5081*cfb92d14SAndroid Build Coastguard Worker 
5082*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumRefreshQueries; queryCount++)
5083*cfb92d14SAndroid Build Coastguard Worker     {
5084*cfb92d14SAndroid Build Coastguard Worker         if (queryCount == 0)
5085*cfb92d14SAndroid Build Coastguard Worker         {
5086*cfb92d14SAndroid Build Coastguard Worker             // First query is expected in 80-82% of TTL, so
5087*cfb92d14SAndroid Build Coastguard Worker             // 80% of 120 = 96.0, 82% of 120 = 98.4
5088*cfb92d14SAndroid Build Coastguard Worker 
5089*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(96 * 1000 - 1);
5090*cfb92d14SAndroid Build Coastguard Worker         }
5091*cfb92d14SAndroid Build Coastguard Worker         else
5092*cfb92d14SAndroid Build Coastguard Worker         {
5093*cfb92d14SAndroid Build Coastguard Worker             // Next query should happen within 3%-5% of TTL
5094*cfb92d14SAndroid Build Coastguard Worker             // from previous query. We wait 3% of TTL here.
5095*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(3600 - 1);
5096*cfb92d14SAndroid Build Coastguard Worker         }
5097*cfb92d14SAndroid Build Coastguard Worker 
5098*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
5099*cfb92d14SAndroid Build Coastguard Worker 
5100*cfb92d14SAndroid Build Coastguard Worker         // Wait for 2% of TTL of 120 which is 2.4 sec.
5101*cfb92d14SAndroid Build Coastguard Worker 
5102*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2400 + 1);
5103*cfb92d14SAndroid Build Coastguard Worker 
5104*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5105*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5106*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5107*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(browser);
5108*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5109*cfb92d14SAndroid Build Coastguard Worker 
5110*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5111*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5112*cfb92d14SAndroid Build Coastguard Worker     }
5113*cfb92d14SAndroid Build Coastguard Worker 
5114*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5115*cfb92d14SAndroid Build Coastguard Worker     Log("Check TTL timeout and callback result.");
5116*cfb92d14SAndroid Build Coastguard Worker 
5117*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(6 * 1000);
5118*cfb92d14SAndroid Build Coastguard Worker 
5119*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sBrowseCallbacks.IsEmpty());
5120*cfb92d14SAndroid Build Coastguard Worker 
5121*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
5122*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
5123*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!browseCallback->mIsSubType);
5124*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("mysrv"));
5125*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 0);
5126*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
5127*cfb92d14SAndroid Build Coastguard Worker 
5128*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5129*cfb92d14SAndroid Build Coastguard Worker 
5130*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5131*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5132*cfb92d14SAndroid Build Coastguard Worker 
5133*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200 * 1000);
5134*cfb92d14SAndroid Build Coastguard Worker 
5135*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5136*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5137*cfb92d14SAndroid Build Coastguard Worker 
5138*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5139*cfb92d14SAndroid Build Coastguard Worker     Log("Send a new response and make sure result callback is invoked");
5140*cfb92d14SAndroid Build Coastguard Worker 
5141*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "great._srv._udp.local.", 200, kInAdditionalSection);
5142*cfb92d14SAndroid Build Coastguard Worker 
5143*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5144*cfb92d14SAndroid Build Coastguard Worker 
5145*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
5146*cfb92d14SAndroid Build Coastguard Worker 
5147*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
5148*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!browseCallback->mIsSubType);
5149*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("great"));
5150*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 200);
5151*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
5152*cfb92d14SAndroid Build Coastguard Worker 
5153*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5154*cfb92d14SAndroid Build Coastguard Worker 
5155*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(150 * 1000);
5156*cfb92d14SAndroid Build Coastguard Worker 
5157*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5158*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5159*cfb92d14SAndroid Build Coastguard Worker 
5160*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5161*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the browser. There is no active browser for this service. Ensure no queries are sent");
5162*cfb92d14SAndroid Build Coastguard Worker 
5163*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5164*cfb92d14SAndroid Build Coastguard Worker 
5165*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopBrowser(browser));
5166*cfb92d14SAndroid Build Coastguard Worker 
5167*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100 * 1000);
5168*cfb92d14SAndroid Build Coastguard Worker 
5169*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sBrowseCallbacks.IsEmpty());
5170*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5171*cfb92d14SAndroid Build Coastguard Worker 
5172*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5173*cfb92d14SAndroid Build Coastguard Worker     Log("Start browser again. Validate that initial queries are sent again");
5174*cfb92d14SAndroid Build Coastguard Worker 
5175*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartBrowser(browser));
5176*cfb92d14SAndroid Build Coastguard Worker 
5177*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(125);
5178*cfb92d14SAndroid Build Coastguard Worker 
5179*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
5180*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
5181*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5182*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateAsQueryFor(browser);
5183*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5184*cfb92d14SAndroid Build Coastguard Worker 
5185*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5186*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response after the first initial query");
5187*cfb92d14SAndroid Build Coastguard Worker 
5188*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5189*cfb92d14SAndroid Build Coastguard Worker 
5190*cfb92d14SAndroid Build Coastguard Worker     SendPtrResponse("_srv._udp.local.", "mysrv._srv._udp.local.", 120, kInAnswerSection);
5191*cfb92d14SAndroid Build Coastguard Worker 
5192*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5193*cfb92d14SAndroid Build Coastguard Worker 
5194*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
5195*cfb92d14SAndroid Build Coastguard Worker 
5196*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
5197*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!browseCallback->mIsSubType);
5198*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("mysrv"));
5199*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 120);
5200*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
5201*cfb92d14SAndroid Build Coastguard Worker 
5202*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
5203*cfb92d14SAndroid Build Coastguard Worker 
5204*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5205*cfb92d14SAndroid Build Coastguard Worker     Log("Validate initial esquires are still sent and include known-answer");
5206*cfb92d14SAndroid Build Coastguard Worker 
5207*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 1; queryCount < kNumInitalQueries; queryCount++)
5208*cfb92d14SAndroid Build Coastguard Worker     {
5209*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5210*cfb92d14SAndroid Build Coastguard Worker 
5211*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((1U << (queryCount - 1)) * 1000);
5212*cfb92d14SAndroid Build Coastguard Worker 
5213*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5214*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5215*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0);
5216*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(browser);
5217*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5218*cfb92d14SAndroid Build Coastguard Worker     }
5219*cfb92d14SAndroid Build Coastguard Worker 
5220*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5221*cfb92d14SAndroid Build Coastguard Worker 
5222*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5223*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(50 * 1000);
5224*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5225*cfb92d14SAndroid Build Coastguard Worker 
5226*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
5227*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
5228*cfb92d14SAndroid Build Coastguard Worker 
5229*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
5230*cfb92d14SAndroid Build Coastguard Worker 
5231*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
5232*cfb92d14SAndroid Build Coastguard Worker }
5233*cfb92d14SAndroid Build Coastguard Worker 
TestSrvResolver(void)5234*cfb92d14SAndroid Build Coastguard Worker void TestSrvResolver(void)
5235*cfb92d14SAndroid Build Coastguard Worker {
5236*cfb92d14SAndroid Build Coastguard Worker     Core              *mdns = InitTest();
5237*cfb92d14SAndroid Build Coastguard Worker     Core::SrvResolver  resolver;
5238*cfb92d14SAndroid Build Coastguard Worker     Core::SrvResolver  resolver2;
5239*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage  *dnsMsg;
5240*cfb92d14SAndroid Build Coastguard Worker     const SrvCallback *srvCallback;
5241*cfb92d14SAndroid Build Coastguard Worker     uint16_t           heapAllocations;
5242*cfb92d14SAndroid Build Coastguard Worker 
5243*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
5244*cfb92d14SAndroid Build Coastguard Worker     Log("TestSrvResolver");
5245*cfb92d14SAndroid Build Coastguard Worker 
5246*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5247*cfb92d14SAndroid Build Coastguard Worker 
5248*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
5249*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
5250*cfb92d14SAndroid Build Coastguard Worker 
5251*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5252*cfb92d14SAndroid Build Coastguard Worker     Log("Start a SRV resolver. Validate initial queries.");
5253*cfb92d14SAndroid Build Coastguard Worker 
5254*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(resolver);
5255*cfb92d14SAndroid Build Coastguard Worker 
5256*cfb92d14SAndroid Build Coastguard Worker     resolver.mServiceInstance = "mysrv";
5257*cfb92d14SAndroid Build Coastguard Worker     resolver.mServiceType     = "_srv._udp";
5258*cfb92d14SAndroid Build Coastguard Worker     resolver.mInfraIfIndex    = kInfraIfIndex;
5259*cfb92d14SAndroid Build Coastguard Worker     resolver.mCallback        = HandleSrvResult;
5260*cfb92d14SAndroid Build Coastguard Worker 
5261*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5262*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(resolver));
5263*cfb92d14SAndroid Build Coastguard Worker 
5264*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
5265*cfb92d14SAndroid Build Coastguard Worker     {
5266*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5267*cfb92d14SAndroid Build Coastguard Worker 
5268*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((queryCount == 0) ? 125 : (1U << (queryCount - 1)) * 1000);
5269*cfb92d14SAndroid Build Coastguard Worker 
5270*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5271*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5272*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5273*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
5274*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5275*cfb92d14SAndroid Build Coastguard Worker     }
5276*cfb92d14SAndroid Build Coastguard Worker 
5277*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5278*cfb92d14SAndroid Build Coastguard Worker 
5279*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
5280*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5281*cfb92d14SAndroid Build Coastguard Worker 
5282*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5283*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response. Validate callback result.");
5284*cfb92d14SAndroid Build Coastguard Worker 
5285*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5286*cfb92d14SAndroid Build Coastguard Worker 
5287*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 0, 1, 120, kInAnswerSection);
5288*cfb92d14SAndroid Build Coastguard Worker 
5289*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5290*cfb92d14SAndroid Build Coastguard Worker 
5291*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5292*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5293*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5294*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5295*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5296*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5297*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 0);
5298*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 1);
5299*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5300*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5301*cfb92d14SAndroid Build Coastguard Worker 
5302*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5303*cfb92d14SAndroid Build Coastguard Worker 
5304*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5305*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing host name. Validate callback result.");
5306*cfb92d14SAndroid Build Coastguard Worker 
5307*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5308*cfb92d14SAndroid Build Coastguard Worker 
5309*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5310*cfb92d14SAndroid Build Coastguard Worker 
5311*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost2.local.", 1234, 0, 1, 120, kInAnswerSection);
5312*cfb92d14SAndroid Build Coastguard Worker 
5313*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5314*cfb92d14SAndroid Build Coastguard Worker 
5315*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5316*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5317*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5318*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5319*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost2"));
5320*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5321*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 0);
5322*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 1);
5323*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5324*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5325*cfb92d14SAndroid Build Coastguard Worker 
5326*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5327*cfb92d14SAndroid Build Coastguard Worker 
5328*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5329*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing port. Validate callback result.");
5330*cfb92d14SAndroid Build Coastguard Worker 
5331*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5332*cfb92d14SAndroid Build Coastguard Worker 
5333*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5334*cfb92d14SAndroid Build Coastguard Worker 
5335*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost2.local.", 4567, 0, 1, 120, kInAnswerSection);
5336*cfb92d14SAndroid Build Coastguard Worker 
5337*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5338*cfb92d14SAndroid Build Coastguard Worker 
5339*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5340*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5341*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5342*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5343*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost2"));
5344*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 4567);
5345*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 0);
5346*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 1);
5347*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5348*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5349*cfb92d14SAndroid Build Coastguard Worker 
5350*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5351*cfb92d14SAndroid Build Coastguard Worker 
5352*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5353*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing TTL. Validate callback result.");
5354*cfb92d14SAndroid Build Coastguard Worker 
5355*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5356*cfb92d14SAndroid Build Coastguard Worker 
5357*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5358*cfb92d14SAndroid Build Coastguard Worker 
5359*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost2.local.", 4567, 0, 1, 0, kInAnswerSection);
5360*cfb92d14SAndroid Build Coastguard Worker 
5361*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5362*cfb92d14SAndroid Build Coastguard Worker 
5363*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5364*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5365*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5366*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5367*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches(""));
5368*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 4567);
5369*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 0);
5370*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 1);
5371*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 0);
5372*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5373*cfb92d14SAndroid Build Coastguard Worker 
5374*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5375*cfb92d14SAndroid Build Coastguard Worker 
5376*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5377*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing a bunch of things. Validate callback result.");
5378*cfb92d14SAndroid Build Coastguard Worker 
5379*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5380*cfb92d14SAndroid Build Coastguard Worker 
5381*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5382*cfb92d14SAndroid Build Coastguard Worker 
5383*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 2, 3, 120, kInAnswerSection);
5384*cfb92d14SAndroid Build Coastguard Worker 
5385*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5386*cfb92d14SAndroid Build Coastguard Worker 
5387*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5388*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5389*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5390*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5391*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5392*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5393*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
5394*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
5395*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5396*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5397*cfb92d14SAndroid Build Coastguard Worker 
5398*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5399*cfb92d14SAndroid Build Coastguard Worker 
5400*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5401*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response with no changes. Validate callback is not invoked.");
5402*cfb92d14SAndroid Build Coastguard Worker 
5403*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5404*cfb92d14SAndroid Build Coastguard Worker 
5405*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5406*cfb92d14SAndroid Build Coastguard Worker 
5407*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 2, 3, 120, kInAnswerSection);
5408*cfb92d14SAndroid Build Coastguard Worker 
5409*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5410*cfb92d14SAndroid Build Coastguard Worker 
5411*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5412*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5413*cfb92d14SAndroid Build Coastguard Worker 
5414*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5415*cfb92d14SAndroid Build Coastguard Worker     Log("Start another resolver for the same service and different callback. Validate results.");
5416*cfb92d14SAndroid Build Coastguard Worker 
5417*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(resolver2);
5418*cfb92d14SAndroid Build Coastguard Worker 
5419*cfb92d14SAndroid Build Coastguard Worker     resolver2.mServiceInstance = "mysrv";
5420*cfb92d14SAndroid Build Coastguard Worker     resolver2.mServiceType     = "_srv._udp";
5421*cfb92d14SAndroid Build Coastguard Worker     resolver2.mInfraIfIndex    = kInfraIfIndex;
5422*cfb92d14SAndroid Build Coastguard Worker     resolver2.mCallback        = HandleSrvResultAlternate;
5423*cfb92d14SAndroid Build Coastguard Worker 
5424*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5425*cfb92d14SAndroid Build Coastguard Worker 
5426*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(resolver2));
5427*cfb92d14SAndroid Build Coastguard Worker 
5428*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5429*cfb92d14SAndroid Build Coastguard Worker 
5430*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5431*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5432*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5433*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5434*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5435*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5436*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
5437*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
5438*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5439*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5440*cfb92d14SAndroid Build Coastguard Worker 
5441*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5442*cfb92d14SAndroid Build Coastguard Worker 
5443*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5444*cfb92d14SAndroid Build Coastguard Worker     Log("Start same resolver again and check the returned error.");
5445*cfb92d14SAndroid Build Coastguard Worker 
5446*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5447*cfb92d14SAndroid Build Coastguard Worker 
5448*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(mdns->StartSrvResolver(resolver2) == kErrorAlready);
5449*cfb92d14SAndroid Build Coastguard Worker 
5450*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
5451*cfb92d14SAndroid Build Coastguard Worker 
5452*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5453*cfb92d14SAndroid Build Coastguard Worker 
5454*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5455*cfb92d14SAndroid Build Coastguard Worker     Log("Check query is sent at 80 percentage of TTL and then respond to it.");
5456*cfb92d14SAndroid Build Coastguard Worker 
5457*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 2, 3, 120, kInAnswerSection);
5458*cfb92d14SAndroid Build Coastguard Worker 
5459*cfb92d14SAndroid Build Coastguard Worker     // First query should be sent at 80-82% of TTL of 120 second (96.0-98.4 sec).
5460*cfb92d14SAndroid Build Coastguard Worker     // We wait for 100 second. Note that 5 seconds already passed in the
5461*cfb92d14SAndroid Build Coastguard Worker     // previous step.
5462*cfb92d14SAndroid Build Coastguard Worker 
5463*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(96 * 1000 - 1);
5464*cfb92d14SAndroid Build Coastguard Worker 
5465*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5466*cfb92d14SAndroid Build Coastguard Worker 
5467*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(4 * 1000 + 1);
5468*cfb92d14SAndroid Build Coastguard Worker 
5469*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
5470*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
5471*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5472*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateAsQueryFor(resolver);
5473*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5474*cfb92d14SAndroid Build Coastguard Worker 
5475*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5476*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5477*cfb92d14SAndroid Build Coastguard Worker 
5478*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
5479*cfb92d14SAndroid Build Coastguard Worker 
5480*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 2, 3, 120, kInAnswerSection);
5481*cfb92d14SAndroid Build Coastguard Worker 
5482*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5483*cfb92d14SAndroid Build Coastguard Worker     Log("Check queries are sent at 80, 85, 90, 95 percentages of TTL.");
5484*cfb92d14SAndroid Build Coastguard Worker 
5485*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumRefreshQueries; queryCount++)
5486*cfb92d14SAndroid Build Coastguard Worker     {
5487*cfb92d14SAndroid Build Coastguard Worker         if (queryCount == 0)
5488*cfb92d14SAndroid Build Coastguard Worker         {
5489*cfb92d14SAndroid Build Coastguard Worker             // First query is expected in 80-82% of TTL, so
5490*cfb92d14SAndroid Build Coastguard Worker             // 80% of 120 = 96.0, 82% of 120 = 98.4
5491*cfb92d14SAndroid Build Coastguard Worker 
5492*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(96 * 1000 - 1);
5493*cfb92d14SAndroid Build Coastguard Worker         }
5494*cfb92d14SAndroid Build Coastguard Worker         else
5495*cfb92d14SAndroid Build Coastguard Worker         {
5496*cfb92d14SAndroid Build Coastguard Worker             // Next query should happen within 3%-5% of TTL
5497*cfb92d14SAndroid Build Coastguard Worker             // from previous query. We wait 3% of TTL here.
5498*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(3600 - 1);
5499*cfb92d14SAndroid Build Coastguard Worker         }
5500*cfb92d14SAndroid Build Coastguard Worker 
5501*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
5502*cfb92d14SAndroid Build Coastguard Worker 
5503*cfb92d14SAndroid Build Coastguard Worker         // Wait for 2% of TTL of 120 which is 2.4 sec.
5504*cfb92d14SAndroid Build Coastguard Worker 
5505*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2400 + 1);
5506*cfb92d14SAndroid Build Coastguard Worker 
5507*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5508*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5509*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5510*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
5511*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5512*cfb92d14SAndroid Build Coastguard Worker 
5513*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5514*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sSrvCallbacks.IsEmpty());
5515*cfb92d14SAndroid Build Coastguard Worker     }
5516*cfb92d14SAndroid Build Coastguard Worker 
5517*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5518*cfb92d14SAndroid Build Coastguard Worker     Log("Check TTL timeout and callback result.");
5519*cfb92d14SAndroid Build Coastguard Worker 
5520*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(6 * 1000);
5521*cfb92d14SAndroid Build Coastguard Worker 
5522*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5523*cfb92d14SAndroid Build Coastguard Worker 
5524*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
5525*cfb92d14SAndroid Build Coastguard Worker     {
5526*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(srvCallback != nullptr);
5527*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5528*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5529*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(srvCallback->mTtl == 0);
5530*cfb92d14SAndroid Build Coastguard Worker         srvCallback = srvCallback->GetNext();
5531*cfb92d14SAndroid Build Coastguard Worker     }
5532*cfb92d14SAndroid Build Coastguard Worker 
5533*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback == nullptr);
5534*cfb92d14SAndroid Build Coastguard Worker 
5535*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5536*cfb92d14SAndroid Build Coastguard Worker 
5537*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5538*cfb92d14SAndroid Build Coastguard Worker 
5539*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5540*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5541*cfb92d14SAndroid Build Coastguard Worker 
5542*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200 * 1000);
5543*cfb92d14SAndroid Build Coastguard Worker 
5544*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5545*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5546*cfb92d14SAndroid Build Coastguard Worker 
5547*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5548*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the second resolver");
5549*cfb92d14SAndroid Build Coastguard Worker 
5550*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5551*cfb92d14SAndroid Build Coastguard Worker 
5552*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopSrvResolver(resolver2));
5553*cfb92d14SAndroid Build Coastguard Worker 
5554*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100 * 1000);
5555*cfb92d14SAndroid Build Coastguard Worker 
5556*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5557*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5558*cfb92d14SAndroid Build Coastguard Worker 
5559*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5560*cfb92d14SAndroid Build Coastguard Worker     Log("Send a new response and make sure result callback is invoked");
5561*cfb92d14SAndroid Build Coastguard Worker 
5562*cfb92d14SAndroid Build Coastguard Worker     SendSrvResponse("mysrv._srv._udp.local.", "myhost.local.", 1234, 2, 3, 120, kInAnswerSection);
5563*cfb92d14SAndroid Build Coastguard Worker 
5564*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5565*cfb92d14SAndroid Build Coastguard Worker 
5566*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5567*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5568*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5569*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5570*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5571*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5572*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
5573*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
5574*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5575*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5576*cfb92d14SAndroid Build Coastguard Worker 
5577*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5578*cfb92d14SAndroid Build Coastguard Worker 
5579*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5580*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the resolver. There is no active resolver. Ensure no queries are sent");
5581*cfb92d14SAndroid Build Coastguard Worker 
5582*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5583*cfb92d14SAndroid Build Coastguard Worker 
5584*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopSrvResolver(resolver));
5585*cfb92d14SAndroid Build Coastguard Worker 
5586*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
5587*cfb92d14SAndroid Build Coastguard Worker 
5588*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sSrvCallbacks.IsEmpty());
5589*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5590*cfb92d14SAndroid Build Coastguard Worker 
5591*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5592*cfb92d14SAndroid Build Coastguard Worker     Log("Restart the resolver with more than half of TTL remaining.");
5593*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is reported in the result callback and no queries are sent.");
5594*cfb92d14SAndroid Build Coastguard Worker 
5595*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(resolver));
5596*cfb92d14SAndroid Build Coastguard Worker 
5597*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5598*cfb92d14SAndroid Build Coastguard Worker 
5599*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5600*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5601*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5602*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5603*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5604*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5605*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
5606*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
5607*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5608*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5609*cfb92d14SAndroid Build Coastguard Worker 
5610*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5611*cfb92d14SAndroid Build Coastguard Worker 
5612*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
5613*cfb92d14SAndroid Build Coastguard Worker 
5614*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5615*cfb92d14SAndroid Build Coastguard Worker 
5616*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5617*cfb92d14SAndroid Build Coastguard Worker     Log("Stop and start the resolver again after less than half TTL remaining.");
5618*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is still reported in the result callback but queries should be sent");
5619*cfb92d14SAndroid Build Coastguard Worker 
5620*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5621*cfb92d14SAndroid Build Coastguard Worker 
5622*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopSrvResolver(resolver));
5623*cfb92d14SAndroid Build Coastguard Worker 
5624*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(25 * 1000);
5625*cfb92d14SAndroid Build Coastguard Worker 
5626*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(resolver));
5627*cfb92d14SAndroid Build Coastguard Worker 
5628*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5629*cfb92d14SAndroid Build Coastguard Worker 
5630*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
5631*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
5632*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("mysrv"));
5633*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
5634*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("myhost"));
5635*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1234);
5636*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
5637*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
5638*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 120);
5639*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
5640*cfb92d14SAndroid Build Coastguard Worker 
5641*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
5642*cfb92d14SAndroid Build Coastguard Worker 
5643*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15 * 1000);
5644*cfb92d14SAndroid Build Coastguard Worker 
5645*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
5646*cfb92d14SAndroid Build Coastguard Worker 
5647*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
5648*cfb92d14SAndroid Build Coastguard Worker     {
5649*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
5650*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5651*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
5652*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
5653*cfb92d14SAndroid Build Coastguard Worker     }
5654*cfb92d14SAndroid Build Coastguard Worker 
5655*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg == nullptr);
5656*cfb92d14SAndroid Build Coastguard Worker 
5657*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5658*cfb92d14SAndroid Build Coastguard Worker 
5659*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
5660*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
5661*cfb92d14SAndroid Build Coastguard Worker 
5662*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
5663*cfb92d14SAndroid Build Coastguard Worker 
5664*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
5665*cfb92d14SAndroid Build Coastguard Worker }
5666*cfb92d14SAndroid Build Coastguard Worker 
TestTxtResolver(void)5667*cfb92d14SAndroid Build Coastguard Worker void TestTxtResolver(void)
5668*cfb92d14SAndroid Build Coastguard Worker {
5669*cfb92d14SAndroid Build Coastguard Worker     Core              *mdns = InitTest();
5670*cfb92d14SAndroid Build Coastguard Worker     Core::TxtResolver  resolver;
5671*cfb92d14SAndroid Build Coastguard Worker     Core::TxtResolver  resolver2;
5672*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage  *dnsMsg;
5673*cfb92d14SAndroid Build Coastguard Worker     const TxtCallback *txtCallback;
5674*cfb92d14SAndroid Build Coastguard Worker     uint16_t           heapAllocations;
5675*cfb92d14SAndroid Build Coastguard Worker 
5676*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
5677*cfb92d14SAndroid Build Coastguard Worker     Log("TestTxtResolver");
5678*cfb92d14SAndroid Build Coastguard Worker 
5679*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5680*cfb92d14SAndroid Build Coastguard Worker 
5681*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
5682*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
5683*cfb92d14SAndroid Build Coastguard Worker 
5684*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5685*cfb92d14SAndroid Build Coastguard Worker     Log("Start a TXT resolver. Validate initial queries.");
5686*cfb92d14SAndroid Build Coastguard Worker 
5687*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(resolver);
5688*cfb92d14SAndroid Build Coastguard Worker 
5689*cfb92d14SAndroid Build Coastguard Worker     resolver.mServiceInstance = "mysrv";
5690*cfb92d14SAndroid Build Coastguard Worker     resolver.mServiceType     = "_srv._udp";
5691*cfb92d14SAndroid Build Coastguard Worker     resolver.mInfraIfIndex    = kInfraIfIndex;
5692*cfb92d14SAndroid Build Coastguard Worker     resolver.mCallback        = HandleTxtResult;
5693*cfb92d14SAndroid Build Coastguard Worker 
5694*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5695*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(resolver));
5696*cfb92d14SAndroid Build Coastguard Worker 
5697*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
5698*cfb92d14SAndroid Build Coastguard Worker     {
5699*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5700*cfb92d14SAndroid Build Coastguard Worker 
5701*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((queryCount == 0) ? 125 : (1U << (queryCount - 1)) * 1000);
5702*cfb92d14SAndroid Build Coastguard Worker 
5703*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5704*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5705*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5706*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
5707*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5708*cfb92d14SAndroid Build Coastguard Worker     }
5709*cfb92d14SAndroid Build Coastguard Worker 
5710*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5711*cfb92d14SAndroid Build Coastguard Worker 
5712*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
5713*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5714*cfb92d14SAndroid Build Coastguard Worker 
5715*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5716*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response. Validate callback result.");
5717*cfb92d14SAndroid Build Coastguard Worker 
5718*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5719*cfb92d14SAndroid Build Coastguard Worker 
5720*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5721*cfb92d14SAndroid Build Coastguard Worker 
5722*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5723*cfb92d14SAndroid Build Coastguard Worker 
5724*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5725*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5726*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5727*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5728*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
5729*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
5730*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5731*cfb92d14SAndroid Build Coastguard Worker 
5732*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5733*cfb92d14SAndroid Build Coastguard Worker 
5734*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5735*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing TXT data. Validate callback result.");
5736*cfb92d14SAndroid Build Coastguard Worker 
5737*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5738*cfb92d14SAndroid Build Coastguard Worker 
5739*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5740*cfb92d14SAndroid Build Coastguard Worker 
5741*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData2, sizeof(kTxtData2), 120, kInAnswerSection);
5742*cfb92d14SAndroid Build Coastguard Worker 
5743*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5744*cfb92d14SAndroid Build Coastguard Worker 
5745*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5746*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5747*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5748*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5749*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData2));
5750*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
5751*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5752*cfb92d14SAndroid Build Coastguard Worker 
5753*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5754*cfb92d14SAndroid Build Coastguard Worker 
5755*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5756*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing TXT data to empty. Validate callback result.");
5757*cfb92d14SAndroid Build Coastguard Worker 
5758*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5759*cfb92d14SAndroid Build Coastguard Worker 
5760*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5761*cfb92d14SAndroid Build Coastguard Worker 
5762*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kEmptyTxtData, sizeof(kEmptyTxtData), 120, kInAnswerSection);
5763*cfb92d14SAndroid Build Coastguard Worker 
5764*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5765*cfb92d14SAndroid Build Coastguard Worker 
5766*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5767*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5768*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5769*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5770*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kEmptyTxtData));
5771*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
5772*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5773*cfb92d14SAndroid Build Coastguard Worker 
5774*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5775*cfb92d14SAndroid Build Coastguard Worker 
5776*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5777*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response changing TTL. Validate callback result.");
5778*cfb92d14SAndroid Build Coastguard Worker 
5779*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5780*cfb92d14SAndroid Build Coastguard Worker 
5781*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5782*cfb92d14SAndroid Build Coastguard Worker 
5783*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kEmptyTxtData, sizeof(kEmptyTxtData), 500, kInAnswerSection);
5784*cfb92d14SAndroid Build Coastguard Worker 
5785*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5786*cfb92d14SAndroid Build Coastguard Worker 
5787*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5788*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5789*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5790*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5791*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kEmptyTxtData));
5792*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 500);
5793*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5794*cfb92d14SAndroid Build Coastguard Worker 
5795*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5796*cfb92d14SAndroid Build Coastguard Worker 
5797*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5798*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response with zero TTL. Validate callback result.");
5799*cfb92d14SAndroid Build Coastguard Worker 
5800*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5801*cfb92d14SAndroid Build Coastguard Worker 
5802*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5803*cfb92d14SAndroid Build Coastguard Worker 
5804*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kEmptyTxtData, sizeof(kEmptyTxtData), 0, kInAnswerSection);
5805*cfb92d14SAndroid Build Coastguard Worker 
5806*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5807*cfb92d14SAndroid Build Coastguard Worker 
5808*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5809*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5810*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5811*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5812*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 0);
5813*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5814*cfb92d14SAndroid Build Coastguard Worker 
5815*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5816*cfb92d14SAndroid Build Coastguard Worker 
5817*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5818*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response. Validate callback result.");
5819*cfb92d14SAndroid Build Coastguard Worker 
5820*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5821*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100 * 1000);
5822*cfb92d14SAndroid Build Coastguard Worker 
5823*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5824*cfb92d14SAndroid Build Coastguard Worker 
5825*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5826*cfb92d14SAndroid Build Coastguard Worker 
5827*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5828*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5829*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5830*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5831*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
5832*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
5833*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5834*cfb92d14SAndroid Build Coastguard Worker 
5835*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5836*cfb92d14SAndroid Build Coastguard Worker 
5837*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5838*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response with no changes. Validate callback is not invoked.");
5839*cfb92d14SAndroid Build Coastguard Worker 
5840*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
5841*cfb92d14SAndroid Build Coastguard Worker 
5842*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5843*cfb92d14SAndroid Build Coastguard Worker 
5844*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5845*cfb92d14SAndroid Build Coastguard Worker 
5846*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100);
5847*cfb92d14SAndroid Build Coastguard Worker 
5848*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
5849*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5850*cfb92d14SAndroid Build Coastguard Worker 
5851*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5852*cfb92d14SAndroid Build Coastguard Worker     Log("Start another resolver for the same service and different callback. Validate results.");
5853*cfb92d14SAndroid Build Coastguard Worker 
5854*cfb92d14SAndroid Build Coastguard Worker     resolver2.mServiceInstance = "mysrv";
5855*cfb92d14SAndroid Build Coastguard Worker     resolver2.mServiceType     = "_srv._udp";
5856*cfb92d14SAndroid Build Coastguard Worker     resolver2.mInfraIfIndex    = kInfraIfIndex;
5857*cfb92d14SAndroid Build Coastguard Worker     resolver2.mCallback        = HandleTxtResultAlternate;
5858*cfb92d14SAndroid Build Coastguard Worker 
5859*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5860*cfb92d14SAndroid Build Coastguard Worker 
5861*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(resolver2));
5862*cfb92d14SAndroid Build Coastguard Worker 
5863*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5864*cfb92d14SAndroid Build Coastguard Worker 
5865*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5866*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5867*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5868*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5869*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
5870*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
5871*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
5872*cfb92d14SAndroid Build Coastguard Worker 
5873*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5874*cfb92d14SAndroid Build Coastguard Worker     Log("Start same resolver again and check the returned error.");
5875*cfb92d14SAndroid Build Coastguard Worker 
5876*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5877*cfb92d14SAndroid Build Coastguard Worker 
5878*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(mdns->StartTxtResolver(resolver2) == kErrorAlready);
5879*cfb92d14SAndroid Build Coastguard Worker 
5880*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
5881*cfb92d14SAndroid Build Coastguard Worker 
5882*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
5883*cfb92d14SAndroid Build Coastguard Worker 
5884*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5885*cfb92d14SAndroid Build Coastguard Worker     Log("Check query is sent at 80 percentage of TTL and then respond to it.");
5886*cfb92d14SAndroid Build Coastguard Worker 
5887*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5888*cfb92d14SAndroid Build Coastguard Worker 
5889*cfb92d14SAndroid Build Coastguard Worker     // First query should be sent at 80-82% of TTL of 120 second (96.0-98.4 sec).
5890*cfb92d14SAndroid Build Coastguard Worker     // We wait for 100 second. Note that 5 seconds already passed in the
5891*cfb92d14SAndroid Build Coastguard Worker     // previous step.
5892*cfb92d14SAndroid Build Coastguard Worker 
5893*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(96 * 1000 - 1);
5894*cfb92d14SAndroid Build Coastguard Worker 
5895*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5896*cfb92d14SAndroid Build Coastguard Worker 
5897*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(4 * 1000 + 1);
5898*cfb92d14SAndroid Build Coastguard Worker 
5899*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
5900*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
5901*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5902*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateAsQueryFor(resolver);
5903*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5904*cfb92d14SAndroid Build Coastguard Worker 
5905*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5906*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
5907*cfb92d14SAndroid Build Coastguard Worker 
5908*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
5909*cfb92d14SAndroid Build Coastguard Worker 
5910*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5911*cfb92d14SAndroid Build Coastguard Worker 
5912*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5913*cfb92d14SAndroid Build Coastguard Worker     Log("Check queries are sent at 80, 85, 90, 95 percentages of TTL.");
5914*cfb92d14SAndroid Build Coastguard Worker 
5915*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumRefreshQueries; queryCount++)
5916*cfb92d14SAndroid Build Coastguard Worker     {
5917*cfb92d14SAndroid Build Coastguard Worker         if (queryCount == 0)
5918*cfb92d14SAndroid Build Coastguard Worker         {
5919*cfb92d14SAndroid Build Coastguard Worker             // First query is expected in 80-82% of TTL, so
5920*cfb92d14SAndroid Build Coastguard Worker             // 80% of 120 = 96.0, 82% of 120 = 98.4
5921*cfb92d14SAndroid Build Coastguard Worker 
5922*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(96 * 1000 - 1);
5923*cfb92d14SAndroid Build Coastguard Worker         }
5924*cfb92d14SAndroid Build Coastguard Worker         else
5925*cfb92d14SAndroid Build Coastguard Worker         {
5926*cfb92d14SAndroid Build Coastguard Worker             // Next query should happen within 3%-5% of TTL
5927*cfb92d14SAndroid Build Coastguard Worker             // from previous query. We wait 3% of TTL here.
5928*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(3600 - 1);
5929*cfb92d14SAndroid Build Coastguard Worker         }
5930*cfb92d14SAndroid Build Coastguard Worker 
5931*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
5932*cfb92d14SAndroid Build Coastguard Worker 
5933*cfb92d14SAndroid Build Coastguard Worker         // Wait for 2% of TTL of 120 which is 2.4 sec.
5934*cfb92d14SAndroid Build Coastguard Worker 
5935*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2400 + 1);
5936*cfb92d14SAndroid Build Coastguard Worker 
5937*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
5938*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
5939*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
5940*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
5941*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
5942*cfb92d14SAndroid Build Coastguard Worker 
5943*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
5944*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sTxtCallbacks.IsEmpty());
5945*cfb92d14SAndroid Build Coastguard Worker     }
5946*cfb92d14SAndroid Build Coastguard Worker 
5947*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5948*cfb92d14SAndroid Build Coastguard Worker     Log("Check TTL timeout and callback result.");
5949*cfb92d14SAndroid Build Coastguard Worker 
5950*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(6 * 1000);
5951*cfb92d14SAndroid Build Coastguard Worker 
5952*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5953*cfb92d14SAndroid Build Coastguard Worker 
5954*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
5955*cfb92d14SAndroid Build Coastguard Worker     {
5956*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(txtCallback != nullptr);
5957*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5958*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
5959*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(txtCallback->mTtl == 0);
5960*cfb92d14SAndroid Build Coastguard Worker         txtCallback = txtCallback->GetNext();
5961*cfb92d14SAndroid Build Coastguard Worker     }
5962*cfb92d14SAndroid Build Coastguard Worker 
5963*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback == nullptr);
5964*cfb92d14SAndroid Build Coastguard Worker 
5965*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5966*cfb92d14SAndroid Build Coastguard Worker 
5967*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5968*cfb92d14SAndroid Build Coastguard Worker 
5969*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5970*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
5971*cfb92d14SAndroid Build Coastguard Worker 
5972*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200 * 1000);
5973*cfb92d14SAndroid Build Coastguard Worker 
5974*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
5975*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5976*cfb92d14SAndroid Build Coastguard Worker 
5977*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5978*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the second resolver");
5979*cfb92d14SAndroid Build Coastguard Worker 
5980*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
5981*cfb92d14SAndroid Build Coastguard Worker 
5982*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopTxtResolver(resolver2));
5983*cfb92d14SAndroid Build Coastguard Worker 
5984*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100 * 1000);
5985*cfb92d14SAndroid Build Coastguard Worker 
5986*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
5987*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
5988*cfb92d14SAndroid Build Coastguard Worker 
5989*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
5990*cfb92d14SAndroid Build Coastguard Worker     Log("Send a new response and make sure result callback is invoked");
5991*cfb92d14SAndroid Build Coastguard Worker 
5992*cfb92d14SAndroid Build Coastguard Worker     SendTxtResponse("mysrv._srv._udp.local.", kTxtData1, sizeof(kTxtData1), 120, kInAnswerSection);
5993*cfb92d14SAndroid Build Coastguard Worker 
5994*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
5995*cfb92d14SAndroid Build Coastguard Worker 
5996*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
5997*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
5998*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
5999*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
6000*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
6001*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
6002*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6003*cfb92d14SAndroid Build Coastguard Worker 
6004*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6005*cfb92d14SAndroid Build Coastguard Worker 
6006*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6007*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the resolver. There is no active resolver. Ensure no queries are sent");
6008*cfb92d14SAndroid Build Coastguard Worker 
6009*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6010*cfb92d14SAndroid Build Coastguard Worker 
6011*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopTxtResolver(resolver));
6012*cfb92d14SAndroid Build Coastguard Worker 
6013*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
6014*cfb92d14SAndroid Build Coastguard Worker 
6015*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTxtCallbacks.IsEmpty());
6016*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6017*cfb92d14SAndroid Build Coastguard Worker 
6018*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6019*cfb92d14SAndroid Build Coastguard Worker     Log("Restart the resolver with more than half of TTL remaining.");
6020*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is reported in the result callback and no queries are sent.");
6021*cfb92d14SAndroid Build Coastguard Worker 
6022*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(resolver));
6023*cfb92d14SAndroid Build Coastguard Worker 
6024*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6025*cfb92d14SAndroid Build Coastguard Worker 
6026*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
6027*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
6028*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
6029*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
6030*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
6031*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
6032*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6033*cfb92d14SAndroid Build Coastguard Worker 
6034*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6035*cfb92d14SAndroid Build Coastguard Worker 
6036*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
6037*cfb92d14SAndroid Build Coastguard Worker 
6038*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6039*cfb92d14SAndroid Build Coastguard Worker 
6040*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6041*cfb92d14SAndroid Build Coastguard Worker     Log("Stop and start the resolver again after less than half TTL remaining.");
6042*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is still reported in the result callback but queries should be sent");
6043*cfb92d14SAndroid Build Coastguard Worker 
6044*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6045*cfb92d14SAndroid Build Coastguard Worker 
6046*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopTxtResolver(resolver));
6047*cfb92d14SAndroid Build Coastguard Worker 
6048*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(25 * 1000);
6049*cfb92d14SAndroid Build Coastguard Worker 
6050*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(resolver));
6051*cfb92d14SAndroid Build Coastguard Worker 
6052*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6053*cfb92d14SAndroid Build Coastguard Worker 
6054*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
6055*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
6056*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("mysrv"));
6057*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
6058*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
6059*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 120);
6060*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6061*cfb92d14SAndroid Build Coastguard Worker 
6062*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6063*cfb92d14SAndroid Build Coastguard Worker 
6064*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15 * 1000);
6065*cfb92d14SAndroid Build Coastguard Worker 
6066*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
6067*cfb92d14SAndroid Build Coastguard Worker 
6068*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
6069*cfb92d14SAndroid Build Coastguard Worker     {
6070*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
6071*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
6072*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
6073*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
6074*cfb92d14SAndroid Build Coastguard Worker     }
6075*cfb92d14SAndroid Build Coastguard Worker 
6076*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg == nullptr);
6077*cfb92d14SAndroid Build Coastguard Worker 
6078*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6079*cfb92d14SAndroid Build Coastguard Worker 
6080*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
6081*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
6082*cfb92d14SAndroid Build Coastguard Worker 
6083*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
6084*cfb92d14SAndroid Build Coastguard Worker 
6085*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
6086*cfb92d14SAndroid Build Coastguard Worker }
6087*cfb92d14SAndroid Build Coastguard Worker 
TestIp6AddrResolver(void)6088*cfb92d14SAndroid Build Coastguard Worker void TestIp6AddrResolver(void)
6089*cfb92d14SAndroid Build Coastguard Worker {
6090*cfb92d14SAndroid Build Coastguard Worker     Core                 *mdns = InitTest();
6091*cfb92d14SAndroid Build Coastguard Worker     Core::AddressResolver resolver;
6092*cfb92d14SAndroid Build Coastguard Worker     Core::AddressResolver resolver2;
6093*cfb92d14SAndroid Build Coastguard Worker     AddrAndTtl            addrs[5];
6094*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage     *dnsMsg;
6095*cfb92d14SAndroid Build Coastguard Worker     const AddrCallback   *addrCallback;
6096*cfb92d14SAndroid Build Coastguard Worker     uint16_t              heapAllocations;
6097*cfb92d14SAndroid Build Coastguard Worker 
6098*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
6099*cfb92d14SAndroid Build Coastguard Worker     Log("TestIp6AddrResolver");
6100*cfb92d14SAndroid Build Coastguard Worker 
6101*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6102*cfb92d14SAndroid Build Coastguard Worker 
6103*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
6104*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
6105*cfb92d14SAndroid Build Coastguard Worker 
6106*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6107*cfb92d14SAndroid Build Coastguard Worker     Log("Start an IPv6 address resolver. Validate initial queries.");
6108*cfb92d14SAndroid Build Coastguard Worker 
6109*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(resolver);
6110*cfb92d14SAndroid Build Coastguard Worker 
6111*cfb92d14SAndroid Build Coastguard Worker     resolver.mHostName     = "myhost";
6112*cfb92d14SAndroid Build Coastguard Worker     resolver.mInfraIfIndex = kInfraIfIndex;
6113*cfb92d14SAndroid Build Coastguard Worker     resolver.mCallback     = HandleAddrResult;
6114*cfb92d14SAndroid Build Coastguard Worker 
6115*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6116*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(resolver));
6117*cfb92d14SAndroid Build Coastguard Worker 
6118*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
6119*cfb92d14SAndroid Build Coastguard Worker     {
6120*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
6121*cfb92d14SAndroid Build Coastguard Worker 
6122*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime((queryCount == 0) ? 125 : (1U << (queryCount - 1)) * 1000);
6123*cfb92d14SAndroid Build Coastguard Worker 
6124*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
6125*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
6126*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
6127*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
6128*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
6129*cfb92d14SAndroid Build Coastguard Worker     }
6130*cfb92d14SAndroid Build Coastguard Worker 
6131*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6132*cfb92d14SAndroid Build Coastguard Worker 
6133*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
6134*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6135*cfb92d14SAndroid Build Coastguard Worker 
6136*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6137*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response. Validate callback result.");
6138*cfb92d14SAndroid Build Coastguard Worker 
6139*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6140*cfb92d14SAndroid Build Coastguard Worker 
6141*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[0].mAddress.FromString("fd00::1"));
6142*cfb92d14SAndroid Build Coastguard Worker     addrs[0].mTtl = 120;
6143*cfb92d14SAndroid Build Coastguard Worker 
6144*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 1, /* aCachFlush */ true, kInAnswerSection);
6145*cfb92d14SAndroid Build Coastguard Worker 
6146*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6147*cfb92d14SAndroid Build Coastguard Worker 
6148*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6149*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6150*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6151*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 1));
6152*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6153*cfb92d14SAndroid Build Coastguard Worker 
6154*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6155*cfb92d14SAndroid Build Coastguard Worker 
6156*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6157*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response adding a new address. Validate callback result.");
6158*cfb92d14SAndroid Build Coastguard Worker 
6159*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[1].mAddress.FromString("fd00::2"));
6160*cfb92d14SAndroid Build Coastguard Worker     addrs[1].mTtl = 120;
6161*cfb92d14SAndroid Build Coastguard Worker 
6162*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6163*cfb92d14SAndroid Build Coastguard Worker 
6164*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6165*cfb92d14SAndroid Build Coastguard Worker 
6166*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 2, /* aCachFlush */ true, kInAnswerSection);
6167*cfb92d14SAndroid Build Coastguard Worker 
6168*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6169*cfb92d14SAndroid Build Coastguard Worker 
6170*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6171*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6172*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6173*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 2));
6174*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6175*cfb92d14SAndroid Build Coastguard Worker 
6176*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6177*cfb92d14SAndroid Build Coastguard Worker 
6178*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6179*cfb92d14SAndroid Build Coastguard Worker     Log("Send an updated response adding and removing addresses. Validate callback result.");
6180*cfb92d14SAndroid Build Coastguard Worker 
6181*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[0].mAddress.FromString("fd00::2"));
6182*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[1].mAddress.FromString("fd00::aa"));
6183*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[2].mAddress.FromString("fe80::bb"));
6184*cfb92d14SAndroid Build Coastguard Worker     addrs[0].mTtl = 120;
6185*cfb92d14SAndroid Build Coastguard Worker     addrs[1].mTtl = 120;
6186*cfb92d14SAndroid Build Coastguard Worker     addrs[2].mTtl = 120;
6187*cfb92d14SAndroid Build Coastguard Worker 
6188*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6189*cfb92d14SAndroid Build Coastguard Worker 
6190*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6191*cfb92d14SAndroid Build Coastguard Worker 
6192*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 3, /* aCachFlush */ true, kInAnswerSection);
6193*cfb92d14SAndroid Build Coastguard Worker 
6194*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6195*cfb92d14SAndroid Build Coastguard Worker 
6196*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6197*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6198*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6199*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 3));
6200*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6201*cfb92d14SAndroid Build Coastguard Worker 
6202*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6203*cfb92d14SAndroid Build Coastguard Worker 
6204*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6205*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response without cache flush adding an address. Validate callback result.");
6206*cfb92d14SAndroid Build Coastguard Worker 
6207*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[3].mAddress.FromString("fd00::3"));
6208*cfb92d14SAndroid Build Coastguard Worker     addrs[3].mTtl = 500;
6209*cfb92d14SAndroid Build Coastguard Worker 
6210*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6211*cfb92d14SAndroid Build Coastguard Worker 
6212*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6213*cfb92d14SAndroid Build Coastguard Worker 
6214*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", &addrs[3], 1, /* aCachFlush */ false, kInAnswerSection);
6215*cfb92d14SAndroid Build Coastguard Worker 
6216*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6217*cfb92d14SAndroid Build Coastguard Worker 
6218*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6219*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6220*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6221*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 4));
6222*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6223*cfb92d14SAndroid Build Coastguard Worker 
6224*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6225*cfb92d14SAndroid Build Coastguard Worker 
6226*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6227*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response without cache flush with existing addresses. Validate that callback is not called.");
6228*cfb92d14SAndroid Build Coastguard Worker 
6229*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6230*cfb92d14SAndroid Build Coastguard Worker 
6231*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6232*cfb92d14SAndroid Build Coastguard Worker 
6233*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", &addrs[2], 2, /* aCachFlush */ false, kInAnswerSection);
6234*cfb92d14SAndroid Build Coastguard Worker 
6235*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6236*cfb92d14SAndroid Build Coastguard Worker 
6237*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6238*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6239*cfb92d14SAndroid Build Coastguard Worker 
6240*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6241*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response without no changes to the list. Validate that callback is not called");
6242*cfb92d14SAndroid Build Coastguard Worker 
6243*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6244*cfb92d14SAndroid Build Coastguard Worker 
6245*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6246*cfb92d14SAndroid Build Coastguard Worker 
6247*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 4, /* aCachFlush */ true, kInAdditionalSection);
6248*cfb92d14SAndroid Build Coastguard Worker 
6249*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6250*cfb92d14SAndroid Build Coastguard Worker 
6251*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6252*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6253*cfb92d14SAndroid Build Coastguard Worker 
6254*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6255*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response without cache flush updating TTL of existing address. Validate callback result.");
6256*cfb92d14SAndroid Build Coastguard Worker 
6257*cfb92d14SAndroid Build Coastguard Worker     addrs[3].mTtl = 200;
6258*cfb92d14SAndroid Build Coastguard Worker 
6259*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6260*cfb92d14SAndroid Build Coastguard Worker 
6261*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6262*cfb92d14SAndroid Build Coastguard Worker 
6263*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", &addrs[3], 1, /* aCachFlush */ false, kInAnswerSection);
6264*cfb92d14SAndroid Build Coastguard Worker 
6265*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6266*cfb92d14SAndroid Build Coastguard Worker 
6267*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6268*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6269*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6270*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 4));
6271*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6272*cfb92d14SAndroid Build Coastguard Worker 
6273*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6274*cfb92d14SAndroid Build Coastguard Worker 
6275*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6276*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response without cache flush removing an address (zero TTL). Validate callback result.");
6277*cfb92d14SAndroid Build Coastguard Worker 
6278*cfb92d14SAndroid Build Coastguard Worker     addrs[3].mTtl = 0;
6279*cfb92d14SAndroid Build Coastguard Worker 
6280*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6281*cfb92d14SAndroid Build Coastguard Worker 
6282*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6283*cfb92d14SAndroid Build Coastguard Worker 
6284*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", &addrs[3], 1, /* aCachFlush */ false, kInAnswerSection);
6285*cfb92d14SAndroid Build Coastguard Worker 
6286*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6287*cfb92d14SAndroid Build Coastguard Worker 
6288*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6289*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6290*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6291*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 3));
6292*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6293*cfb92d14SAndroid Build Coastguard Worker 
6294*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6295*cfb92d14SAndroid Build Coastguard Worker 
6296*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6297*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response with cache flush removing all addresses. Validate callback result.");
6298*cfb92d14SAndroid Build Coastguard Worker 
6299*cfb92d14SAndroid Build Coastguard Worker     addrs[0].mTtl = 0;
6300*cfb92d14SAndroid Build Coastguard Worker 
6301*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
6302*cfb92d14SAndroid Build Coastguard Worker 
6303*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6304*cfb92d14SAndroid Build Coastguard Worker 
6305*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 1, /* aCachFlush */ true, kInAnswerSection);
6306*cfb92d14SAndroid Build Coastguard Worker 
6307*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6308*cfb92d14SAndroid Build Coastguard Worker 
6309*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6310*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6311*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6312*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 0));
6313*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6314*cfb92d14SAndroid Build Coastguard Worker 
6315*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6316*cfb92d14SAndroid Build Coastguard Worker 
6317*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6318*cfb92d14SAndroid Build Coastguard Worker     Log("Send a response with addresses with different TTL. Validate callback result");
6319*cfb92d14SAndroid Build Coastguard Worker 
6320*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[0].mAddress.FromString("fd00::00"));
6321*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[1].mAddress.FromString("fd00::11"));
6322*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[2].mAddress.FromString("fe80::22"));
6323*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(addrs[3].mAddress.FromString("fe80::33"));
6324*cfb92d14SAndroid Build Coastguard Worker     addrs[0].mTtl = 120;
6325*cfb92d14SAndroid Build Coastguard Worker     addrs[1].mTtl = 800;
6326*cfb92d14SAndroid Build Coastguard Worker     addrs[2].mTtl = 2000;
6327*cfb92d14SAndroid Build Coastguard Worker     addrs[3].mTtl = 8000;
6328*cfb92d14SAndroid Build Coastguard Worker 
6329*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5 * 1000);
6330*cfb92d14SAndroid Build Coastguard Worker 
6331*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6332*cfb92d14SAndroid Build Coastguard Worker 
6333*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 4, /* aCachFlush */ true, kInAnswerSection);
6334*cfb92d14SAndroid Build Coastguard Worker 
6335*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6336*cfb92d14SAndroid Build Coastguard Worker 
6337*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6338*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6339*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6340*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 4));
6341*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6342*cfb92d14SAndroid Build Coastguard Worker 
6343*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6344*cfb92d14SAndroid Build Coastguard Worker 
6345*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6346*cfb92d14SAndroid Build Coastguard Worker     Log("Start another resolver for the same host and different callback. Validate results.");
6347*cfb92d14SAndroid Build Coastguard Worker 
6348*cfb92d14SAndroid Build Coastguard Worker     resolver2.mHostName     = "myhost";
6349*cfb92d14SAndroid Build Coastguard Worker     resolver2.mInfraIfIndex = kInfraIfIndex;
6350*cfb92d14SAndroid Build Coastguard Worker     resolver2.mCallback     = HandleAddrResultAlternate;
6351*cfb92d14SAndroid Build Coastguard Worker 
6352*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6353*cfb92d14SAndroid Build Coastguard Worker 
6354*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(resolver2));
6355*cfb92d14SAndroid Build Coastguard Worker 
6356*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6357*cfb92d14SAndroid Build Coastguard Worker 
6358*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6359*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6360*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6361*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 4));
6362*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6363*cfb92d14SAndroid Build Coastguard Worker 
6364*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6365*cfb92d14SAndroid Build Coastguard Worker 
6366*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6367*cfb92d14SAndroid Build Coastguard Worker     Log("Start same resolver again and check the returned error.");
6368*cfb92d14SAndroid Build Coastguard Worker 
6369*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6370*cfb92d14SAndroid Build Coastguard Worker 
6371*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(mdns->StartIp6AddressResolver(resolver2) == kErrorAlready);
6372*cfb92d14SAndroid Build Coastguard Worker 
6373*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5000);
6374*cfb92d14SAndroid Build Coastguard Worker 
6375*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6376*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6377*cfb92d14SAndroid Build Coastguard Worker 
6378*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6379*cfb92d14SAndroid Build Coastguard Worker     Log("Check query is sent at 80 percentage of TTL and then respond to it.");
6380*cfb92d14SAndroid Build Coastguard Worker 
6381*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 4, /* aCachFlush */ true, kInAnswerSection);
6382*cfb92d14SAndroid Build Coastguard Worker 
6383*cfb92d14SAndroid Build Coastguard Worker     // First query should be sent at 80-82% of TTL of 120 second (96.0-98.4 sec).
6384*cfb92d14SAndroid Build Coastguard Worker     // We wait for 100 second. Note that 5 seconds already passed in the
6385*cfb92d14SAndroid Build Coastguard Worker     // previous step.
6386*cfb92d14SAndroid Build Coastguard Worker 
6387*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(96 * 1000 - 1);
6388*cfb92d14SAndroid Build Coastguard Worker 
6389*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6390*cfb92d14SAndroid Build Coastguard Worker 
6391*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(4 * 1000 + 1);
6392*cfb92d14SAndroid Build Coastguard Worker 
6393*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sDnsMessages.IsEmpty());
6394*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
6395*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
6396*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateAsQueryFor(resolver);
6397*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->GetNext() == nullptr);
6398*cfb92d14SAndroid Build Coastguard Worker 
6399*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6400*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6401*cfb92d14SAndroid Build Coastguard Worker 
6402*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10);
6403*cfb92d14SAndroid Build Coastguard Worker 
6404*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 4, /* aCachFlush */ true, kInAnswerSection);
6405*cfb92d14SAndroid Build Coastguard Worker 
6406*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6407*cfb92d14SAndroid Build Coastguard Worker     Log("Check queries are sent at 80, 85, 90, 95 percentages of TTL.");
6408*cfb92d14SAndroid Build Coastguard Worker 
6409*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumRefreshQueries; queryCount++)
6410*cfb92d14SAndroid Build Coastguard Worker     {
6411*cfb92d14SAndroid Build Coastguard Worker         if (queryCount == 0)
6412*cfb92d14SAndroid Build Coastguard Worker         {
6413*cfb92d14SAndroid Build Coastguard Worker             // First query is expected in 80-82% of TTL, so
6414*cfb92d14SAndroid Build Coastguard Worker             // 80% of 120 = 96.0, 82% of 120 = 98.4
6415*cfb92d14SAndroid Build Coastguard Worker 
6416*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(96 * 1000 - 1);
6417*cfb92d14SAndroid Build Coastguard Worker         }
6418*cfb92d14SAndroid Build Coastguard Worker         else
6419*cfb92d14SAndroid Build Coastguard Worker         {
6420*cfb92d14SAndroid Build Coastguard Worker             // Next query should happen within 3%-5% of TTL
6421*cfb92d14SAndroid Build Coastguard Worker             // from previous query. We wait 3% of TTL here.
6422*cfb92d14SAndroid Build Coastguard Worker             AdvanceTime(3600 - 1);
6423*cfb92d14SAndroid Build Coastguard Worker         }
6424*cfb92d14SAndroid Build Coastguard Worker 
6425*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sDnsMessages.IsEmpty());
6426*cfb92d14SAndroid Build Coastguard Worker 
6427*cfb92d14SAndroid Build Coastguard Worker         // Wait for 2% of TTL of 120 which is 2.4 sec.
6428*cfb92d14SAndroid Build Coastguard Worker 
6429*cfb92d14SAndroid Build Coastguard Worker         AdvanceTime(2400 + 1);
6430*cfb92d14SAndroid Build Coastguard Worker 
6431*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!sDnsMessages.IsEmpty());
6432*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = sDnsMessages.GetHead();
6433*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
6434*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
6435*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg->GetNext() == nullptr);
6436*cfb92d14SAndroid Build Coastguard Worker 
6437*cfb92d14SAndroid Build Coastguard Worker         sDnsMessages.Clear();
6438*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sAddrCallbacks.IsEmpty());
6439*cfb92d14SAndroid Build Coastguard Worker     }
6440*cfb92d14SAndroid Build Coastguard Worker 
6441*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6442*cfb92d14SAndroid Build Coastguard Worker     Log("Check TTL timeout of first address (TTL 120) and callback result.");
6443*cfb92d14SAndroid Build Coastguard Worker 
6444*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(6 * 1000);
6445*cfb92d14SAndroid Build Coastguard Worker 
6446*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6447*cfb92d14SAndroid Build Coastguard Worker 
6448*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
6449*cfb92d14SAndroid Build Coastguard Worker     {
6450*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback != nullptr);
6451*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6452*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback->Matches(&addrs[1], 3));
6453*cfb92d14SAndroid Build Coastguard Worker         addrCallback = addrCallback->GetNext();
6454*cfb92d14SAndroid Build Coastguard Worker     }
6455*cfb92d14SAndroid Build Coastguard Worker 
6456*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback == nullptr);
6457*cfb92d14SAndroid Build Coastguard Worker 
6458*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6459*cfb92d14SAndroid Build Coastguard Worker 
6460*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6461*cfb92d14SAndroid Build Coastguard Worker     Log("Check TTL timeout of next address (TTL 800) and callback result.");
6462*cfb92d14SAndroid Build Coastguard Worker 
6463*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6464*cfb92d14SAndroid Build Coastguard Worker 
6465*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime((800 - 120) * 1000);
6466*cfb92d14SAndroid Build Coastguard Worker 
6467*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6468*cfb92d14SAndroid Build Coastguard Worker 
6469*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
6470*cfb92d14SAndroid Build Coastguard Worker     {
6471*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback != nullptr);
6472*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6473*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(addrCallback->Matches(&addrs[2], 2));
6474*cfb92d14SAndroid Build Coastguard Worker         addrCallback = addrCallback->GetNext();
6475*cfb92d14SAndroid Build Coastguard Worker     }
6476*cfb92d14SAndroid Build Coastguard Worker 
6477*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback == nullptr);
6478*cfb92d14SAndroid Build Coastguard Worker 
6479*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6480*cfb92d14SAndroid Build Coastguard Worker 
6481*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6482*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6483*cfb92d14SAndroid Build Coastguard Worker 
6484*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200 * 1000);
6485*cfb92d14SAndroid Build Coastguard Worker 
6486*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6487*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6488*cfb92d14SAndroid Build Coastguard Worker 
6489*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6490*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the second resolver");
6491*cfb92d14SAndroid Build Coastguard Worker 
6492*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6493*cfb92d14SAndroid Build Coastguard Worker 
6494*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopIp6AddressResolver(resolver2));
6495*cfb92d14SAndroid Build Coastguard Worker 
6496*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(100 * 1000);
6497*cfb92d14SAndroid Build Coastguard Worker 
6498*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6499*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6500*cfb92d14SAndroid Build Coastguard Worker 
6501*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6502*cfb92d14SAndroid Build Coastguard Worker     Log("Send a new response and make sure result callback is invoked");
6503*cfb92d14SAndroid Build Coastguard Worker 
6504*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6505*cfb92d14SAndroid Build Coastguard Worker 
6506*cfb92d14SAndroid Build Coastguard Worker     SendHostAddrResponse("myhost.local.", addrs, 1, /* aCachFlush */ true, kInAnswerSection);
6507*cfb92d14SAndroid Build Coastguard Worker 
6508*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6509*cfb92d14SAndroid Build Coastguard Worker 
6510*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6511*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6512*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6513*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 1));
6514*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6515*cfb92d14SAndroid Build Coastguard Worker 
6516*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6517*cfb92d14SAndroid Build Coastguard Worker 
6518*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6519*cfb92d14SAndroid Build Coastguard Worker     Log("Stop the resolver. There is no active resolver. Ensure no queries are sent");
6520*cfb92d14SAndroid Build Coastguard Worker 
6521*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6522*cfb92d14SAndroid Build Coastguard Worker 
6523*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopIp6AddressResolver(resolver));
6524*cfb92d14SAndroid Build Coastguard Worker 
6525*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
6526*cfb92d14SAndroid Build Coastguard Worker 
6527*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sAddrCallbacks.IsEmpty());
6528*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6529*cfb92d14SAndroid Build Coastguard Worker 
6530*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6531*cfb92d14SAndroid Build Coastguard Worker     Log("Restart the resolver with more than half of TTL remaining.");
6532*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is reported in the result callback and no queries are sent.");
6533*cfb92d14SAndroid Build Coastguard Worker 
6534*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(resolver));
6535*cfb92d14SAndroid Build Coastguard Worker 
6536*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6537*cfb92d14SAndroid Build Coastguard Worker 
6538*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6539*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6540*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6541*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 1));
6542*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6543*cfb92d14SAndroid Build Coastguard Worker 
6544*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6545*cfb92d14SAndroid Build Coastguard Worker 
6546*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(20 * 1000);
6547*cfb92d14SAndroid Build Coastguard Worker 
6548*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6549*cfb92d14SAndroid Build Coastguard Worker 
6550*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6551*cfb92d14SAndroid Build Coastguard Worker     Log("Stop and start the resolver again after less than half TTL remaining.");
6552*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure cached entry is still reported in the result callback but queries should be sent");
6553*cfb92d14SAndroid Build Coastguard Worker 
6554*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6555*cfb92d14SAndroid Build Coastguard Worker 
6556*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StopIp6AddressResolver(resolver));
6557*cfb92d14SAndroid Build Coastguard Worker 
6558*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(25 * 1000);
6559*cfb92d14SAndroid Build Coastguard Worker 
6560*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(resolver));
6561*cfb92d14SAndroid Build Coastguard Worker 
6562*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6563*cfb92d14SAndroid Build Coastguard Worker 
6564*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6565*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6566*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("myhost"));
6567*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(addrs, 1));
6568*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6569*cfb92d14SAndroid Build Coastguard Worker 
6570*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6571*cfb92d14SAndroid Build Coastguard Worker 
6572*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15 * 1000);
6573*cfb92d14SAndroid Build Coastguard Worker 
6574*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
6575*cfb92d14SAndroid Build Coastguard Worker 
6576*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t queryCount = 0; queryCount < kNumInitalQueries; queryCount++)
6577*cfb92d14SAndroid Build Coastguard Worker     {
6578*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(dnsMsg != nullptr);
6579*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateHeader(kMulticastQuery, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 0);
6580*cfb92d14SAndroid Build Coastguard Worker         dnsMsg->ValidateAsQueryFor(resolver);
6581*cfb92d14SAndroid Build Coastguard Worker         dnsMsg = dnsMsg->GetNext();
6582*cfb92d14SAndroid Build Coastguard Worker     }
6583*cfb92d14SAndroid Build Coastguard Worker 
6584*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg == nullptr);
6585*cfb92d14SAndroid Build Coastguard Worker 
6586*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6587*cfb92d14SAndroid Build Coastguard Worker 
6588*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
6589*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
6590*cfb92d14SAndroid Build Coastguard Worker 
6591*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
6592*cfb92d14SAndroid Build Coastguard Worker 
6593*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
6594*cfb92d14SAndroid Build Coastguard Worker }
6595*cfb92d14SAndroid Build Coastguard Worker 
TestPassiveCache(void)6596*cfb92d14SAndroid Build Coastguard Worker void TestPassiveCache(void)
6597*cfb92d14SAndroid Build Coastguard Worker {
6598*cfb92d14SAndroid Build Coastguard Worker     static const char *const kSubTypes[] = {"_sub1", "_xyzw"};
6599*cfb92d14SAndroid Build Coastguard Worker 
6600*cfb92d14SAndroid Build Coastguard Worker     Core                 *mdns = InitTest();
6601*cfb92d14SAndroid Build Coastguard Worker     Core::Browser         browser;
6602*cfb92d14SAndroid Build Coastguard Worker     Core::SrvResolver     srvResolver;
6603*cfb92d14SAndroid Build Coastguard Worker     Core::TxtResolver     txtResolver;
6604*cfb92d14SAndroid Build Coastguard Worker     Core::AddressResolver addrResolver;
6605*cfb92d14SAndroid Build Coastguard Worker     Core::Host            host1;
6606*cfb92d14SAndroid Build Coastguard Worker     Core::Host            host2;
6607*cfb92d14SAndroid Build Coastguard Worker     Core::Service         service1;
6608*cfb92d14SAndroid Build Coastguard Worker     Core::Service         service2;
6609*cfb92d14SAndroid Build Coastguard Worker     Core::Service         service3;
6610*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address          host1Addresses[3];
6611*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address          host2Addresses[2];
6612*cfb92d14SAndroid Build Coastguard Worker     AddrAndTtl            host1AddrTtls[3];
6613*cfb92d14SAndroid Build Coastguard Worker     AddrAndTtl            host2AddrTtls[2];
6614*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage     *dnsMsg;
6615*cfb92d14SAndroid Build Coastguard Worker     BrowseCallback       *browseCallback;
6616*cfb92d14SAndroid Build Coastguard Worker     SrvCallback          *srvCallback;
6617*cfb92d14SAndroid Build Coastguard Worker     TxtCallback          *txtCallback;
6618*cfb92d14SAndroid Build Coastguard Worker     AddrCallback         *addrCallback;
6619*cfb92d14SAndroid Build Coastguard Worker     uint16_t              heapAllocations;
6620*cfb92d14SAndroid Build Coastguard Worker 
6621*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
6622*cfb92d14SAndroid Build Coastguard Worker     Log("TestPassiveCache");
6623*cfb92d14SAndroid Build Coastguard Worker 
6624*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6625*cfb92d14SAndroid Build Coastguard Worker 
6626*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
6627*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
6628*cfb92d14SAndroid Build Coastguard Worker 
6629*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[0].FromString("fd00::1:aaaa"));
6630*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[1].FromString("fd00::1:bbbb"));
6631*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host1Addresses[2].FromString("fd00::1:cccc"));
6632*cfb92d14SAndroid Build Coastguard Worker     host1.mHostName        = "host1";
6633*cfb92d14SAndroid Build Coastguard Worker     host1.mAddresses       = host1Addresses;
6634*cfb92d14SAndroid Build Coastguard Worker     host1.mAddressesLength = 3;
6635*cfb92d14SAndroid Build Coastguard Worker     host1.mTtl             = 1500;
6636*cfb92d14SAndroid Build Coastguard Worker 
6637*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[0].mAddress = host1Addresses[0];
6638*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[1].mAddress = host1Addresses[1];
6639*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[2].mAddress = host1Addresses[2];
6640*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[0].mTtl     = host1.mTtl;
6641*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[1].mTtl     = host1.mTtl;
6642*cfb92d14SAndroid Build Coastguard Worker     host1AddrTtls[2].mTtl     = host1.mTtl;
6643*cfb92d14SAndroid Build Coastguard Worker 
6644*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host2Addresses[0].FromString("fd00::2:eeee"));
6645*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(host2Addresses[1].FromString("fd00::2:ffff"));
6646*cfb92d14SAndroid Build Coastguard Worker     host2.mHostName        = "host2";
6647*cfb92d14SAndroid Build Coastguard Worker     host2.mAddresses       = host2Addresses;
6648*cfb92d14SAndroid Build Coastguard Worker     host2.mAddressesLength = 2;
6649*cfb92d14SAndroid Build Coastguard Worker     host2.mTtl             = 1500;
6650*cfb92d14SAndroid Build Coastguard Worker 
6651*cfb92d14SAndroid Build Coastguard Worker     host2AddrTtls[0].mAddress = host2Addresses[0];
6652*cfb92d14SAndroid Build Coastguard Worker     host2AddrTtls[1].mAddress = host2Addresses[1];
6653*cfb92d14SAndroid Build Coastguard Worker     host2AddrTtls[0].mTtl     = host2.mTtl;
6654*cfb92d14SAndroid Build Coastguard Worker     host2AddrTtls[1].mTtl     = host2.mTtl;
6655*cfb92d14SAndroid Build Coastguard Worker 
6656*cfb92d14SAndroid Build Coastguard Worker     service1.mHostName            = host1.mHostName;
6657*cfb92d14SAndroid Build Coastguard Worker     service1.mServiceInstance     = "srv1";
6658*cfb92d14SAndroid Build Coastguard Worker     service1.mServiceType         = "_srv._udp";
6659*cfb92d14SAndroid Build Coastguard Worker     service1.mSubTypeLabels       = kSubTypes;
6660*cfb92d14SAndroid Build Coastguard Worker     service1.mSubTypeLabelsLength = 2;
6661*cfb92d14SAndroid Build Coastguard Worker     service1.mTxtData             = kTxtData1;
6662*cfb92d14SAndroid Build Coastguard Worker     service1.mTxtDataLength       = sizeof(kTxtData1);
6663*cfb92d14SAndroid Build Coastguard Worker     service1.mPort                = 1111;
6664*cfb92d14SAndroid Build Coastguard Worker     service1.mPriority            = 0;
6665*cfb92d14SAndroid Build Coastguard Worker     service1.mWeight              = 0;
6666*cfb92d14SAndroid Build Coastguard Worker     service1.mTtl                 = 1500;
6667*cfb92d14SAndroid Build Coastguard Worker 
6668*cfb92d14SAndroid Build Coastguard Worker     service2.mHostName            = host1.mHostName;
6669*cfb92d14SAndroid Build Coastguard Worker     service2.mServiceInstance     = "srv2";
6670*cfb92d14SAndroid Build Coastguard Worker     service2.mServiceType         = "_tst._tcp";
6671*cfb92d14SAndroid Build Coastguard Worker     service2.mSubTypeLabels       = nullptr;
6672*cfb92d14SAndroid Build Coastguard Worker     service2.mSubTypeLabelsLength = 0;
6673*cfb92d14SAndroid Build Coastguard Worker     service2.mTxtData             = nullptr;
6674*cfb92d14SAndroid Build Coastguard Worker     service2.mTxtDataLength       = 0;
6675*cfb92d14SAndroid Build Coastguard Worker     service2.mPort                = 2222;
6676*cfb92d14SAndroid Build Coastguard Worker     service2.mPriority            = 2;
6677*cfb92d14SAndroid Build Coastguard Worker     service2.mWeight              = 2;
6678*cfb92d14SAndroid Build Coastguard Worker     service2.mTtl                 = 1500;
6679*cfb92d14SAndroid Build Coastguard Worker 
6680*cfb92d14SAndroid Build Coastguard Worker     service3.mHostName            = host2.mHostName;
6681*cfb92d14SAndroid Build Coastguard Worker     service3.mServiceInstance     = "srv3";
6682*cfb92d14SAndroid Build Coastguard Worker     service3.mServiceType         = "_srv._udp";
6683*cfb92d14SAndroid Build Coastguard Worker     service3.mSubTypeLabels       = kSubTypes;
6684*cfb92d14SAndroid Build Coastguard Worker     service3.mSubTypeLabelsLength = 1;
6685*cfb92d14SAndroid Build Coastguard Worker     service3.mTxtData             = kTxtData2;
6686*cfb92d14SAndroid Build Coastguard Worker     service3.mTxtDataLength       = sizeof(kTxtData2);
6687*cfb92d14SAndroid Build Coastguard Worker     service3.mPort                = 3333;
6688*cfb92d14SAndroid Build Coastguard Worker     service3.mPriority            = 3;
6689*cfb92d14SAndroid Build Coastguard Worker     service3.mWeight              = 3;
6690*cfb92d14SAndroid Build Coastguard Worker     service3.mTtl                 = 1500;
6691*cfb92d14SAndroid Build Coastguard Worker 
6692*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6693*cfb92d14SAndroid Build Coastguard Worker     Log("Register 2 hosts and 3 services");
6694*cfb92d14SAndroid Build Coastguard Worker 
6695*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host1, 0, HandleSuccessCallback));
6696*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host2, 1, HandleSuccessCallback));
6697*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service1, 2, HandleSuccessCallback));
6698*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service2, 3, HandleSuccessCallback));
6699*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service3, 4, HandleSuccessCallback));
6700*cfb92d14SAndroid Build Coastguard Worker 
6701*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10 * 1000);
6702*cfb92d14SAndroid Build Coastguard Worker 
6703*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6704*cfb92d14SAndroid Build Coastguard Worker     Log("Start a browser for `_srv._udp`, validate callback result");
6705*cfb92d14SAndroid Build Coastguard Worker 
6706*cfb92d14SAndroid Build Coastguard Worker     browser.mServiceType  = "_srv._udp";
6707*cfb92d14SAndroid Build Coastguard Worker     browser.mSubTypeLabel = nullptr;
6708*cfb92d14SAndroid Build Coastguard Worker     browser.mInfraIfIndex = kInfraIfIndex;
6709*cfb92d14SAndroid Build Coastguard Worker     browser.mCallback     = HandleBrowseResult;
6710*cfb92d14SAndroid Build Coastguard Worker 
6711*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
6712*cfb92d14SAndroid Build Coastguard Worker 
6713*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartBrowser(browser));
6714*cfb92d14SAndroid Build Coastguard Worker 
6715*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(350);
6716*cfb92d14SAndroid Build Coastguard Worker 
6717*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
6718*cfb92d14SAndroid Build Coastguard Worker 
6719*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t iter = 0; iter < 2; iter++)
6720*cfb92d14SAndroid Build Coastguard Worker     {
6721*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback != nullptr);
6722*cfb92d14SAndroid Build Coastguard Worker 
6723*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
6724*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!browseCallback->mIsSubType);
6725*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mServiceInstance.Matches("srv1") ||
6726*cfb92d14SAndroid Build Coastguard Worker                      browseCallback->mServiceInstance.Matches("srv3"));
6727*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(browseCallback->mTtl == 1500);
6728*cfb92d14SAndroid Build Coastguard Worker 
6729*cfb92d14SAndroid Build Coastguard Worker         browseCallback = browseCallback->GetNext();
6730*cfb92d14SAndroid Build Coastguard Worker     }
6731*cfb92d14SAndroid Build Coastguard Worker 
6732*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback == nullptr);
6733*cfb92d14SAndroid Build Coastguard Worker 
6734*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6735*cfb92d14SAndroid Build Coastguard Worker     Log("Start SRV and TXT resolvers for the srv1 and for its host name.");
6736*cfb92d14SAndroid Build Coastguard Worker     Log("Ensure all results are immediately provided from cache.");
6737*cfb92d14SAndroid Build Coastguard Worker 
6738*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceInstance = "srv1";
6739*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceType     = "_srv._udp";
6740*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mInfraIfIndex    = kInfraIfIndex;
6741*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mCallback        = HandleSrvResult;
6742*cfb92d14SAndroid Build Coastguard Worker 
6743*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mServiceInstance = "srv1";
6744*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mServiceType     = "_srv._udp";
6745*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mInfraIfIndex    = kInfraIfIndex;
6746*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mCallback        = HandleTxtResult;
6747*cfb92d14SAndroid Build Coastguard Worker 
6748*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mHostName     = "host1";
6749*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mInfraIfIndex = kInfraIfIndex;
6750*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mCallback     = HandleAddrResult;
6751*cfb92d14SAndroid Build Coastguard Worker 
6752*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
6753*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6754*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6755*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6756*cfb92d14SAndroid Build Coastguard Worker 
6757*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(srvResolver));
6758*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(txtResolver));
6759*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(addrResolver));
6760*cfb92d14SAndroid Build Coastguard Worker 
6761*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6762*cfb92d14SAndroid Build Coastguard Worker 
6763*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
6764*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
6765*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("srv1"));
6766*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
6767*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("host1"));
6768*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 1111);
6769*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 0);
6770*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 0);
6771*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 1500);
6772*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
6773*cfb92d14SAndroid Build Coastguard Worker 
6774*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
6775*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
6776*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("srv1"));
6777*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_srv._udp"));
6778*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kTxtData1));
6779*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 1500);
6780*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6781*cfb92d14SAndroid Build Coastguard Worker 
6782*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6783*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6784*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("host1"));
6785*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(host1AddrTtls, 3));
6786*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6787*cfb92d14SAndroid Build Coastguard Worker 
6788*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(400);
6789*cfb92d14SAndroid Build Coastguard Worker 
6790*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sDnsMessages.IsEmpty());
6791*cfb92d14SAndroid Build Coastguard Worker 
6792*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6793*cfb92d14SAndroid Build Coastguard Worker     Log("Start a browser for sub-type service, validate callback result");
6794*cfb92d14SAndroid Build Coastguard Worker 
6795*cfb92d14SAndroid Build Coastguard Worker     browser.mServiceType  = "_srv._udp";
6796*cfb92d14SAndroid Build Coastguard Worker     browser.mSubTypeLabel = "_xyzw";
6797*cfb92d14SAndroid Build Coastguard Worker     browser.mInfraIfIndex = kInfraIfIndex;
6798*cfb92d14SAndroid Build Coastguard Worker     browser.mCallback     = HandleBrowseResult;
6799*cfb92d14SAndroid Build Coastguard Worker 
6800*cfb92d14SAndroid Build Coastguard Worker     sBrowseCallbacks.Clear();
6801*cfb92d14SAndroid Build Coastguard Worker 
6802*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartBrowser(browser));
6803*cfb92d14SAndroid Build Coastguard Worker 
6804*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(350);
6805*cfb92d14SAndroid Build Coastguard Worker 
6806*cfb92d14SAndroid Build Coastguard Worker     browseCallback = sBrowseCallbacks.GetHead();
6807*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback != nullptr);
6808*cfb92d14SAndroid Build Coastguard Worker 
6809*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceType.Matches("_srv._udp"));
6810*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mIsSubType);
6811*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mSubTypeLabel.Matches("_xyzw"));
6812*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mServiceInstance.Matches("srv1"));
6813*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->mTtl == 1500);
6814*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(browseCallback->GetNext() == nullptr);
6815*cfb92d14SAndroid Build Coastguard Worker 
6816*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(5 * 1000);
6817*cfb92d14SAndroid Build Coastguard Worker 
6818*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6819*cfb92d14SAndroid Build Coastguard Worker     Log("Start SRV and TXT resolvers for `srv2._tst._tcp` service and validate callback result");
6820*cfb92d14SAndroid Build Coastguard Worker 
6821*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceInstance = "srv2";
6822*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceType     = "_tst._tcp";
6823*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mInfraIfIndex    = kInfraIfIndex;
6824*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mCallback        = HandleSrvResult;
6825*cfb92d14SAndroid Build Coastguard Worker 
6826*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mServiceInstance = "srv2";
6827*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mServiceType     = "_tst._tcp";
6828*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mInfraIfIndex    = kInfraIfIndex;
6829*cfb92d14SAndroid Build Coastguard Worker     txtResolver.mCallback        = HandleTxtResult;
6830*cfb92d14SAndroid Build Coastguard Worker 
6831*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
6832*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6833*cfb92d14SAndroid Build Coastguard Worker 
6834*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(srvResolver));
6835*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartTxtResolver(txtResolver));
6836*cfb92d14SAndroid Build Coastguard Worker 
6837*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(350);
6838*cfb92d14SAndroid Build Coastguard Worker 
6839*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
6840*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
6841*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("srv2"));
6842*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_tst._tcp"));
6843*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("host1"));
6844*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 2222);
6845*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 2);
6846*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 2);
6847*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 1500);
6848*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
6849*cfb92d14SAndroid Build Coastguard Worker 
6850*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
6851*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
6852*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("srv2"));
6853*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_tst._tcp"));
6854*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->Matches(kEmptyTxtData));
6855*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 1500);
6856*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6857*cfb92d14SAndroid Build Coastguard Worker 
6858*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6859*cfb92d14SAndroid Build Coastguard Worker     Log("Unregister `srv2._tst._tcp` and validate callback results");
6860*cfb92d14SAndroid Build Coastguard Worker 
6861*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
6862*cfb92d14SAndroid Build Coastguard Worker     sTxtCallbacks.Clear();
6863*cfb92d14SAndroid Build Coastguard Worker 
6864*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterService(service2));
6865*cfb92d14SAndroid Build Coastguard Worker 
6866*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(350);
6867*cfb92d14SAndroid Build Coastguard Worker 
6868*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
6869*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
6870*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("srv2"));
6871*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_tst._tcp"));
6872*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 0);
6873*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
6874*cfb92d14SAndroid Build Coastguard Worker 
6875*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sTxtCallbacks.IsEmpty());
6876*cfb92d14SAndroid Build Coastguard Worker     txtCallback = sTxtCallbacks.GetHead();
6877*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceInstance.Matches("srv2"));
6878*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mServiceType.Matches("_tst._tcp"));
6879*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->mTtl == 0);
6880*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(txtCallback->GetNext() == nullptr);
6881*cfb92d14SAndroid Build Coastguard Worker 
6882*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6883*cfb92d14SAndroid Build Coastguard Worker     Log("Start an SRV resolver for `srv3._srv._udp` service and validate callback result");
6884*cfb92d14SAndroid Build Coastguard Worker 
6885*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceInstance = "srv3";
6886*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mServiceType     = "_srv._udp";
6887*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mInfraIfIndex    = kInfraIfIndex;
6888*cfb92d14SAndroid Build Coastguard Worker     srvResolver.mCallback        = HandleSrvResult;
6889*cfb92d14SAndroid Build Coastguard Worker 
6890*cfb92d14SAndroid Build Coastguard Worker     sSrvCallbacks.Clear();
6891*cfb92d14SAndroid Build Coastguard Worker 
6892*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartSrvResolver(srvResolver));
6893*cfb92d14SAndroid Build Coastguard Worker 
6894*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(350);
6895*cfb92d14SAndroid Build Coastguard Worker 
6896*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sSrvCallbacks.IsEmpty());
6897*cfb92d14SAndroid Build Coastguard Worker     srvCallback = sSrvCallbacks.GetHead();
6898*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceInstance.Matches("srv3"));
6899*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mServiceType.Matches("_srv._udp"));
6900*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mHostName.Matches("host2"));
6901*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPort == 3333);
6902*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mPriority == 3);
6903*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mWeight == 3);
6904*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->mTtl == 1500);
6905*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(srvCallback->GetNext() == nullptr);
6906*cfb92d14SAndroid Build Coastguard Worker 
6907*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6908*cfb92d14SAndroid Build Coastguard Worker     Log("Start an address resolver for host2 and validate result is immediately reported from cache");
6909*cfb92d14SAndroid Build Coastguard Worker 
6910*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mHostName     = "host2";
6911*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mInfraIfIndex = kInfraIfIndex;
6912*cfb92d14SAndroid Build Coastguard Worker     addrResolver.mCallback     = HandleAddrResult;
6913*cfb92d14SAndroid Build Coastguard Worker 
6914*cfb92d14SAndroid Build Coastguard Worker     sAddrCallbacks.Clear();
6915*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->StartIp6AddressResolver(addrResolver));
6916*cfb92d14SAndroid Build Coastguard Worker 
6917*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6918*cfb92d14SAndroid Build Coastguard Worker 
6919*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!sAddrCallbacks.IsEmpty());
6920*cfb92d14SAndroid Build Coastguard Worker     addrCallback = sAddrCallbacks.GetHead();
6921*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->mHostName.Matches("host2"));
6922*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->Matches(host2AddrTtls, 2));
6923*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(addrCallback->GetNext() == nullptr);
6924*cfb92d14SAndroid Build Coastguard Worker 
6925*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6926*cfb92d14SAndroid Build Coastguard Worker 
6927*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
6928*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
6929*cfb92d14SAndroid Build Coastguard Worker 
6930*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
6931*cfb92d14SAndroid Build Coastguard Worker 
6932*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
6933*cfb92d14SAndroid Build Coastguard Worker }
6934*cfb92d14SAndroid Build Coastguard Worker 
TestLegacyUnicastResponse(void)6935*cfb92d14SAndroid Build Coastguard Worker void TestLegacyUnicastResponse(void)
6936*cfb92d14SAndroid Build Coastguard Worker {
6937*cfb92d14SAndroid Build Coastguard Worker     Core             *mdns = InitTest();
6938*cfb92d14SAndroid Build Coastguard Worker     Core::Host        host;
6939*cfb92d14SAndroid Build Coastguard Worker     Core::Service     service;
6940*cfb92d14SAndroid Build Coastguard Worker     const DnsMessage *dnsMsg;
6941*cfb92d14SAndroid Build Coastguard Worker     uint16_t          heapAllocations;
6942*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceName;
6943*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     fullServiceType;
6944*cfb92d14SAndroid Build Coastguard Worker     DnsNameString     hostFullName;
6945*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address      hostAddresses[2];
6946*cfb92d14SAndroid Build Coastguard Worker 
6947*cfb92d14SAndroid Build Coastguard Worker     Log("-------------------------------------------------------------------------------------------");
6948*cfb92d14SAndroid Build Coastguard Worker     Log("TestLegacyUnicastResponse");
6949*cfb92d14SAndroid Build Coastguard Worker 
6950*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1);
6951*cfb92d14SAndroid Build Coastguard Worker 
6952*cfb92d14SAndroid Build Coastguard Worker     heapAllocations = sHeapAllocatedPtrs.GetLength();
6953*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
6954*cfb92d14SAndroid Build Coastguard Worker 
6955*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[0].FromString("fd00::1:aaaa"));
6956*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(hostAddresses[1].FromString("fd00::1:bbbb"));
6957*cfb92d14SAndroid Build Coastguard Worker     host.mHostName        = "host";
6958*cfb92d14SAndroid Build Coastguard Worker     host.mAddresses       = hostAddresses;
6959*cfb92d14SAndroid Build Coastguard Worker     host.mAddressesLength = 2;
6960*cfb92d14SAndroid Build Coastguard Worker     host.mTtl             = 1500;
6961*cfb92d14SAndroid Build Coastguard Worker     hostFullName.Append("%s.local.", host.mHostName);
6962*cfb92d14SAndroid Build Coastguard Worker 
6963*cfb92d14SAndroid Build Coastguard Worker     service.mHostName            = host.mHostName;
6964*cfb92d14SAndroid Build Coastguard Worker     service.mServiceInstance     = "myservice";
6965*cfb92d14SAndroid Build Coastguard Worker     service.mServiceType         = "_srv._udp";
6966*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabels       = nullptr;
6967*cfb92d14SAndroid Build Coastguard Worker     service.mSubTypeLabelsLength = 0;
6968*cfb92d14SAndroid Build Coastguard Worker     service.mTxtData             = kTxtData1;
6969*cfb92d14SAndroid Build Coastguard Worker     service.mTxtDataLength       = sizeof(kTxtData1);
6970*cfb92d14SAndroid Build Coastguard Worker     service.mPort                = 1234;
6971*cfb92d14SAndroid Build Coastguard Worker     service.mPriority            = 1;
6972*cfb92d14SAndroid Build Coastguard Worker     service.mWeight              = 2;
6973*cfb92d14SAndroid Build Coastguard Worker     service.mTtl                 = 1000;
6974*cfb92d14SAndroid Build Coastguard Worker 
6975*cfb92d14SAndroid Build Coastguard Worker     fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
6976*cfb92d14SAndroid Build Coastguard Worker     fullServiceType.Append("%s.local.", service.mServiceType);
6977*cfb92d14SAndroid Build Coastguard Worker 
6978*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6979*cfb92d14SAndroid Build Coastguard Worker 
6980*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6981*cfb92d14SAndroid Build Coastguard Worker 
6982*cfb92d14SAndroid Build Coastguard Worker     for (RegCallback &regCallbck : sRegCallbacks)
6983*cfb92d14SAndroid Build Coastguard Worker     {
6984*cfb92d14SAndroid Build Coastguard Worker         regCallbck.Reset();
6985*cfb92d14SAndroid Build Coastguard Worker     }
6986*cfb92d14SAndroid Build Coastguard Worker 
6987*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
6988*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
6989*cfb92d14SAndroid Build Coastguard Worker 
6990*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(10 * 1000);
6991*cfb92d14SAndroid Build Coastguard Worker 
6992*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
6993*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query with two questions (SRV for service1 and AAAA for host). Validate that no response is sent");
6994*cfb92d14SAndroid Build Coastguard Worker 
6995*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
6996*cfb92d14SAndroid Build Coastguard Worker 
6997*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
6998*cfb92d14SAndroid Build Coastguard Worker     SendQueryForTwo(fullServiceName.AsCString(), ResourceRecord::kTypeSrv, hostFullName.AsCString(),
6999*cfb92d14SAndroid Build Coastguard Worker                     ResourceRecord::kTypeAaaa, /* aIsLegacyUnicast */ true);
7000*cfb92d14SAndroid Build Coastguard Worker 
7001*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(200);
7002*cfb92d14SAndroid Build Coastguard Worker 
7003*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7004*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg == nullptr);
7005*cfb92d14SAndroid Build Coastguard Worker 
7006*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7007*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for SRV record and validate the response");
7008*cfb92d14SAndroid Build Coastguard Worker 
7009*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
7010*cfb92d14SAndroid Build Coastguard Worker 
7011*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7012*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeSrv, ResourceRecord::kClassInternet,
7013*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ false,
7014*cfb92d14SAndroid Build Coastguard Worker               /* aLegacyUnicastQuery */ true);
7015*cfb92d14SAndroid Build Coastguard Worker 
7016*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
7017*cfb92d14SAndroid Build Coastguard Worker 
7018*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7019*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
7020*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 3);
7021*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
7022*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAdditionalSection);
7023*cfb92d14SAndroid Build Coastguard Worker 
7024*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7025*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for TXT record and validate the response");
7026*cfb92d14SAndroid Build Coastguard Worker 
7027*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
7028*cfb92d14SAndroid Build Coastguard Worker 
7029*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7030*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeTxt, ResourceRecord::kClassInternet,
7031*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ false,
7032*cfb92d14SAndroid Build Coastguard Worker               /* aLegacyUnicastQuery */ true);
7033*cfb92d14SAndroid Build Coastguard Worker 
7034*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
7035*cfb92d14SAndroid Build Coastguard Worker 
7036*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7037*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
7038*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
7039*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckTxt);
7040*cfb92d14SAndroid Build Coastguard Worker 
7041*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7042*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for ANY record and validate the response");
7043*cfb92d14SAndroid Build Coastguard Worker 
7044*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
7045*cfb92d14SAndroid Build Coastguard Worker 
7046*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7047*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeAny, ResourceRecord::kClassInternet,
7048*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ false,
7049*cfb92d14SAndroid Build Coastguard Worker               /* aLegacyUnicastQuery */ true);
7050*cfb92d14SAndroid Build Coastguard Worker 
7051*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
7052*cfb92d14SAndroid Build Coastguard Worker 
7053*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7054*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
7055*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 3);
7056*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt);
7057*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAdditionalSection);
7058*cfb92d14SAndroid Build Coastguard Worker 
7059*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7060*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for PTR record for service type and validate the response");
7061*cfb92d14SAndroid Build Coastguard Worker 
7062*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
7063*cfb92d14SAndroid Build Coastguard Worker 
7064*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7065*cfb92d14SAndroid Build Coastguard Worker     SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
7066*cfb92d14SAndroid Build Coastguard Worker               /* aTruncated */ false,
7067*cfb92d14SAndroid Build Coastguard Worker               /* aLegacyUnicastQuery */ true);
7068*cfb92d14SAndroid Build Coastguard Worker 
7069*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
7070*cfb92d14SAndroid Build Coastguard Worker 
7071*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7072*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
7073*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
7074*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
7075*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
7076*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->Validate(host, kInAdditionalSection);
7077*cfb92d14SAndroid Build Coastguard Worker 
7078*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7079*cfb92d14SAndroid Build Coastguard Worker     Log("Send a query for non-existing record and validate the response with NSEC");
7080*cfb92d14SAndroid Build Coastguard Worker 
7081*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(2000);
7082*cfb92d14SAndroid Build Coastguard Worker 
7083*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7084*cfb92d14SAndroid Build Coastguard Worker     SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeA, ResourceRecord::kClassInternet, /* aTruncated */ false,
7085*cfb92d14SAndroid Build Coastguard Worker               /* aLegacyUnicastQuery */ true);
7086*cfb92d14SAndroid Build Coastguard Worker 
7087*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(1000);
7088*cfb92d14SAndroid Build Coastguard Worker 
7089*cfb92d14SAndroid Build Coastguard Worker     dnsMsg = sDnsMessages.GetHead();
7090*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg != nullptr);
7091*cfb92d14SAndroid Build Coastguard Worker     dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 1);
7092*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(dnsMsg->mAdditionalRecords.ContainsNsec(hostFullName, ResourceRecord::kTypeAaaa));
7093*cfb92d14SAndroid Build Coastguard Worker 
7094*cfb92d14SAndroid Build Coastguard Worker     Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
7095*cfb92d14SAndroid Build Coastguard Worker 
7096*cfb92d14SAndroid Build Coastguard Worker     sDnsMessages.Clear();
7097*cfb92d14SAndroid Build Coastguard Worker 
7098*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->UnregisterHost(host));
7099*cfb92d14SAndroid Build Coastguard Worker 
7100*cfb92d14SAndroid Build Coastguard Worker     AdvanceTime(15000);
7101*cfb92d14SAndroid Build Coastguard Worker 
7102*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
7103*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
7104*cfb92d14SAndroid Build Coastguard Worker 
7105*cfb92d14SAndroid Build Coastguard Worker     Log("End of test");
7106*cfb92d14SAndroid Build Coastguard Worker 
7107*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
7108*cfb92d14SAndroid Build Coastguard Worker }
7109*cfb92d14SAndroid Build Coastguard Worker 
7110*cfb92d14SAndroid Build Coastguard Worker } // namespace Multicast
7111*cfb92d14SAndroid Build Coastguard Worker } // namespace Dns
7112*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
7113*cfb92d14SAndroid Build Coastguard Worker 
7114*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
7115*cfb92d14SAndroid Build Coastguard Worker 
main(void)7116*cfb92d14SAndroid Build Coastguard Worker int main(void)
7117*cfb92d14SAndroid Build Coastguard Worker {
7118*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
7119*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestHostReg();
7120*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestKeyReg();
7121*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestServiceReg();
7122*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestUnregisterBeforeProbeFinished();
7123*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestServiceSubTypeReg();
7124*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestHostOrServiceAndKeyReg();
7125*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestQuery();
7126*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestMultiPacket();
7127*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestQuestionUnicastDisallowed();
7128*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestTxMessageSizeLimit();
7129*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestHostConflict();
7130*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestServiceConflict();
7131*cfb92d14SAndroid Build Coastguard Worker 
7132*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestBrowser();
7133*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestSrvResolver();
7134*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestTxtResolver();
7135*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestIp6AddrResolver();
7136*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestPassiveCache();
7137*cfb92d14SAndroid Build Coastguard Worker     ot::Dns::Multicast::TestLegacyUnicastResponse();
7138*cfb92d14SAndroid Build Coastguard Worker 
7139*cfb92d14SAndroid Build Coastguard Worker     printf("All tests passed\n");
7140*cfb92d14SAndroid Build Coastguard Worker #else
7141*cfb92d14SAndroid Build Coastguard Worker     printf("mDNS feature is not enabled\n");
7142*cfb92d14SAndroid Build Coastguard Worker #endif
7143*cfb92d14SAndroid Build Coastguard Worker 
7144*cfb92d14SAndroid Build Coastguard Worker     return 0;
7145*cfb92d14SAndroid Build Coastguard Worker }
7146