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