xref: /aosp_15_r20/external/ot-br-posix/src/sdp_proxy/discovery_proxy.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  *   The file implements the DNS-SD Discovery Proxy.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "DPROXY"
37*4a64e381SAndroid Build Coastguard Worker 
38*4a64e381SAndroid Build Coastguard Worker #include "sdp_proxy/discovery_proxy.hpp"
39*4a64e381SAndroid Build Coastguard Worker 
40*4a64e381SAndroid Build Coastguard Worker #include <algorithm>
41*4a64e381SAndroid Build Coastguard Worker #include <string>
42*4a64e381SAndroid Build Coastguard Worker 
43*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
44*4a64e381SAndroid Build Coastguard Worker 
45*4a64e381SAndroid Build Coastguard Worker #include <openthread/dnssd_server.h>
46*4a64e381SAndroid Build Coastguard Worker 
47*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
48*4a64e381SAndroid Build Coastguard Worker #include "common/dns_utils.hpp"
49*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
50*4a64e381SAndroid Build Coastguard Worker #include "utils/dns_utils.hpp"
51*4a64e381SAndroid Build Coastguard Worker #include "utils/string_utils.hpp"
52*4a64e381SAndroid Build Coastguard Worker 
53*4a64e381SAndroid Build Coastguard Worker namespace otbr {
54*4a64e381SAndroid Build Coastguard Worker namespace Dnssd {
55*4a64e381SAndroid Build Coastguard Worker 
DnsLabelsEqual(const std::string & aLabel1,const std::string & aLabel2)56*4a64e381SAndroid Build Coastguard Worker static inline bool DnsLabelsEqual(const std::string &aLabel1, const std::string &aLabel2)
57*4a64e381SAndroid Build Coastguard Worker {
58*4a64e381SAndroid Build Coastguard Worker     return StringUtils::EqualCaseInsensitive(aLabel1, aLabel2);
59*4a64e381SAndroid Build Coastguard Worker }
60*4a64e381SAndroid Build Coastguard Worker 
DiscoveryProxy(Ncp::RcpHost & aHost,Mdns::Publisher & aPublisher)61*4a64e381SAndroid Build Coastguard Worker DiscoveryProxy::DiscoveryProxy(Ncp::RcpHost &aHost, Mdns::Publisher &aPublisher)
62*4a64e381SAndroid Build Coastguard Worker     : mHost(aHost)
63*4a64e381SAndroid Build Coastguard Worker     , mMdnsPublisher(aPublisher)
64*4a64e381SAndroid Build Coastguard Worker     , mIsEnabled(false)
65*4a64e381SAndroid Build Coastguard Worker {
66*4a64e381SAndroid Build Coastguard Worker     mHost.RegisterResetHandler([this]() {
67*4a64e381SAndroid Build Coastguard Worker         otDnssdQuerySetCallbacks(mHost.GetInstance(), &DiscoveryProxy::OnDiscoveryProxySubscribe,
68*4a64e381SAndroid Build Coastguard Worker                                  &DiscoveryProxy::OnDiscoveryProxyUnsubscribe, this);
69*4a64e381SAndroid Build Coastguard Worker     });
70*4a64e381SAndroid Build Coastguard Worker }
71*4a64e381SAndroid Build Coastguard Worker 
SetEnabled(bool aIsEnabled)72*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::SetEnabled(bool aIsEnabled)
73*4a64e381SAndroid Build Coastguard Worker {
74*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(IsEnabled() != aIsEnabled);
75*4a64e381SAndroid Build Coastguard Worker     mIsEnabled = aIsEnabled;
76*4a64e381SAndroid Build Coastguard Worker     if (mIsEnabled)
77*4a64e381SAndroid Build Coastguard Worker     {
78*4a64e381SAndroid Build Coastguard Worker         Start();
79*4a64e381SAndroid Build Coastguard Worker     }
80*4a64e381SAndroid Build Coastguard Worker     else
81*4a64e381SAndroid Build Coastguard Worker     {
82*4a64e381SAndroid Build Coastguard Worker         Stop();
83*4a64e381SAndroid Build Coastguard Worker     }
84*4a64e381SAndroid Build Coastguard Worker exit:
85*4a64e381SAndroid Build Coastguard Worker     return;
86*4a64e381SAndroid Build Coastguard Worker }
87*4a64e381SAndroid Build Coastguard Worker 
Start(void)88*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::Start(void)
89*4a64e381SAndroid Build Coastguard Worker {
90*4a64e381SAndroid Build Coastguard Worker     assert(mSubscriberId == 0);
91*4a64e381SAndroid Build Coastguard Worker 
92*4a64e381SAndroid Build Coastguard Worker     otDnssdQuerySetCallbacks(mHost.GetInstance(), &DiscoveryProxy::OnDiscoveryProxySubscribe,
93*4a64e381SAndroid Build Coastguard Worker                              &DiscoveryProxy::OnDiscoveryProxyUnsubscribe, this);
94*4a64e381SAndroid Build Coastguard Worker 
95*4a64e381SAndroid Build Coastguard Worker     mSubscriberId = mMdnsPublisher.AddSubscriptionCallbacks(
96*4a64e381SAndroid Build Coastguard Worker         [this](const std::string &aType, const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) {
97*4a64e381SAndroid Build Coastguard Worker             if (!aInstanceInfo.mRemoved)
98*4a64e381SAndroid Build Coastguard Worker             {
99*4a64e381SAndroid Build Coastguard Worker                 OnServiceDiscovered(aType, aInstanceInfo);
100*4a64e381SAndroid Build Coastguard Worker             }
101*4a64e381SAndroid Build Coastguard Worker         },
102*4a64e381SAndroid Build Coastguard Worker 
103*4a64e381SAndroid Build Coastguard Worker         [this](const std::string &aHostName, const Mdns::Publisher::DiscoveredHostInfo &aHostInfo) {
104*4a64e381SAndroid Build Coastguard Worker             OnHostDiscovered(aHostName, aHostInfo);
105*4a64e381SAndroid Build Coastguard Worker         });
106*4a64e381SAndroid Build Coastguard Worker 
107*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Started");
108*4a64e381SAndroid Build Coastguard Worker }
109*4a64e381SAndroid Build Coastguard Worker 
Stop(void)110*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::Stop(void)
111*4a64e381SAndroid Build Coastguard Worker {
112*4a64e381SAndroid Build Coastguard Worker     otDnssdQuerySetCallbacks(mHost.GetInstance(), nullptr, nullptr, nullptr);
113*4a64e381SAndroid Build Coastguard Worker 
114*4a64e381SAndroid Build Coastguard Worker     if (mSubscriberId > 0)
115*4a64e381SAndroid Build Coastguard Worker     {
116*4a64e381SAndroid Build Coastguard Worker         mMdnsPublisher.RemoveSubscriptionCallbacks(mSubscriberId);
117*4a64e381SAndroid Build Coastguard Worker         mSubscriberId = 0;
118*4a64e381SAndroid Build Coastguard Worker     }
119*4a64e381SAndroid Build Coastguard Worker 
120*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Stopped");
121*4a64e381SAndroid Build Coastguard Worker }
122*4a64e381SAndroid Build Coastguard Worker 
OnDiscoveryProxySubscribe(void * aContext,const char * aFullName)123*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnDiscoveryProxySubscribe(void *aContext, const char *aFullName)
124*4a64e381SAndroid Build Coastguard Worker {
125*4a64e381SAndroid Build Coastguard Worker     reinterpret_cast<DiscoveryProxy *>(aContext)->OnDiscoveryProxySubscribe(aFullName);
126*4a64e381SAndroid Build Coastguard Worker }
127*4a64e381SAndroid Build Coastguard Worker 
OnDiscoveryProxySubscribe(const char * aFullName)128*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnDiscoveryProxySubscribe(const char *aFullName)
129*4a64e381SAndroid Build Coastguard Worker {
130*4a64e381SAndroid Build Coastguard Worker     std::string fullName(aFullName);
131*4a64e381SAndroid Build Coastguard Worker     DnsNameInfo nameInfo = SplitFullDnsName(fullName);
132*4a64e381SAndroid Build Coastguard Worker 
133*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Subscribe: %s", fullName.c_str());
134*4a64e381SAndroid Build Coastguard Worker 
135*4a64e381SAndroid Build Coastguard Worker     if (GetServiceSubscriptionCount(nameInfo) == 1)
136*4a64e381SAndroid Build Coastguard Worker     {
137*4a64e381SAndroid Build Coastguard Worker         if (nameInfo.mHostName.empty())
138*4a64e381SAndroid Build Coastguard Worker         {
139*4a64e381SAndroid Build Coastguard Worker             mMdnsPublisher.SubscribeService(nameInfo.mServiceName, nameInfo.mInstanceName);
140*4a64e381SAndroid Build Coastguard Worker         }
141*4a64e381SAndroid Build Coastguard Worker         else
142*4a64e381SAndroid Build Coastguard Worker         {
143*4a64e381SAndroid Build Coastguard Worker             mMdnsPublisher.SubscribeHost(nameInfo.mHostName);
144*4a64e381SAndroid Build Coastguard Worker         }
145*4a64e381SAndroid Build Coastguard Worker     }
146*4a64e381SAndroid Build Coastguard Worker }
147*4a64e381SAndroid Build Coastguard Worker 
OnDiscoveryProxyUnsubscribe(void * aContext,const char * aFullName)148*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnDiscoveryProxyUnsubscribe(void *aContext, const char *aFullName)
149*4a64e381SAndroid Build Coastguard Worker {
150*4a64e381SAndroid Build Coastguard Worker     reinterpret_cast<DiscoveryProxy *>(aContext)->OnDiscoveryProxyUnsubscribe(aFullName);
151*4a64e381SAndroid Build Coastguard Worker }
152*4a64e381SAndroid Build Coastguard Worker 
OnDiscoveryProxyUnsubscribe(const char * aFullName)153*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnDiscoveryProxyUnsubscribe(const char *aFullName)
154*4a64e381SAndroid Build Coastguard Worker {
155*4a64e381SAndroid Build Coastguard Worker     std::string fullName(aFullName);
156*4a64e381SAndroid Build Coastguard Worker     DnsNameInfo nameInfo = SplitFullDnsName(fullName);
157*4a64e381SAndroid Build Coastguard Worker 
158*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Unsubscribe: %s", fullName.c_str());
159*4a64e381SAndroid Build Coastguard Worker 
160*4a64e381SAndroid Build Coastguard Worker     if (GetServiceSubscriptionCount(nameInfo) == 1)
161*4a64e381SAndroid Build Coastguard Worker     {
162*4a64e381SAndroid Build Coastguard Worker         if (nameInfo.mHostName.empty())
163*4a64e381SAndroid Build Coastguard Worker         {
164*4a64e381SAndroid Build Coastguard Worker             mMdnsPublisher.UnsubscribeService(nameInfo.mServiceName, nameInfo.mInstanceName);
165*4a64e381SAndroid Build Coastguard Worker         }
166*4a64e381SAndroid Build Coastguard Worker         else
167*4a64e381SAndroid Build Coastguard Worker         {
168*4a64e381SAndroid Build Coastguard Worker             mMdnsPublisher.UnsubscribeHost(nameInfo.mHostName);
169*4a64e381SAndroid Build Coastguard Worker         }
170*4a64e381SAndroid Build Coastguard Worker     }
171*4a64e381SAndroid Build Coastguard Worker }
172*4a64e381SAndroid Build Coastguard Worker 
OnServiceDiscovered(const std::string & aType,const Mdns::Publisher::DiscoveredInstanceInfo & aInstanceInfo)173*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnServiceDiscovered(const std::string                             &aType,
174*4a64e381SAndroid Build Coastguard Worker                                          const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo)
175*4a64e381SAndroid Build Coastguard Worker {
176*4a64e381SAndroid Build Coastguard Worker     otDnssdServiceInstanceInfo instanceInfo;
177*4a64e381SAndroid Build Coastguard Worker     const otDnssdQuery        *query                 = nullptr;
178*4a64e381SAndroid Build Coastguard Worker     std::string                unescapedInstanceName = DnsUtils::UnescapeInstanceName(aInstanceInfo.mName);
179*4a64e381SAndroid Build Coastguard Worker 
180*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Service discovered: %s, instance %s hostname %s addresses %zu port %d priority %d "
181*4a64e381SAndroid Build Coastguard Worker                 "weight %d",
182*4a64e381SAndroid Build Coastguard Worker                 aType.c_str(), aInstanceInfo.mName.c_str(), aInstanceInfo.mHostName.c_str(),
183*4a64e381SAndroid Build Coastguard Worker                 aInstanceInfo.mAddresses.size(), aInstanceInfo.mPort, aInstanceInfo.mPriority, aInstanceInfo.mWeight);
184*4a64e381SAndroid Build Coastguard Worker 
185*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mAddressNum = aInstanceInfo.mAddresses.size();
186*4a64e381SAndroid Build Coastguard Worker 
187*4a64e381SAndroid Build Coastguard Worker     if (!aInstanceInfo.mAddresses.empty())
188*4a64e381SAndroid Build Coastguard Worker     {
189*4a64e381SAndroid Build Coastguard Worker         instanceInfo.mAddresses = reinterpret_cast<const otIp6Address *>(&aInstanceInfo.mAddresses[0]);
190*4a64e381SAndroid Build Coastguard Worker     }
191*4a64e381SAndroid Build Coastguard Worker     else
192*4a64e381SAndroid Build Coastguard Worker     {
193*4a64e381SAndroid Build Coastguard Worker         instanceInfo.mAddresses = nullptr;
194*4a64e381SAndroid Build Coastguard Worker     }
195*4a64e381SAndroid Build Coastguard Worker 
196*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mPort      = aInstanceInfo.mPort;
197*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mPriority  = aInstanceInfo.mPriority;
198*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mWeight    = aInstanceInfo.mWeight;
199*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mTxtLength = static_cast<uint16_t>(aInstanceInfo.mTxtData.size());
200*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mTxtData   = aInstanceInfo.mTxtData.data();
201*4a64e381SAndroid Build Coastguard Worker     instanceInfo.mTtl       = CapTtl(aInstanceInfo.mTtl);
202*4a64e381SAndroid Build Coastguard Worker 
203*4a64e381SAndroid Build Coastguard Worker     while ((query = otDnssdGetNextQuery(mHost.GetInstance(), query)) != nullptr)
204*4a64e381SAndroid Build Coastguard Worker     {
205*4a64e381SAndroid Build Coastguard Worker         std::string      instanceName;
206*4a64e381SAndroid Build Coastguard Worker         std::string      serviceName;
207*4a64e381SAndroid Build Coastguard Worker         std::string      hostName;
208*4a64e381SAndroid Build Coastguard Worker         std::string      domain;
209*4a64e381SAndroid Build Coastguard Worker         char             queryName[OT_DNS_MAX_NAME_SIZE];
210*4a64e381SAndroid Build Coastguard Worker         otDnssdQueryType type = otDnssdGetQueryTypeAndName(query, &queryName);
211*4a64e381SAndroid Build Coastguard Worker         otbrError        splitError;
212*4a64e381SAndroid Build Coastguard Worker 
213*4a64e381SAndroid Build Coastguard Worker         switch (type)
214*4a64e381SAndroid Build Coastguard Worker         {
215*4a64e381SAndroid Build Coastguard Worker         case OT_DNSSD_QUERY_TYPE_BROWSE:
216*4a64e381SAndroid Build Coastguard Worker             splitError = SplitFullServiceName(queryName, serviceName, domain);
217*4a64e381SAndroid Build Coastguard Worker             break;
218*4a64e381SAndroid Build Coastguard Worker         case OT_DNSSD_QUERY_TYPE_RESOLVE:
219*4a64e381SAndroid Build Coastguard Worker             splitError = SplitFullServiceInstanceName(queryName, instanceName, serviceName, domain);
220*4a64e381SAndroid Build Coastguard Worker             break;
221*4a64e381SAndroid Build Coastguard Worker         default:
222*4a64e381SAndroid Build Coastguard Worker             splitError = OTBR_ERROR_NOT_FOUND;
223*4a64e381SAndroid Build Coastguard Worker             break;
224*4a64e381SAndroid Build Coastguard Worker         }
225*4a64e381SAndroid Build Coastguard Worker         if (splitError != OTBR_ERROR_NONE)
226*4a64e381SAndroid Build Coastguard Worker         {
227*4a64e381SAndroid Build Coastguard Worker             // Incoming service/instance was not what current query wanted to see, move on.
228*4a64e381SAndroid Build Coastguard Worker             continue;
229*4a64e381SAndroid Build Coastguard Worker         }
230*4a64e381SAndroid Build Coastguard Worker 
231*4a64e381SAndroid Build Coastguard Worker         if (DnsLabelsEqual(serviceName, aType) &&
232*4a64e381SAndroid Build Coastguard Worker             (instanceName.empty() || DnsLabelsEqual(instanceName, unescapedInstanceName)))
233*4a64e381SAndroid Build Coastguard Worker         {
234*4a64e381SAndroid Build Coastguard Worker             std::string serviceFullName    = aType + "." + domain;
235*4a64e381SAndroid Build Coastguard Worker             std::string translatedHostName = TranslateDomain(aInstanceInfo.mHostName, domain);
236*4a64e381SAndroid Build Coastguard Worker             std::string instanceFullName   = unescapedInstanceName + "." + serviceFullName;
237*4a64e381SAndroid Build Coastguard Worker 
238*4a64e381SAndroid Build Coastguard Worker             instanceInfo.mFullName = instanceFullName.c_str();
239*4a64e381SAndroid Build Coastguard Worker             instanceInfo.mHostName = translatedHostName.c_str();
240*4a64e381SAndroid Build Coastguard Worker 
241*4a64e381SAndroid Build Coastguard Worker             otDnssdQueryHandleDiscoveredServiceInstance(mHost.GetInstance(), serviceFullName.c_str(), &instanceInfo);
242*4a64e381SAndroid Build Coastguard Worker         }
243*4a64e381SAndroid Build Coastguard Worker     }
244*4a64e381SAndroid Build Coastguard Worker }
245*4a64e381SAndroid Build Coastguard Worker 
OnHostDiscovered(const std::string & aHostName,const Mdns::Publisher::DiscoveredHostInfo & aHostInfo)246*4a64e381SAndroid Build Coastguard Worker void DiscoveryProxy::OnHostDiscovered(const std::string                         &aHostName,
247*4a64e381SAndroid Build Coastguard Worker                                       const Mdns::Publisher::DiscoveredHostInfo &aHostInfo)
248*4a64e381SAndroid Build Coastguard Worker {
249*4a64e381SAndroid Build Coastguard Worker     otDnssdHostInfo     hostInfo;
250*4a64e381SAndroid Build Coastguard Worker     const otDnssdQuery *query            = nullptr;
251*4a64e381SAndroid Build Coastguard Worker     std::string         resolvedHostName = aHostInfo.mHostName;
252*4a64e381SAndroid Build Coastguard Worker 
253*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Host discovered: %s hostname %s addresses %zu", aHostName.c_str(), aHostInfo.mHostName.c_str(),
254*4a64e381SAndroid Build Coastguard Worker                 aHostInfo.mAddresses.size());
255*4a64e381SAndroid Build Coastguard Worker 
256*4a64e381SAndroid Build Coastguard Worker     if (resolvedHostName.empty())
257*4a64e381SAndroid Build Coastguard Worker     {
258*4a64e381SAndroid Build Coastguard Worker         resolvedHostName = aHostName + ".local.";
259*4a64e381SAndroid Build Coastguard Worker     }
260*4a64e381SAndroid Build Coastguard Worker 
261*4a64e381SAndroid Build Coastguard Worker     hostInfo.mAddressNum = aHostInfo.mAddresses.size();
262*4a64e381SAndroid Build Coastguard Worker     if (!aHostInfo.mAddresses.empty())
263*4a64e381SAndroid Build Coastguard Worker     {
264*4a64e381SAndroid Build Coastguard Worker         hostInfo.mAddresses = reinterpret_cast<const otIp6Address *>(&aHostInfo.mAddresses[0]);
265*4a64e381SAndroid Build Coastguard Worker     }
266*4a64e381SAndroid Build Coastguard Worker     else
267*4a64e381SAndroid Build Coastguard Worker     {
268*4a64e381SAndroid Build Coastguard Worker         hostInfo.mAddresses = nullptr;
269*4a64e381SAndroid Build Coastguard Worker     }
270*4a64e381SAndroid Build Coastguard Worker 
271*4a64e381SAndroid Build Coastguard Worker     hostInfo.mTtl = CapTtl(aHostInfo.mTtl);
272*4a64e381SAndroid Build Coastguard Worker 
273*4a64e381SAndroid Build Coastguard Worker     while ((query = otDnssdGetNextQuery(mHost.GetInstance(), query)) != nullptr)
274*4a64e381SAndroid Build Coastguard Worker     {
275*4a64e381SAndroid Build Coastguard Worker         std::string      hostName, domain;
276*4a64e381SAndroid Build Coastguard Worker         char             queryName[OT_DNS_MAX_NAME_SIZE];
277*4a64e381SAndroid Build Coastguard Worker         otDnssdQueryType type = otDnssdGetQueryTypeAndName(query, &queryName);
278*4a64e381SAndroid Build Coastguard Worker         otbrError        splitError;
279*4a64e381SAndroid Build Coastguard Worker 
280*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(splitError);
281*4a64e381SAndroid Build Coastguard Worker 
282*4a64e381SAndroid Build Coastguard Worker         if (type != OT_DNSSD_QUERY_TYPE_RESOLVE_HOST)
283*4a64e381SAndroid Build Coastguard Worker         {
284*4a64e381SAndroid Build Coastguard Worker             continue;
285*4a64e381SAndroid Build Coastguard Worker         }
286*4a64e381SAndroid Build Coastguard Worker 
287*4a64e381SAndroid Build Coastguard Worker         splitError = SplitFullHostName(queryName, hostName, domain);
288*4a64e381SAndroid Build Coastguard Worker 
289*4a64e381SAndroid Build Coastguard Worker         if (splitError != OTBR_ERROR_NONE)
290*4a64e381SAndroid Build Coastguard Worker         {
291*4a64e381SAndroid Build Coastguard Worker             continue;
292*4a64e381SAndroid Build Coastguard Worker         }
293*4a64e381SAndroid Build Coastguard Worker 
294*4a64e381SAndroid Build Coastguard Worker         if (DnsLabelsEqual(hostName, aHostName))
295*4a64e381SAndroid Build Coastguard Worker         {
296*4a64e381SAndroid Build Coastguard Worker             std::string hostFullName = TranslateDomain(resolvedHostName, domain);
297*4a64e381SAndroid Build Coastguard Worker 
298*4a64e381SAndroid Build Coastguard Worker             otDnssdQueryHandleDiscoveredHost(mHost.GetInstance(), hostFullName.c_str(), &hostInfo);
299*4a64e381SAndroid Build Coastguard Worker         }
300*4a64e381SAndroid Build Coastguard Worker     }
301*4a64e381SAndroid Build Coastguard Worker }
302*4a64e381SAndroid Build Coastguard Worker 
TranslateDomain(const std::string & aName,const std::string & aTargetDomain)303*4a64e381SAndroid Build Coastguard Worker std::string DiscoveryProxy::TranslateDomain(const std::string &aName, const std::string &aTargetDomain)
304*4a64e381SAndroid Build Coastguard Worker {
305*4a64e381SAndroid Build Coastguard Worker     std::string targetName;
306*4a64e381SAndroid Build Coastguard Worker     std::string hostName;
307*4a64e381SAndroid Build Coastguard Worker     std::string domain;
308*4a64e381SAndroid Build Coastguard Worker 
309*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(OTBR_ERROR_NONE == SplitFullHostName(aName, hostName, domain), targetName = aName);
310*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(DnsLabelsEqual(domain, "local."), targetName = aName);
311*4a64e381SAndroid Build Coastguard Worker 
312*4a64e381SAndroid Build Coastguard Worker     targetName = hostName + "." + aTargetDomain;
313*4a64e381SAndroid Build Coastguard Worker 
314*4a64e381SAndroid Build Coastguard Worker exit:
315*4a64e381SAndroid Build Coastguard Worker     otbrLogDebug("Translate domain: %s => %s", aName.c_str(), targetName.c_str());
316*4a64e381SAndroid Build Coastguard Worker     return targetName;
317*4a64e381SAndroid Build Coastguard Worker }
318*4a64e381SAndroid Build Coastguard Worker 
GetServiceSubscriptionCount(const DnsNameInfo & aNameInfo) const319*4a64e381SAndroid Build Coastguard Worker int DiscoveryProxy::GetServiceSubscriptionCount(const DnsNameInfo &aNameInfo) const
320*4a64e381SAndroid Build Coastguard Worker {
321*4a64e381SAndroid Build Coastguard Worker     const otDnssdQuery *query = nullptr;
322*4a64e381SAndroid Build Coastguard Worker     int                 count = 0;
323*4a64e381SAndroid Build Coastguard Worker 
324*4a64e381SAndroid Build Coastguard Worker     while ((query = otDnssdGetNextQuery(mHost.GetInstance(), query)) != nullptr)
325*4a64e381SAndroid Build Coastguard Worker     {
326*4a64e381SAndroid Build Coastguard Worker         char        queryName[OT_DNS_MAX_NAME_SIZE];
327*4a64e381SAndroid Build Coastguard Worker         DnsNameInfo queryInfo;
328*4a64e381SAndroid Build Coastguard Worker 
329*4a64e381SAndroid Build Coastguard Worker         otDnssdGetQueryTypeAndName(query, &queryName);
330*4a64e381SAndroid Build Coastguard Worker         queryInfo = SplitFullDnsName(queryName);
331*4a64e381SAndroid Build Coastguard Worker 
332*4a64e381SAndroid Build Coastguard Worker         count += (DnsLabelsEqual(aNameInfo.mInstanceName, queryInfo.mInstanceName) &&
333*4a64e381SAndroid Build Coastguard Worker                   DnsLabelsEqual(aNameInfo.mServiceName, queryInfo.mServiceName) &&
334*4a64e381SAndroid Build Coastguard Worker                   DnsLabelsEqual(aNameInfo.mHostName, queryInfo.mHostName));
335*4a64e381SAndroid Build Coastguard Worker     }
336*4a64e381SAndroid Build Coastguard Worker 
337*4a64e381SAndroid Build Coastguard Worker     return count;
338*4a64e381SAndroid Build Coastguard Worker }
339*4a64e381SAndroid Build Coastguard Worker 
CapTtl(uint32_t aTtl)340*4a64e381SAndroid Build Coastguard Worker uint32_t DiscoveryProxy::CapTtl(uint32_t aTtl)
341*4a64e381SAndroid Build Coastguard Worker {
342*4a64e381SAndroid Build Coastguard Worker     return std::min(aTtl, static_cast<uint32_t>(kServiceTtlCapLimit));
343*4a64e381SAndroid Build Coastguard Worker }
344*4a64e381SAndroid Build Coastguard Worker 
345*4a64e381SAndroid Build Coastguard Worker } // namespace Dnssd
346*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
347*4a64e381SAndroid Build Coastguard Worker 
348*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
349