xref: /aosp_15_r20/external/ot-br-posix/src/mdns/mdns.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2021, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker  * @file
31*4a64e381SAndroid Build Coastguard Worker  *   This file includes implementation of mDNS publisher.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "MDNS"
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #include "mdns/mdns.hpp"
37*4a64e381SAndroid Build Coastguard Worker 
38*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_MDNS
39*4a64e381SAndroid Build Coastguard Worker 
40*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
41*4a64e381SAndroid Build Coastguard Worker 
42*4a64e381SAndroid Build Coastguard Worker #include <algorithm>
43*4a64e381SAndroid Build Coastguard Worker #include <functional>
44*4a64e381SAndroid Build Coastguard Worker 
45*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
46*4a64e381SAndroid Build Coastguard Worker #include "utils/dns_utils.hpp"
47*4a64e381SAndroid Build Coastguard Worker 
48*4a64e381SAndroid Build Coastguard Worker namespace otbr {
49*4a64e381SAndroid Build Coastguard Worker 
50*4a64e381SAndroid Build Coastguard Worker namespace Mdns {
51*4a64e381SAndroid Build Coastguard Worker 
PublishService(const std::string & aHostName,const std::string & aName,const std::string & aType,const SubTypeList & aSubTypeList,uint16_t aPort,const TxtData & aTxtData,ResultCallback && aCallback)52*4a64e381SAndroid Build Coastguard Worker void Publisher::PublishService(const std::string &aHostName,
53*4a64e381SAndroid Build Coastguard Worker                                const std::string &aName,
54*4a64e381SAndroid Build Coastguard Worker                                const std::string &aType,
55*4a64e381SAndroid Build Coastguard Worker                                const SubTypeList &aSubTypeList,
56*4a64e381SAndroid Build Coastguard Worker                                uint16_t           aPort,
57*4a64e381SAndroid Build Coastguard Worker                                const TxtData     &aTxtData,
58*4a64e381SAndroid Build Coastguard Worker                                ResultCallback   &&aCallback)
59*4a64e381SAndroid Build Coastguard Worker {
60*4a64e381SAndroid Build Coastguard Worker     otbrError error;
61*4a64e381SAndroid Build Coastguard Worker 
62*4a64e381SAndroid Build Coastguard Worker     mServiceRegistrationBeginTime[std::make_pair(aName, aType)] = Clock::now();
63*4a64e381SAndroid Build Coastguard Worker 
64*4a64e381SAndroid Build Coastguard Worker     error = PublishServiceImpl(aHostName, aName, aType, aSubTypeList, aPort, aTxtData, std::move(aCallback));
65*4a64e381SAndroid Build Coastguard Worker     if (error != OTBR_ERROR_NONE)
66*4a64e381SAndroid Build Coastguard Worker     {
67*4a64e381SAndroid Build Coastguard Worker         UpdateMdnsResponseCounters(mTelemetryInfo.mServiceRegistrations, error);
68*4a64e381SAndroid Build Coastguard Worker     }
69*4a64e381SAndroid Build Coastguard Worker }
70*4a64e381SAndroid Build Coastguard Worker 
PublishHost(const std::string & aName,const AddressList & aAddresses,ResultCallback && aCallback)71*4a64e381SAndroid Build Coastguard Worker void Publisher::PublishHost(const std::string &aName, const AddressList &aAddresses, ResultCallback &&aCallback)
72*4a64e381SAndroid Build Coastguard Worker {
73*4a64e381SAndroid Build Coastguard Worker     otbrError error;
74*4a64e381SAndroid Build Coastguard Worker 
75*4a64e381SAndroid Build Coastguard Worker     mHostRegistrationBeginTime[aName] = Clock::now();
76*4a64e381SAndroid Build Coastguard Worker 
77*4a64e381SAndroid Build Coastguard Worker     error = PublishHostImpl(aName, aAddresses, std::move(aCallback));
78*4a64e381SAndroid Build Coastguard Worker     if (error != OTBR_ERROR_NONE)
79*4a64e381SAndroid Build Coastguard Worker     {
80*4a64e381SAndroid Build Coastguard Worker         UpdateMdnsResponseCounters(mTelemetryInfo.mHostRegistrations, error);
81*4a64e381SAndroid Build Coastguard Worker     }
82*4a64e381SAndroid Build Coastguard Worker }
83*4a64e381SAndroid Build Coastguard Worker 
PublishKey(const std::string & aName,const KeyData & aKeyData,ResultCallback && aCallback)84*4a64e381SAndroid Build Coastguard Worker void Publisher::PublishKey(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback)
85*4a64e381SAndroid Build Coastguard Worker {
86*4a64e381SAndroid Build Coastguard Worker     otbrError error;
87*4a64e381SAndroid Build Coastguard Worker 
88*4a64e381SAndroid Build Coastguard Worker     mKeyRegistrationBeginTime[aName] = Clock::now();
89*4a64e381SAndroid Build Coastguard Worker 
90*4a64e381SAndroid Build Coastguard Worker     error = PublishKeyImpl(aName, aKeyData, std::move(aCallback));
91*4a64e381SAndroid Build Coastguard Worker     if (error != OTBR_ERROR_NONE)
92*4a64e381SAndroid Build Coastguard Worker     {
93*4a64e381SAndroid Build Coastguard Worker         UpdateMdnsResponseCounters(mTelemetryInfo.mKeyRegistrations, error);
94*4a64e381SAndroid Build Coastguard Worker     }
95*4a64e381SAndroid Build Coastguard Worker }
96*4a64e381SAndroid Build Coastguard Worker 
OnServiceResolveFailed(std::string aType,std::string aInstanceName,int32_t aErrorCode)97*4a64e381SAndroid Build Coastguard Worker void Publisher::OnServiceResolveFailed(std::string aType, std::string aInstanceName, int32_t aErrorCode)
98*4a64e381SAndroid Build Coastguard Worker {
99*4a64e381SAndroid Build Coastguard Worker     UpdateMdnsResponseCounters(mTelemetryInfo.mServiceResolutions, DnsErrorToOtbrError(aErrorCode));
100*4a64e381SAndroid Build Coastguard Worker     UpdateServiceInstanceResolutionEmaLatency(aInstanceName, aType, DnsErrorToOtbrError(aErrorCode));
101*4a64e381SAndroid Build Coastguard Worker     OnServiceResolveFailedImpl(aType, aInstanceName, aErrorCode);
102*4a64e381SAndroid Build Coastguard Worker }
103*4a64e381SAndroid Build Coastguard Worker 
OnHostResolveFailed(std::string aHostName,int32_t aErrorCode)104*4a64e381SAndroid Build Coastguard Worker void Publisher::OnHostResolveFailed(std::string aHostName, int32_t aErrorCode)
105*4a64e381SAndroid Build Coastguard Worker {
106*4a64e381SAndroid Build Coastguard Worker     UpdateMdnsResponseCounters(mTelemetryInfo.mHostResolutions, DnsErrorToOtbrError(aErrorCode));
107*4a64e381SAndroid Build Coastguard Worker     UpdateHostResolutionEmaLatency(aHostName, DnsErrorToOtbrError(aErrorCode));
108*4a64e381SAndroid Build Coastguard Worker     OnHostResolveFailedImpl(aHostName, aErrorCode);
109*4a64e381SAndroid Build Coastguard Worker }
110*4a64e381SAndroid Build Coastguard Worker 
EncodeTxtData(const TxtList & aTxtList,std::vector<uint8_t> & aTxtData)111*4a64e381SAndroid Build Coastguard Worker otbrError Publisher::EncodeTxtData(const TxtList &aTxtList, std::vector<uint8_t> &aTxtData)
112*4a64e381SAndroid Build Coastguard Worker {
113*4a64e381SAndroid Build Coastguard Worker     otbrError error = OTBR_ERROR_NONE;
114*4a64e381SAndroid Build Coastguard Worker 
115*4a64e381SAndroid Build Coastguard Worker     aTxtData.clear();
116*4a64e381SAndroid Build Coastguard Worker 
117*4a64e381SAndroid Build Coastguard Worker     for (const TxtEntry &txtEntry : aTxtList)
118*4a64e381SAndroid Build Coastguard Worker     {
119*4a64e381SAndroid Build Coastguard Worker         size_t entryLength = txtEntry.mKey.length();
120*4a64e381SAndroid Build Coastguard Worker 
121*4a64e381SAndroid Build Coastguard Worker         if (!txtEntry.mIsBooleanAttribute)
122*4a64e381SAndroid Build Coastguard Worker         {
123*4a64e381SAndroid Build Coastguard Worker             entryLength += txtEntry.mValue.size() + sizeof(uint8_t); // for `=` char.
124*4a64e381SAndroid Build Coastguard Worker         }
125*4a64e381SAndroid Build Coastguard Worker 
126*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(entryLength <= kMaxTextEntrySize, error = OTBR_ERROR_INVALID_ARGS);
127*4a64e381SAndroid Build Coastguard Worker 
128*4a64e381SAndroid Build Coastguard Worker         aTxtData.push_back(static_cast<uint8_t>(entryLength));
129*4a64e381SAndroid Build Coastguard Worker         aTxtData.insert(aTxtData.end(), txtEntry.mKey.begin(), txtEntry.mKey.end());
130*4a64e381SAndroid Build Coastguard Worker 
131*4a64e381SAndroid Build Coastguard Worker         if (!txtEntry.mIsBooleanAttribute)
132*4a64e381SAndroid Build Coastguard Worker         {
133*4a64e381SAndroid Build Coastguard Worker             aTxtData.push_back('=');
134*4a64e381SAndroid Build Coastguard Worker             aTxtData.insert(aTxtData.end(), txtEntry.mValue.begin(), txtEntry.mValue.end());
135*4a64e381SAndroid Build Coastguard Worker         }
136*4a64e381SAndroid Build Coastguard Worker     }
137*4a64e381SAndroid Build Coastguard Worker 
138*4a64e381SAndroid Build Coastguard Worker     if (aTxtData.empty())
139*4a64e381SAndroid Build Coastguard Worker     {
140*4a64e381SAndroid Build Coastguard Worker         aTxtData.push_back(0);
141*4a64e381SAndroid Build Coastguard Worker     }
142*4a64e381SAndroid Build Coastguard Worker 
143*4a64e381SAndroid Build Coastguard Worker exit:
144*4a64e381SAndroid Build Coastguard Worker     return error;
145*4a64e381SAndroid Build Coastguard Worker }
146*4a64e381SAndroid Build Coastguard Worker 
DecodeTxtData(Publisher::TxtList & aTxtList,const uint8_t * aTxtData,uint16_t aTxtLength)147*4a64e381SAndroid Build Coastguard Worker otbrError Publisher::DecodeTxtData(Publisher::TxtList &aTxtList, const uint8_t *aTxtData, uint16_t aTxtLength)
148*4a64e381SAndroid Build Coastguard Worker {
149*4a64e381SAndroid Build Coastguard Worker     otbrError error = OTBR_ERROR_NONE;
150*4a64e381SAndroid Build Coastguard Worker 
151*4a64e381SAndroid Build Coastguard Worker     aTxtList.clear();
152*4a64e381SAndroid Build Coastguard Worker 
153*4a64e381SAndroid Build Coastguard Worker     for (uint16_t r = 0; r < aTxtLength;)
154*4a64e381SAndroid Build Coastguard Worker     {
155*4a64e381SAndroid Build Coastguard Worker         uint16_t entrySize = aTxtData[r];
156*4a64e381SAndroid Build Coastguard Worker         uint16_t keyStart  = r + 1;
157*4a64e381SAndroid Build Coastguard Worker         uint16_t entryEnd  = keyStart + entrySize;
158*4a64e381SAndroid Build Coastguard Worker         uint16_t keyEnd    = keyStart;
159*4a64e381SAndroid Build Coastguard Worker 
160*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(entryEnd <= aTxtLength, error = OTBR_ERROR_PARSE);
161*4a64e381SAndroid Build Coastguard Worker 
162*4a64e381SAndroid Build Coastguard Worker         while (keyEnd < entryEnd && aTxtData[keyEnd] != '=')
163*4a64e381SAndroid Build Coastguard Worker         {
164*4a64e381SAndroid Build Coastguard Worker             keyEnd++;
165*4a64e381SAndroid Build Coastguard Worker         }
166*4a64e381SAndroid Build Coastguard Worker 
167*4a64e381SAndroid Build Coastguard Worker         if (keyEnd == entryEnd)
168*4a64e381SAndroid Build Coastguard Worker         {
169*4a64e381SAndroid Build Coastguard Worker             if (keyEnd > keyStart)
170*4a64e381SAndroid Build Coastguard Worker             {
171*4a64e381SAndroid Build Coastguard Worker                 // No `=`, treat as a boolean attribute.
172*4a64e381SAndroid Build Coastguard Worker                 aTxtList.emplace_back(reinterpret_cast<const char *>(&aTxtData[keyStart]), keyEnd - keyStart);
173*4a64e381SAndroid Build Coastguard Worker             }
174*4a64e381SAndroid Build Coastguard Worker         }
175*4a64e381SAndroid Build Coastguard Worker         else
176*4a64e381SAndroid Build Coastguard Worker         {
177*4a64e381SAndroid Build Coastguard Worker             uint16_t valStart = keyEnd + 1; // To skip over `=`
178*4a64e381SAndroid Build Coastguard Worker 
179*4a64e381SAndroid Build Coastguard Worker             aTxtList.emplace_back(reinterpret_cast<const char *>(&aTxtData[keyStart]), keyEnd - keyStart,
180*4a64e381SAndroid Build Coastguard Worker                                   &aTxtData[valStart], entryEnd - valStart);
181*4a64e381SAndroid Build Coastguard Worker         }
182*4a64e381SAndroid Build Coastguard Worker 
183*4a64e381SAndroid Build Coastguard Worker         r += entrySize + 1;
184*4a64e381SAndroid Build Coastguard Worker     }
185*4a64e381SAndroid Build Coastguard Worker 
186*4a64e381SAndroid Build Coastguard Worker exit:
187*4a64e381SAndroid Build Coastguard Worker     return error;
188*4a64e381SAndroid Build Coastguard Worker }
189*4a64e381SAndroid Build Coastguard Worker 
RemoveSubscriptionCallbacks(uint64_t aSubscriberId)190*4a64e381SAndroid Build Coastguard Worker void Publisher::RemoveSubscriptionCallbacks(uint64_t aSubscriberId)
191*4a64e381SAndroid Build Coastguard Worker {
192*4a64e381SAndroid Build Coastguard Worker     mDiscoverCallbacks.remove_if(
193*4a64e381SAndroid Build Coastguard Worker         [aSubscriberId](const DiscoverCallback &aCallback) { return (aCallback.mId == aSubscriberId); });
194*4a64e381SAndroid Build Coastguard Worker }
195*4a64e381SAndroid Build Coastguard Worker 
AddSubscriptionCallbacks(Publisher::DiscoveredServiceInstanceCallback aInstanceCallback,Publisher::DiscoveredHostCallback aHostCallback)196*4a64e381SAndroid Build Coastguard Worker uint64_t Publisher::AddSubscriptionCallbacks(Publisher::DiscoveredServiceInstanceCallback aInstanceCallback,
197*4a64e381SAndroid Build Coastguard Worker                                              Publisher::DiscoveredHostCallback            aHostCallback)
198*4a64e381SAndroid Build Coastguard Worker {
199*4a64e381SAndroid Build Coastguard Worker     uint64_t id = mNextSubscriberId++;
200*4a64e381SAndroid Build Coastguard Worker 
201*4a64e381SAndroid Build Coastguard Worker     assert(id > 0);
202*4a64e381SAndroid Build Coastguard Worker     mDiscoverCallbacks.emplace_back(id, aInstanceCallback, aHostCallback);
203*4a64e381SAndroid Build Coastguard Worker 
204*4a64e381SAndroid Build Coastguard Worker     return id;
205*4a64e381SAndroid Build Coastguard Worker }
206*4a64e381SAndroid Build Coastguard Worker 
OnServiceResolved(std::string aType,DiscoveredInstanceInfo aInstanceInfo)207*4a64e381SAndroid Build Coastguard Worker void Publisher::OnServiceResolved(std::string aType, DiscoveredInstanceInfo aInstanceInfo)
208*4a64e381SAndroid Build Coastguard Worker {
209*4a64e381SAndroid Build Coastguard Worker     bool checkToInvoke = false;
210*4a64e381SAndroid Build Coastguard Worker 
211*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Service %s is resolved successfully: %s %s host %s addresses %zu", aType.c_str(),
212*4a64e381SAndroid Build Coastguard Worker                 aInstanceInfo.mRemoved ? "remove" : "add", aInstanceInfo.mName.c_str(), aInstanceInfo.mHostName.c_str(),
213*4a64e381SAndroid Build Coastguard Worker                 aInstanceInfo.mAddresses.size());
214*4a64e381SAndroid Build Coastguard Worker 
215*4a64e381SAndroid Build Coastguard Worker     if (!aInstanceInfo.mRemoved)
216*4a64e381SAndroid Build Coastguard Worker     {
217*4a64e381SAndroid Build Coastguard Worker         std::string addressesString;
218*4a64e381SAndroid Build Coastguard Worker 
219*4a64e381SAndroid Build Coastguard Worker         for (const auto &address : aInstanceInfo.mAddresses)
220*4a64e381SAndroid Build Coastguard Worker         {
221*4a64e381SAndroid Build Coastguard Worker             addressesString += address.ToString() + ",";
222*4a64e381SAndroid Build Coastguard Worker         }
223*4a64e381SAndroid Build Coastguard Worker         if (addressesString.size())
224*4a64e381SAndroid Build Coastguard Worker         {
225*4a64e381SAndroid Build Coastguard Worker             addressesString.pop_back();
226*4a64e381SAndroid Build Coastguard Worker         }
227*4a64e381SAndroid Build Coastguard Worker         otbrLogInfo("addresses: [ %s ]", addressesString.c_str());
228*4a64e381SAndroid Build Coastguard Worker     }
229*4a64e381SAndroid Build Coastguard Worker 
230*4a64e381SAndroid Build Coastguard Worker     DnsUtils::CheckServiceNameSanity(aType);
231*4a64e381SAndroid Build Coastguard Worker 
232*4a64e381SAndroid Build Coastguard Worker     assert(aInstanceInfo.mNetifIndex > 0);
233*4a64e381SAndroid Build Coastguard Worker 
234*4a64e381SAndroid Build Coastguard Worker     if (!aInstanceInfo.mRemoved)
235*4a64e381SAndroid Build Coastguard Worker     {
236*4a64e381SAndroid Build Coastguard Worker         DnsUtils::CheckHostnameSanity(aInstanceInfo.mHostName);
237*4a64e381SAndroid Build Coastguard Worker     }
238*4a64e381SAndroid Build Coastguard Worker 
239*4a64e381SAndroid Build Coastguard Worker     UpdateMdnsResponseCounters(mTelemetryInfo.mServiceResolutions, OTBR_ERROR_NONE);
240*4a64e381SAndroid Build Coastguard Worker     UpdateServiceInstanceResolutionEmaLatency(aInstanceInfo.mName, aType, OTBR_ERROR_NONE);
241*4a64e381SAndroid Build Coastguard Worker 
242*4a64e381SAndroid Build Coastguard Worker     // The `mDiscoverCallbacks` list can get updated as the callbacks
243*4a64e381SAndroid Build Coastguard Worker     // are invoked. We first mark `mShouldInvoke` on all non-null
244*4a64e381SAndroid Build Coastguard Worker     // service callbacks. We clear it before invoking the callback
245*4a64e381SAndroid Build Coastguard Worker     // and restart the iteration over the `mDiscoverCallbacks` list
246*4a64e381SAndroid Build Coastguard Worker     // to find the next one to signal, since the list may have changed.
247*4a64e381SAndroid Build Coastguard Worker 
248*4a64e381SAndroid Build Coastguard Worker     for (DiscoverCallback &callback : mDiscoverCallbacks)
249*4a64e381SAndroid Build Coastguard Worker     {
250*4a64e381SAndroid Build Coastguard Worker         if (callback.mServiceCallback != nullptr)
251*4a64e381SAndroid Build Coastguard Worker         {
252*4a64e381SAndroid Build Coastguard Worker             callback.mShouldInvoke = true;
253*4a64e381SAndroid Build Coastguard Worker             checkToInvoke          = true;
254*4a64e381SAndroid Build Coastguard Worker         }
255*4a64e381SAndroid Build Coastguard Worker     }
256*4a64e381SAndroid Build Coastguard Worker 
257*4a64e381SAndroid Build Coastguard Worker     while (checkToInvoke)
258*4a64e381SAndroid Build Coastguard Worker     {
259*4a64e381SAndroid Build Coastguard Worker         checkToInvoke = false;
260*4a64e381SAndroid Build Coastguard Worker 
261*4a64e381SAndroid Build Coastguard Worker         for (DiscoverCallback &callback : mDiscoverCallbacks)
262*4a64e381SAndroid Build Coastguard Worker         {
263*4a64e381SAndroid Build Coastguard Worker             if (callback.mShouldInvoke)
264*4a64e381SAndroid Build Coastguard Worker             {
265*4a64e381SAndroid Build Coastguard Worker                 callback.mShouldInvoke = false;
266*4a64e381SAndroid Build Coastguard Worker                 checkToInvoke          = true;
267*4a64e381SAndroid Build Coastguard Worker                 callback.mServiceCallback(aType, aInstanceInfo);
268*4a64e381SAndroid Build Coastguard Worker                 break;
269*4a64e381SAndroid Build Coastguard Worker             }
270*4a64e381SAndroid Build Coastguard Worker         }
271*4a64e381SAndroid Build Coastguard Worker     }
272*4a64e381SAndroid Build Coastguard Worker }
273*4a64e381SAndroid Build Coastguard Worker 
OnServiceRemoved(uint32_t aNetifIndex,std::string aType,std::string aInstanceName)274*4a64e381SAndroid Build Coastguard Worker void Publisher::OnServiceRemoved(uint32_t aNetifIndex, std::string aType, std::string aInstanceName)
275*4a64e381SAndroid Build Coastguard Worker {
276*4a64e381SAndroid Build Coastguard Worker     DiscoveredInstanceInfo instanceInfo;
277*4a64e381SAndroid Build Coastguard Worker 
278*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Service %s.%s is removed from netif %u.", aInstanceName.c_str(), aType.c_str(), aNetifIndex);
279*4a64e381SAndroid Build Coastguard Worker 
280*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mRemoved    = true;
281*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mNetifIndex = aNetifIndex;
282*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mName       = aInstanceName;
283*4a64e381SAndroid Build Coastguard Worker 
284*4a64e381SAndroid Build Coastguard Worker     OnServiceResolved(aType, instanceInfo);
285*4a64e381SAndroid Build Coastguard Worker }
286*4a64e381SAndroid Build Coastguard Worker 
OnHostResolved(std::string aHostName,Publisher::DiscoveredHostInfo aHostInfo)287*4a64e381SAndroid Build Coastguard Worker void Publisher::OnHostResolved(std::string aHostName, Publisher::DiscoveredHostInfo aHostInfo)
288*4a64e381SAndroid Build Coastguard Worker {
289*4a64e381SAndroid Build Coastguard Worker     bool checkToInvoke = false;
290*4a64e381SAndroid Build Coastguard Worker 
291*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Host %s is resolved successfully: host %s addresses %zu ttl %u", aHostName.c_str(),
292*4a64e381SAndroid Build Coastguard Worker                 aHostInfo.mHostName.c_str(), aHostInfo.mAddresses.size(), aHostInfo.mTtl);
293*4a64e381SAndroid Build Coastguard Worker 
294*4a64e381SAndroid Build Coastguard Worker     if (!aHostInfo.mHostName.empty())
295*4a64e381SAndroid Build Coastguard Worker     {
296*4a64e381SAndroid Build Coastguard Worker         DnsUtils::CheckHostnameSanity(aHostInfo.mHostName);
297*4a64e381SAndroid Build Coastguard Worker     }
298*4a64e381SAndroid Build Coastguard Worker 
299*4a64e381SAndroid Build Coastguard Worker     UpdateMdnsResponseCounters(mTelemetryInfo.mHostResolutions, OTBR_ERROR_NONE);
300*4a64e381SAndroid Build Coastguard Worker     UpdateHostResolutionEmaLatency(aHostName, OTBR_ERROR_NONE);
301*4a64e381SAndroid Build Coastguard Worker 
302*4a64e381SAndroid Build Coastguard Worker     // The `mDiscoverCallbacks` list can get updated as the callbacks
303*4a64e381SAndroid Build Coastguard Worker     // are invoked. We first mark `mShouldInvoke` on all non-null
304*4a64e381SAndroid Build Coastguard Worker     // host callbacks. We clear it before invoking the callback
305*4a64e381SAndroid Build Coastguard Worker     // and restart the iteration over the `mDiscoverCallbacks` list
306*4a64e381SAndroid Build Coastguard Worker     // to find the next one to signal, since the list may have changed.
307*4a64e381SAndroid Build Coastguard Worker 
308*4a64e381SAndroid Build Coastguard Worker     for (DiscoverCallback &callback : mDiscoverCallbacks)
309*4a64e381SAndroid Build Coastguard Worker     {
310*4a64e381SAndroid Build Coastguard Worker         if (callback.mHostCallback != nullptr)
311*4a64e381SAndroid Build Coastguard Worker         {
312*4a64e381SAndroid Build Coastguard Worker             callback.mShouldInvoke = true;
313*4a64e381SAndroid Build Coastguard Worker             checkToInvoke          = true;
314*4a64e381SAndroid Build Coastguard Worker         }
315*4a64e381SAndroid Build Coastguard Worker     }
316*4a64e381SAndroid Build Coastguard Worker 
317*4a64e381SAndroid Build Coastguard Worker     while (checkToInvoke)
318*4a64e381SAndroid Build Coastguard Worker     {
319*4a64e381SAndroid Build Coastguard Worker         checkToInvoke = false;
320*4a64e381SAndroid Build Coastguard Worker 
321*4a64e381SAndroid Build Coastguard Worker         for (DiscoverCallback &callback : mDiscoverCallbacks)
322*4a64e381SAndroid Build Coastguard Worker         {
323*4a64e381SAndroid Build Coastguard Worker             if (callback.mShouldInvoke)
324*4a64e381SAndroid Build Coastguard Worker             {
325*4a64e381SAndroid Build Coastguard Worker                 callback.mShouldInvoke = false;
326*4a64e381SAndroid Build Coastguard Worker                 checkToInvoke          = true;
327*4a64e381SAndroid Build Coastguard Worker                 callback.mHostCallback(aHostName, aHostInfo);
328*4a64e381SAndroid Build Coastguard Worker                 break;
329*4a64e381SAndroid Build Coastguard Worker             }
330*4a64e381SAndroid Build Coastguard Worker         }
331*4a64e381SAndroid Build Coastguard Worker     }
332*4a64e381SAndroid Build Coastguard Worker }
333*4a64e381SAndroid Build Coastguard Worker 
SortSubTypeList(SubTypeList aSubTypeList)334*4a64e381SAndroid Build Coastguard Worker Publisher::SubTypeList Publisher::SortSubTypeList(SubTypeList aSubTypeList)
335*4a64e381SAndroid Build Coastguard Worker {
336*4a64e381SAndroid Build Coastguard Worker     std::sort(aSubTypeList.begin(), aSubTypeList.end());
337*4a64e381SAndroid Build Coastguard Worker     return aSubTypeList;
338*4a64e381SAndroid Build Coastguard Worker }
339*4a64e381SAndroid Build Coastguard Worker 
SortAddressList(AddressList aAddressList)340*4a64e381SAndroid Build Coastguard Worker Publisher::AddressList Publisher::SortAddressList(AddressList aAddressList)
341*4a64e381SAndroid Build Coastguard Worker {
342*4a64e381SAndroid Build Coastguard Worker     std::sort(aAddressList.begin(), aAddressList.end());
343*4a64e381SAndroid Build Coastguard Worker     return aAddressList;
344*4a64e381SAndroid Build Coastguard Worker }
345*4a64e381SAndroid Build Coastguard Worker 
MakeFullServiceName(const std::string & aName,const std::string & aType)346*4a64e381SAndroid Build Coastguard Worker std::string Publisher::MakeFullServiceName(const std::string &aName, const std::string &aType)
347*4a64e381SAndroid Build Coastguard Worker {
348*4a64e381SAndroid Build Coastguard Worker     return aName + "." + aType + ".local";
349*4a64e381SAndroid Build Coastguard Worker }
350*4a64e381SAndroid Build Coastguard Worker 
MakeFullName(const std::string & aName)351*4a64e381SAndroid Build Coastguard Worker std::string Publisher::MakeFullName(const std::string &aName)
352*4a64e381SAndroid Build Coastguard Worker {
353*4a64e381SAndroid Build Coastguard Worker     return aName + ".local";
354*4a64e381SAndroid Build Coastguard Worker }
355*4a64e381SAndroid Build Coastguard Worker 
AddServiceRegistration(ServiceRegistrationPtr && aServiceReg)356*4a64e381SAndroid Build Coastguard Worker void Publisher::AddServiceRegistration(ServiceRegistrationPtr &&aServiceReg)
357*4a64e381SAndroid Build Coastguard Worker {
358*4a64e381SAndroid Build Coastguard Worker     mServiceRegistrations.emplace(MakeFullServiceName(aServiceReg->mName, aServiceReg->mType), std::move(aServiceReg));
359*4a64e381SAndroid Build Coastguard Worker }
360*4a64e381SAndroid Build Coastguard Worker 
RemoveServiceRegistration(const std::string & aName,const std::string & aType,otbrError aError)361*4a64e381SAndroid Build Coastguard Worker void Publisher::RemoveServiceRegistration(const std::string &aName, const std::string &aType, otbrError aError)
362*4a64e381SAndroid Build Coastguard Worker {
363*4a64e381SAndroid Build Coastguard Worker     auto                   it = mServiceRegistrations.find(MakeFullServiceName(aName, aType));
364*4a64e381SAndroid Build Coastguard Worker     ServiceRegistrationPtr serviceReg;
365*4a64e381SAndroid Build Coastguard Worker 
366*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Removing service %s.%s", aName.c_str(), aType.c_str());
367*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(it != mServiceRegistrations.end());
368*4a64e381SAndroid Build Coastguard Worker 
369*4a64e381SAndroid Build Coastguard Worker     // Keep the ServiceRegistration around before calling `Complete`
370*4a64e381SAndroid Build Coastguard Worker     // to invoke the callback. This is for avoiding invalid access
371*4a64e381SAndroid Build Coastguard Worker     // to the ServiceRegistration when it's freed from the callback.
372*4a64e381SAndroid Build Coastguard Worker     serviceReg = std::move(it->second);
373*4a64e381SAndroid Build Coastguard Worker     mServiceRegistrations.erase(it);
374*4a64e381SAndroid Build Coastguard Worker     serviceReg->Complete(aError);
375*4a64e381SAndroid Build Coastguard Worker 
376*4a64e381SAndroid Build Coastguard Worker exit:
377*4a64e381SAndroid Build Coastguard Worker     return;
378*4a64e381SAndroid Build Coastguard Worker }
379*4a64e381SAndroid Build Coastguard Worker 
FindServiceRegistration(const std::string & aName,const std::string & aType)380*4a64e381SAndroid Build Coastguard Worker Publisher::ServiceRegistration *Publisher::FindServiceRegistration(const std::string &aName, const std::string &aType)
381*4a64e381SAndroid Build Coastguard Worker {
382*4a64e381SAndroid Build Coastguard Worker     auto it = mServiceRegistrations.find(MakeFullServiceName(aName, aType));
383*4a64e381SAndroid Build Coastguard Worker 
384*4a64e381SAndroid Build Coastguard Worker     return it != mServiceRegistrations.end() ? it->second.get() : nullptr;
385*4a64e381SAndroid Build Coastguard Worker }
386*4a64e381SAndroid Build Coastguard Worker 
FindServiceRegistration(const std::string & aNameAndType)387*4a64e381SAndroid Build Coastguard Worker Publisher::ServiceRegistration *Publisher::FindServiceRegistration(const std::string &aNameAndType)
388*4a64e381SAndroid Build Coastguard Worker {
389*4a64e381SAndroid Build Coastguard Worker     auto it = mServiceRegistrations.find(MakeFullName(aNameAndType));
390*4a64e381SAndroid Build Coastguard Worker 
391*4a64e381SAndroid Build Coastguard Worker     return it != mServiceRegistrations.end() ? it->second.get() : nullptr;
392*4a64e381SAndroid Build Coastguard Worker }
393*4a64e381SAndroid Build Coastguard Worker 
HandleDuplicateServiceRegistration(const std::string & aHostName,const std::string & aName,const std::string & aType,const SubTypeList & aSubTypeList,uint16_t aPort,const TxtData & aTxtData,ResultCallback && aCallback)394*4a64e381SAndroid Build Coastguard Worker Publisher::ResultCallback Publisher::HandleDuplicateServiceRegistration(const std::string &aHostName,
395*4a64e381SAndroid Build Coastguard Worker                                                                         const std::string &aName,
396*4a64e381SAndroid Build Coastguard Worker                                                                         const std::string &aType,
397*4a64e381SAndroid Build Coastguard Worker                                                                         const SubTypeList &aSubTypeList,
398*4a64e381SAndroid Build Coastguard Worker                                                                         uint16_t           aPort,
399*4a64e381SAndroid Build Coastguard Worker                                                                         const TxtData     &aTxtData,
400*4a64e381SAndroid Build Coastguard Worker                                                                         ResultCallback   &&aCallback)
401*4a64e381SAndroid Build Coastguard Worker {
402*4a64e381SAndroid Build Coastguard Worker     ServiceRegistration *serviceReg = FindServiceRegistration(aName, aType);
403*4a64e381SAndroid Build Coastguard Worker 
404*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(serviceReg != nullptr);
405*4a64e381SAndroid Build Coastguard Worker 
406*4a64e381SAndroid Build Coastguard Worker     if (serviceReg->IsOutdated(aHostName, aName, aType, aSubTypeList, aPort, aTxtData))
407*4a64e381SAndroid Build Coastguard Worker     {
408*4a64e381SAndroid Build Coastguard Worker         otbrLogInfo("Removing existing service %s.%s: outdated", aName.c_str(), aType.c_str());
409*4a64e381SAndroid Build Coastguard Worker         RemoveServiceRegistration(aName, aType, OTBR_ERROR_ABORTED);
410*4a64e381SAndroid Build Coastguard Worker     }
411*4a64e381SAndroid Build Coastguard Worker     else if (serviceReg->IsCompleted())
412*4a64e381SAndroid Build Coastguard Worker     {
413*4a64e381SAndroid Build Coastguard Worker         // Returns success if the same service has already been
414*4a64e381SAndroid Build Coastguard Worker         // registered with exactly the same parameters.
415*4a64e381SAndroid Build Coastguard Worker         std::move(aCallback)(OTBR_ERROR_NONE);
416*4a64e381SAndroid Build Coastguard Worker     }
417*4a64e381SAndroid Build Coastguard Worker     else
418*4a64e381SAndroid Build Coastguard Worker     {
419*4a64e381SAndroid Build Coastguard Worker         // If the same service is being registered with the same parameters,
420*4a64e381SAndroid Build Coastguard Worker         // let's join the waiting queue for the result.
421*4a64e381SAndroid Build Coastguard Worker         serviceReg->mCallback = std::bind(
422*4a64e381SAndroid Build Coastguard Worker             [](std::shared_ptr<ResultCallback> aExistingCallback, std::shared_ptr<ResultCallback> aNewCallback,
423*4a64e381SAndroid Build Coastguard Worker                otbrError aError) {
424*4a64e381SAndroid Build Coastguard Worker                 std::move (*aExistingCallback)(aError);
425*4a64e381SAndroid Build Coastguard Worker                 std::move (*aNewCallback)(aError);
426*4a64e381SAndroid Build Coastguard Worker             },
427*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(serviceReg->mCallback)),
428*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(aCallback)), std::placeholders::_1);
429*4a64e381SAndroid Build Coastguard Worker     }
430*4a64e381SAndroid Build Coastguard Worker 
431*4a64e381SAndroid Build Coastguard Worker exit:
432*4a64e381SAndroid Build Coastguard Worker     return std::move(aCallback);
433*4a64e381SAndroid Build Coastguard Worker }
434*4a64e381SAndroid Build Coastguard Worker 
HandleDuplicateHostRegistration(const std::string & aName,const AddressList & aAddresses,ResultCallback && aCallback)435*4a64e381SAndroid Build Coastguard Worker Publisher::ResultCallback Publisher::HandleDuplicateHostRegistration(const std::string &aName,
436*4a64e381SAndroid Build Coastguard Worker                                                                      const AddressList &aAddresses,
437*4a64e381SAndroid Build Coastguard Worker                                                                      ResultCallback   &&aCallback)
438*4a64e381SAndroid Build Coastguard Worker {
439*4a64e381SAndroid Build Coastguard Worker     HostRegistration *hostReg = FindHostRegistration(aName);
440*4a64e381SAndroid Build Coastguard Worker 
441*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(hostReg != nullptr);
442*4a64e381SAndroid Build Coastguard Worker 
443*4a64e381SAndroid Build Coastguard Worker     if (hostReg->IsOutdated(aName, aAddresses))
444*4a64e381SAndroid Build Coastguard Worker     {
445*4a64e381SAndroid Build Coastguard Worker         otbrLogInfo("Removing existing host %s: outdated", aName.c_str());
446*4a64e381SAndroid Build Coastguard Worker         RemoveHostRegistration(hostReg->mName, OTBR_ERROR_ABORTED);
447*4a64e381SAndroid Build Coastguard Worker     }
448*4a64e381SAndroid Build Coastguard Worker     else if (hostReg->IsCompleted())
449*4a64e381SAndroid Build Coastguard Worker     {
450*4a64e381SAndroid Build Coastguard Worker         // Returns success if the same service has already been
451*4a64e381SAndroid Build Coastguard Worker         // registered with exactly the same parameters.
452*4a64e381SAndroid Build Coastguard Worker         std::move(aCallback)(OTBR_ERROR_NONE);
453*4a64e381SAndroid Build Coastguard Worker     }
454*4a64e381SAndroid Build Coastguard Worker     else
455*4a64e381SAndroid Build Coastguard Worker     {
456*4a64e381SAndroid Build Coastguard Worker         // If the same service is being registered with the same parameters,
457*4a64e381SAndroid Build Coastguard Worker         // let's join the waiting queue for the result.
458*4a64e381SAndroid Build Coastguard Worker         hostReg->mCallback = std::bind(
459*4a64e381SAndroid Build Coastguard Worker             [](std::shared_ptr<ResultCallback> aExistingCallback, std::shared_ptr<ResultCallback> aNewCallback,
460*4a64e381SAndroid Build Coastguard Worker                otbrError aError) {
461*4a64e381SAndroid Build Coastguard Worker                 std::move (*aExistingCallback)(aError);
462*4a64e381SAndroid Build Coastguard Worker                 std::move (*aNewCallback)(aError);
463*4a64e381SAndroid Build Coastguard Worker             },
464*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(hostReg->mCallback)),
465*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(aCallback)), std::placeholders::_1);
466*4a64e381SAndroid Build Coastguard Worker     }
467*4a64e381SAndroid Build Coastguard Worker 
468*4a64e381SAndroid Build Coastguard Worker exit:
469*4a64e381SAndroid Build Coastguard Worker     return std::move(aCallback);
470*4a64e381SAndroid Build Coastguard Worker }
471*4a64e381SAndroid Build Coastguard Worker 
AddHostRegistration(HostRegistrationPtr && aHostReg)472*4a64e381SAndroid Build Coastguard Worker void Publisher::AddHostRegistration(HostRegistrationPtr &&aHostReg)
473*4a64e381SAndroid Build Coastguard Worker {
474*4a64e381SAndroid Build Coastguard Worker     mHostRegistrations.emplace(MakeFullHostName(aHostReg->mName), std::move(aHostReg));
475*4a64e381SAndroid Build Coastguard Worker }
476*4a64e381SAndroid Build Coastguard Worker 
RemoveHostRegistration(const std::string & aName,otbrError aError)477*4a64e381SAndroid Build Coastguard Worker void Publisher::RemoveHostRegistration(const std::string &aName, otbrError aError)
478*4a64e381SAndroid Build Coastguard Worker {
479*4a64e381SAndroid Build Coastguard Worker     auto                it = mHostRegistrations.find(MakeFullHostName(aName));
480*4a64e381SAndroid Build Coastguard Worker     HostRegistrationPtr hostReg;
481*4a64e381SAndroid Build Coastguard Worker 
482*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Removing host %s", aName.c_str());
483*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(it != mHostRegistrations.end());
484*4a64e381SAndroid Build Coastguard Worker 
485*4a64e381SAndroid Build Coastguard Worker     // Keep the HostRegistration around before calling `Complete`
486*4a64e381SAndroid Build Coastguard Worker     // to invoke the callback. This is for avoiding invalid access
487*4a64e381SAndroid Build Coastguard Worker     // to the HostRegistration when it's freed from the callback.
488*4a64e381SAndroid Build Coastguard Worker     hostReg = std::move(it->second);
489*4a64e381SAndroid Build Coastguard Worker     mHostRegistrations.erase(it);
490*4a64e381SAndroid Build Coastguard Worker     hostReg->Complete(aError);
491*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Removed host %s", aName.c_str());
492*4a64e381SAndroid Build Coastguard Worker 
493*4a64e381SAndroid Build Coastguard Worker exit:
494*4a64e381SAndroid Build Coastguard Worker     return;
495*4a64e381SAndroid Build Coastguard Worker }
496*4a64e381SAndroid Build Coastguard Worker 
FindHostRegistration(const std::string & aName)497*4a64e381SAndroid Build Coastguard Worker Publisher::HostRegistration *Publisher::FindHostRegistration(const std::string &aName)
498*4a64e381SAndroid Build Coastguard Worker {
499*4a64e381SAndroid Build Coastguard Worker     auto it = mHostRegistrations.find(MakeFullHostName(aName));
500*4a64e381SAndroid Build Coastguard Worker 
501*4a64e381SAndroid Build Coastguard Worker     return it != mHostRegistrations.end() ? it->second.get() : nullptr;
502*4a64e381SAndroid Build Coastguard Worker }
503*4a64e381SAndroid Build Coastguard Worker 
HandleDuplicateKeyRegistration(const std::string & aName,const KeyData & aKeyData,ResultCallback && aCallback)504*4a64e381SAndroid Build Coastguard Worker Publisher::ResultCallback Publisher::HandleDuplicateKeyRegistration(const std::string &aName,
505*4a64e381SAndroid Build Coastguard Worker                                                                     const KeyData     &aKeyData,
506*4a64e381SAndroid Build Coastguard Worker                                                                     ResultCallback   &&aCallback)
507*4a64e381SAndroid Build Coastguard Worker {
508*4a64e381SAndroid Build Coastguard Worker     KeyRegistration *keyReg = FindKeyRegistration(aName);
509*4a64e381SAndroid Build Coastguard Worker 
510*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(keyReg != nullptr);
511*4a64e381SAndroid Build Coastguard Worker 
512*4a64e381SAndroid Build Coastguard Worker     if (keyReg->IsOutdated(aName, aKeyData))
513*4a64e381SAndroid Build Coastguard Worker     {
514*4a64e381SAndroid Build Coastguard Worker         otbrLogInfo("Removing existing key %s: outdated", aName.c_str());
515*4a64e381SAndroid Build Coastguard Worker         RemoveKeyRegistration(keyReg->mName, OTBR_ERROR_ABORTED);
516*4a64e381SAndroid Build Coastguard Worker     }
517*4a64e381SAndroid Build Coastguard Worker     else if (keyReg->IsCompleted())
518*4a64e381SAndroid Build Coastguard Worker     {
519*4a64e381SAndroid Build Coastguard Worker         // Returns success if the same key has already been
520*4a64e381SAndroid Build Coastguard Worker         // registered with exactly the same parameters.
521*4a64e381SAndroid Build Coastguard Worker         std::move(aCallback)(OTBR_ERROR_NONE);
522*4a64e381SAndroid Build Coastguard Worker     }
523*4a64e381SAndroid Build Coastguard Worker     else
524*4a64e381SAndroid Build Coastguard Worker     {
525*4a64e381SAndroid Build Coastguard Worker         // If the same key is being registered with the same parameters,
526*4a64e381SAndroid Build Coastguard Worker         // let's join the waiting queue for the result.
527*4a64e381SAndroid Build Coastguard Worker         keyReg->mCallback = std::bind(
528*4a64e381SAndroid Build Coastguard Worker             [](std::shared_ptr<ResultCallback> aExistingCallback, std::shared_ptr<ResultCallback> aNewCallback,
529*4a64e381SAndroid Build Coastguard Worker                otbrError aError) {
530*4a64e381SAndroid Build Coastguard Worker                 std::move (*aExistingCallback)(aError);
531*4a64e381SAndroid Build Coastguard Worker                 std::move (*aNewCallback)(aError);
532*4a64e381SAndroid Build Coastguard Worker             },
533*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(keyReg->mCallback)),
534*4a64e381SAndroid Build Coastguard Worker             std::make_shared<ResultCallback>(std::move(aCallback)), std::placeholders::_1);
535*4a64e381SAndroid Build Coastguard Worker     }
536*4a64e381SAndroid Build Coastguard Worker 
537*4a64e381SAndroid Build Coastguard Worker exit:
538*4a64e381SAndroid Build Coastguard Worker     return std::move(aCallback);
539*4a64e381SAndroid Build Coastguard Worker }
540*4a64e381SAndroid Build Coastguard Worker 
AddKeyRegistration(KeyRegistrationPtr && aKeyReg)541*4a64e381SAndroid Build Coastguard Worker void Publisher::AddKeyRegistration(KeyRegistrationPtr &&aKeyReg)
542*4a64e381SAndroid Build Coastguard Worker {
543*4a64e381SAndroid Build Coastguard Worker     mKeyRegistrations.emplace(MakeFullKeyName(aKeyReg->mName), std::move(aKeyReg));
544*4a64e381SAndroid Build Coastguard Worker }
545*4a64e381SAndroid Build Coastguard Worker 
RemoveKeyRegistration(const std::string & aName,otbrError aError)546*4a64e381SAndroid Build Coastguard Worker void Publisher::RemoveKeyRegistration(const std::string &aName, otbrError aError)
547*4a64e381SAndroid Build Coastguard Worker {
548*4a64e381SAndroid Build Coastguard Worker     auto               it = mKeyRegistrations.find(MakeFullKeyName(aName));
549*4a64e381SAndroid Build Coastguard Worker     KeyRegistrationPtr keyReg;
550*4a64e381SAndroid Build Coastguard Worker 
551*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Removing key %s", aName.c_str());
552*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(it != mKeyRegistrations.end());
553*4a64e381SAndroid Build Coastguard Worker 
554*4a64e381SAndroid Build Coastguard Worker     // Keep the KeyRegistration around before calling `Complete`
555*4a64e381SAndroid Build Coastguard Worker     // to invoke the callback. This is for avoiding invalid access
556*4a64e381SAndroid Build Coastguard Worker     // to the KeyRegistration when it's freed from the callback.
557*4a64e381SAndroid Build Coastguard Worker     keyReg = std::move(it->second);
558*4a64e381SAndroid Build Coastguard Worker     mKeyRegistrations.erase(it);
559*4a64e381SAndroid Build Coastguard Worker     keyReg->Complete(aError);
560*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Removed key %s", aName.c_str());
561*4a64e381SAndroid Build Coastguard Worker 
562*4a64e381SAndroid Build Coastguard Worker exit:
563*4a64e381SAndroid Build Coastguard Worker     return;
564*4a64e381SAndroid Build Coastguard Worker }
565*4a64e381SAndroid Build Coastguard Worker 
FindKeyRegistration(const std::string & aName)566*4a64e381SAndroid Build Coastguard Worker Publisher::KeyRegistration *Publisher::FindKeyRegistration(const std::string &aName)
567*4a64e381SAndroid Build Coastguard Worker {
568*4a64e381SAndroid Build Coastguard Worker     auto it = mKeyRegistrations.find(MakeFullKeyName(aName));
569*4a64e381SAndroid Build Coastguard Worker 
570*4a64e381SAndroid Build Coastguard Worker     return it != mKeyRegistrations.end() ? it->second.get() : nullptr;
571*4a64e381SAndroid Build Coastguard Worker }
572*4a64e381SAndroid Build Coastguard Worker 
FindKeyRegistration(const std::string & aName,const std::string & aType)573*4a64e381SAndroid Build Coastguard Worker Publisher::KeyRegistration *Publisher::FindKeyRegistration(const std::string &aName, const std::string &aType)
574*4a64e381SAndroid Build Coastguard Worker {
575*4a64e381SAndroid Build Coastguard Worker     auto it = mKeyRegistrations.find(MakeFullServiceName(aName, aType));
576*4a64e381SAndroid Build Coastguard Worker 
577*4a64e381SAndroid Build Coastguard Worker     return it != mKeyRegistrations.end() ? it->second.get() : nullptr;
578*4a64e381SAndroid Build Coastguard Worker }
579*4a64e381SAndroid Build Coastguard Worker 
~Registration(void)580*4a64e381SAndroid Build Coastguard Worker Publisher::Registration::~Registration(void)
581*4a64e381SAndroid Build Coastguard Worker {
582*4a64e381SAndroid Build Coastguard Worker     TriggerCompleteCallback(OTBR_ERROR_ABORTED);
583*4a64e381SAndroid Build Coastguard Worker }
584*4a64e381SAndroid Build Coastguard Worker 
IsOutdated(const std::string & aHostName,const std::string & aName,const std::string & aType,const SubTypeList & aSubTypeList,uint16_t aPort,const TxtData & aTxtData) const585*4a64e381SAndroid Build Coastguard Worker bool Publisher::ServiceRegistration::IsOutdated(const std::string &aHostName,
586*4a64e381SAndroid Build Coastguard Worker                                                 const std::string &aName,
587*4a64e381SAndroid Build Coastguard Worker                                                 const std::string &aType,
588*4a64e381SAndroid Build Coastguard Worker                                                 const SubTypeList &aSubTypeList,
589*4a64e381SAndroid Build Coastguard Worker                                                 uint16_t           aPort,
590*4a64e381SAndroid Build Coastguard Worker                                                 const TxtData     &aTxtData) const
591*4a64e381SAndroid Build Coastguard Worker {
592*4a64e381SAndroid Build Coastguard Worker     return !(mHostName == aHostName && mName == aName && mType == aType && mSubTypeList == aSubTypeList &&
593*4a64e381SAndroid Build Coastguard Worker              mPort == aPort && mTxtData == aTxtData);
594*4a64e381SAndroid Build Coastguard Worker }
595*4a64e381SAndroid Build Coastguard Worker 
Complete(otbrError aError)596*4a64e381SAndroid Build Coastguard Worker void Publisher::ServiceRegistration::Complete(otbrError aError)
597*4a64e381SAndroid Build Coastguard Worker {
598*4a64e381SAndroid Build Coastguard Worker     OnComplete(aError);
599*4a64e381SAndroid Build Coastguard Worker     Registration::TriggerCompleteCallback(aError);
600*4a64e381SAndroid Build Coastguard Worker }
601*4a64e381SAndroid Build Coastguard Worker 
OnComplete(otbrError aError)602*4a64e381SAndroid Build Coastguard Worker void Publisher::ServiceRegistration::OnComplete(otbrError aError)
603*4a64e381SAndroid Build Coastguard Worker {
604*4a64e381SAndroid Build Coastguard Worker     if (!IsCompleted())
605*4a64e381SAndroid Build Coastguard Worker     {
606*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateMdnsResponseCounters(mPublisher->mTelemetryInfo.mServiceRegistrations, aError);
607*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateServiceRegistrationEmaLatency(mName, mType, aError);
608*4a64e381SAndroid Build Coastguard Worker     }
609*4a64e381SAndroid Build Coastguard Worker }
610*4a64e381SAndroid Build Coastguard Worker 
IsOutdated(const std::string & aName,const AddressList & aAddresses) const611*4a64e381SAndroid Build Coastguard Worker bool Publisher::HostRegistration::IsOutdated(const std::string &aName, const AddressList &aAddresses) const
612*4a64e381SAndroid Build Coastguard Worker {
613*4a64e381SAndroid Build Coastguard Worker     return !(mName == aName && mAddresses == aAddresses);
614*4a64e381SAndroid Build Coastguard Worker }
615*4a64e381SAndroid Build Coastguard Worker 
Complete(otbrError aError)616*4a64e381SAndroid Build Coastguard Worker void Publisher::HostRegistration::Complete(otbrError aError)
617*4a64e381SAndroid Build Coastguard Worker {
618*4a64e381SAndroid Build Coastguard Worker     OnComplete(aError);
619*4a64e381SAndroid Build Coastguard Worker     Registration::TriggerCompleteCallback(aError);
620*4a64e381SAndroid Build Coastguard Worker }
621*4a64e381SAndroid Build Coastguard Worker 
OnComplete(otbrError aError)622*4a64e381SAndroid Build Coastguard Worker void Publisher::HostRegistration::OnComplete(otbrError aError)
623*4a64e381SAndroid Build Coastguard Worker {
624*4a64e381SAndroid Build Coastguard Worker     if (!IsCompleted())
625*4a64e381SAndroid Build Coastguard Worker     {
626*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateMdnsResponseCounters(mPublisher->mTelemetryInfo.mHostRegistrations, aError);
627*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateHostRegistrationEmaLatency(mName, aError);
628*4a64e381SAndroid Build Coastguard Worker     }
629*4a64e381SAndroid Build Coastguard Worker }
630*4a64e381SAndroid Build Coastguard Worker 
IsOutdated(const std::string & aName,const KeyData & aKeyData) const631*4a64e381SAndroid Build Coastguard Worker bool Publisher::KeyRegistration::IsOutdated(const std::string &aName, const KeyData &aKeyData) const
632*4a64e381SAndroid Build Coastguard Worker {
633*4a64e381SAndroid Build Coastguard Worker     return !(mName == aName && mKeyData == aKeyData);
634*4a64e381SAndroid Build Coastguard Worker }
635*4a64e381SAndroid Build Coastguard Worker 
Complete(otbrError aError)636*4a64e381SAndroid Build Coastguard Worker void Publisher::KeyRegistration::Complete(otbrError aError)
637*4a64e381SAndroid Build Coastguard Worker {
638*4a64e381SAndroid Build Coastguard Worker     OnComplete(aError);
639*4a64e381SAndroid Build Coastguard Worker     Registration::TriggerCompleteCallback(aError);
640*4a64e381SAndroid Build Coastguard Worker }
641*4a64e381SAndroid Build Coastguard Worker 
OnComplete(otbrError aError)642*4a64e381SAndroid Build Coastguard Worker void Publisher::KeyRegistration::OnComplete(otbrError aError)
643*4a64e381SAndroid Build Coastguard Worker {
644*4a64e381SAndroid Build Coastguard Worker     if (!IsCompleted())
645*4a64e381SAndroid Build Coastguard Worker     {
646*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateMdnsResponseCounters(mPublisher->mTelemetryInfo.mKeyRegistrations, aError);
647*4a64e381SAndroid Build Coastguard Worker         mPublisher->UpdateKeyRegistrationEmaLatency(mName, aError);
648*4a64e381SAndroid Build Coastguard Worker     }
649*4a64e381SAndroid Build Coastguard Worker }
650*4a64e381SAndroid Build Coastguard Worker 
UpdateMdnsResponseCounters(otbr::MdnsResponseCounters & aCounters,otbrError aError)651*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateMdnsResponseCounters(otbr::MdnsResponseCounters &aCounters, otbrError aError)
652*4a64e381SAndroid Build Coastguard Worker {
653*4a64e381SAndroid Build Coastguard Worker     switch (aError)
654*4a64e381SAndroid Build Coastguard Worker     {
655*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_NONE:
656*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mSuccess;
657*4a64e381SAndroid Build Coastguard Worker         break;
658*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_NOT_FOUND:
659*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mNotFound;
660*4a64e381SAndroid Build Coastguard Worker         break;
661*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_INVALID_ARGS:
662*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mInvalidArgs;
663*4a64e381SAndroid Build Coastguard Worker         break;
664*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_DUPLICATED:
665*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mDuplicated;
666*4a64e381SAndroid Build Coastguard Worker         break;
667*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_NOT_IMPLEMENTED:
668*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mNotImplemented;
669*4a64e381SAndroid Build Coastguard Worker         break;
670*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_ABORTED:
671*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mAborted;
672*4a64e381SAndroid Build Coastguard Worker         break;
673*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_INVALID_STATE:
674*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mInvalidState;
675*4a64e381SAndroid Build Coastguard Worker         break;
676*4a64e381SAndroid Build Coastguard Worker     case OTBR_ERROR_MDNS:
677*4a64e381SAndroid Build Coastguard Worker     default:
678*4a64e381SAndroid Build Coastguard Worker         ++aCounters.mUnknownError;
679*4a64e381SAndroid Build Coastguard Worker         break;
680*4a64e381SAndroid Build Coastguard Worker     }
681*4a64e381SAndroid Build Coastguard Worker }
682*4a64e381SAndroid Build Coastguard Worker 
UpdateEmaLatency(uint32_t & aEmaLatency,uint32_t aLatency,otbrError aError)683*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateEmaLatency(uint32_t &aEmaLatency, uint32_t aLatency, otbrError aError)
684*4a64e381SAndroid Build Coastguard Worker {
685*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(aError != OTBR_ERROR_ABORTED);
686*4a64e381SAndroid Build Coastguard Worker 
687*4a64e381SAndroid Build Coastguard Worker     if (!aEmaLatency)
688*4a64e381SAndroid Build Coastguard Worker     {
689*4a64e381SAndroid Build Coastguard Worker         aEmaLatency = aLatency;
690*4a64e381SAndroid Build Coastguard Worker     }
691*4a64e381SAndroid Build Coastguard Worker     else
692*4a64e381SAndroid Build Coastguard Worker     {
693*4a64e381SAndroid Build Coastguard Worker         aEmaLatency =
694*4a64e381SAndroid Build Coastguard Worker             (aLatency * MdnsTelemetryInfo::kEmaFactorNumerator +
695*4a64e381SAndroid Build Coastguard Worker              aEmaLatency * (MdnsTelemetryInfo::kEmaFactorDenominator - MdnsTelemetryInfo::kEmaFactorNumerator)) /
696*4a64e381SAndroid Build Coastguard Worker             MdnsTelemetryInfo::kEmaFactorDenominator;
697*4a64e381SAndroid Build Coastguard Worker     }
698*4a64e381SAndroid Build Coastguard Worker 
699*4a64e381SAndroid Build Coastguard Worker exit:
700*4a64e381SAndroid Build Coastguard Worker     return;
701*4a64e381SAndroid Build Coastguard Worker }
702*4a64e381SAndroid Build Coastguard Worker 
UpdateServiceRegistrationEmaLatency(const std::string & aInstanceName,const std::string & aType,otbrError aError)703*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateServiceRegistrationEmaLatency(const std::string &aInstanceName,
704*4a64e381SAndroid Build Coastguard Worker                                                     const std::string &aType,
705*4a64e381SAndroid Build Coastguard Worker                                                     otbrError          aError)
706*4a64e381SAndroid Build Coastguard Worker {
707*4a64e381SAndroid Build Coastguard Worker     auto it = mServiceRegistrationBeginTime.find(std::make_pair(aInstanceName, aType));
708*4a64e381SAndroid Build Coastguard Worker 
709*4a64e381SAndroid Build Coastguard Worker     if (it != mServiceRegistrationBeginTime.end())
710*4a64e381SAndroid Build Coastguard Worker     {
711*4a64e381SAndroid Build Coastguard Worker         uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count();
712*4a64e381SAndroid Build Coastguard Worker         UpdateEmaLatency(mTelemetryInfo.mServiceRegistrationEmaLatency, latency, aError);
713*4a64e381SAndroid Build Coastguard Worker         mServiceRegistrationBeginTime.erase(it);
714*4a64e381SAndroid Build Coastguard Worker     }
715*4a64e381SAndroid Build Coastguard Worker }
716*4a64e381SAndroid Build Coastguard Worker 
UpdateHostRegistrationEmaLatency(const std::string & aHostName,otbrError aError)717*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateHostRegistrationEmaLatency(const std::string &aHostName, otbrError aError)
718*4a64e381SAndroid Build Coastguard Worker {
719*4a64e381SAndroid Build Coastguard Worker     auto it = mHostRegistrationBeginTime.find(aHostName);
720*4a64e381SAndroid Build Coastguard Worker 
721*4a64e381SAndroid Build Coastguard Worker     if (it != mHostRegistrationBeginTime.end())
722*4a64e381SAndroid Build Coastguard Worker     {
723*4a64e381SAndroid Build Coastguard Worker         uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count();
724*4a64e381SAndroid Build Coastguard Worker         UpdateEmaLatency(mTelemetryInfo.mHostRegistrationEmaLatency, latency, aError);
725*4a64e381SAndroid Build Coastguard Worker         mHostRegistrationBeginTime.erase(it);
726*4a64e381SAndroid Build Coastguard Worker     }
727*4a64e381SAndroid Build Coastguard Worker }
728*4a64e381SAndroid Build Coastguard Worker 
UpdateKeyRegistrationEmaLatency(const std::string & aKeyName,otbrError aError)729*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateKeyRegistrationEmaLatency(const std::string &aKeyName, otbrError aError)
730*4a64e381SAndroid Build Coastguard Worker {
731*4a64e381SAndroid Build Coastguard Worker     auto it = mKeyRegistrationBeginTime.find(aKeyName);
732*4a64e381SAndroid Build Coastguard Worker 
733*4a64e381SAndroid Build Coastguard Worker     if (it != mKeyRegistrationBeginTime.end())
734*4a64e381SAndroid Build Coastguard Worker     {
735*4a64e381SAndroid Build Coastguard Worker         uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count();
736*4a64e381SAndroid Build Coastguard Worker         UpdateEmaLatency(mTelemetryInfo.mKeyRegistrationEmaLatency, latency, aError);
737*4a64e381SAndroid Build Coastguard Worker         mKeyRegistrationBeginTime.erase(it);
738*4a64e381SAndroid Build Coastguard Worker     }
739*4a64e381SAndroid Build Coastguard Worker }
740*4a64e381SAndroid Build Coastguard Worker 
UpdateServiceInstanceResolutionEmaLatency(const std::string & aInstanceName,const std::string & aType,otbrError aError)741*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName,
742*4a64e381SAndroid Build Coastguard Worker                                                           const std::string &aType,
743*4a64e381SAndroid Build Coastguard Worker                                                           otbrError          aError)
744*4a64e381SAndroid Build Coastguard Worker {
745*4a64e381SAndroid Build Coastguard Worker     auto it = mServiceInstanceResolutionBeginTime.find(std::make_pair(aInstanceName, aType));
746*4a64e381SAndroid Build Coastguard Worker 
747*4a64e381SAndroid Build Coastguard Worker     if (it != mServiceInstanceResolutionBeginTime.end())
748*4a64e381SAndroid Build Coastguard Worker     {
749*4a64e381SAndroid Build Coastguard Worker         uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count();
750*4a64e381SAndroid Build Coastguard Worker         UpdateEmaLatency(mTelemetryInfo.mServiceResolutionEmaLatency, latency, aError);
751*4a64e381SAndroid Build Coastguard Worker         mServiceInstanceResolutionBeginTime.erase(it);
752*4a64e381SAndroid Build Coastguard Worker     }
753*4a64e381SAndroid Build Coastguard Worker }
754*4a64e381SAndroid Build Coastguard Worker 
UpdateHostResolutionEmaLatency(const std::string & aHostName,otbrError aError)755*4a64e381SAndroid Build Coastguard Worker void Publisher::UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError)
756*4a64e381SAndroid Build Coastguard Worker {
757*4a64e381SAndroid Build Coastguard Worker     auto it = mHostResolutionBeginTime.find(aHostName);
758*4a64e381SAndroid Build Coastguard Worker 
759*4a64e381SAndroid Build Coastguard Worker     if (it != mHostResolutionBeginTime.end())
760*4a64e381SAndroid Build Coastguard Worker     {
761*4a64e381SAndroid Build Coastguard Worker         uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count();
762*4a64e381SAndroid Build Coastguard Worker         UpdateEmaLatency(mTelemetryInfo.mHostResolutionEmaLatency, latency, aError);
763*4a64e381SAndroid Build Coastguard Worker         mHostResolutionBeginTime.erase(it);
764*4a64e381SAndroid Build Coastguard Worker     }
765*4a64e381SAndroid Build Coastguard Worker }
766*4a64e381SAndroid Build Coastguard Worker 
AddAddress(AddressList & aAddressList,const Ip6Address & aAddress)767*4a64e381SAndroid Build Coastguard Worker void Publisher::AddAddress(AddressList &aAddressList, const Ip6Address &aAddress)
768*4a64e381SAndroid Build Coastguard Worker {
769*4a64e381SAndroid Build Coastguard Worker     aAddressList.push_back(aAddress);
770*4a64e381SAndroid Build Coastguard Worker }
771*4a64e381SAndroid Build Coastguard Worker 
RemoveAddress(AddressList & aAddressList,const Ip6Address & aAddress)772*4a64e381SAndroid Build Coastguard Worker void Publisher::RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddress)
773*4a64e381SAndroid Build Coastguard Worker {
774*4a64e381SAndroid Build Coastguard Worker     auto it = std::find(aAddressList.begin(), aAddressList.end(), aAddress);
775*4a64e381SAndroid Build Coastguard Worker 
776*4a64e381SAndroid Build Coastguard Worker     if (it != aAddressList.end())
777*4a64e381SAndroid Build Coastguard Worker     {
778*4a64e381SAndroid Build Coastguard Worker         aAddressList.erase(it);
779*4a64e381SAndroid Build Coastguard Worker     }
780*4a64e381SAndroid Build Coastguard Worker }
781*4a64e381SAndroid Build Coastguard Worker 
782*4a64e381SAndroid Build Coastguard Worker } // namespace Mdns
783*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
784*4a64e381SAndroid Build Coastguard Worker 
785*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_ENABLE_MDNS
786