1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define TRACE_TAG TRANSPORT
18 
19 #include "transport.h"
20 
21 #ifdef _WIN32
22 #include <winsock2.h>
23 #else
24 #include <arpa/inet.h>
25 #endif
26 
27 #include <memory>
28 #include <thread>
29 #include <vector>
30 
31 #include <android-base/stringprintf.h>
32 #include <android-base/strings.h>
33 #include <dns_sd.h>
34 
35 #include "adb_client.h"
36 #include "adb_mdns.h"
37 #include "adb_trace.h"
38 #include "adb_utils.h"
39 #include "adb_wifi.h"
40 #include "client/mdns_utils.h"
41 #include "fdevent/fdevent.h"
42 #include "sysdeps.h"
43 
44 // TODO: Remove this file once openscreen has bonjour client APIs implemented.
45 namespace {
46 
47 DNSServiceRef g_service_refs[kNumADBDNSServices];
48 fdevent* g_service_ref_fdes[kNumADBDNSServices];
49 
50 // Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
51 // directly so that the socket is put through the appropriate compatibility
52 // layers to work with the rest of ADB's internal APIs.
53 int adb_DNSServiceRefSockFD(DNSServiceRef ref) {
54     return adb_register_socket(DNSServiceRefSockFD(ref));
55 }
56 #define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD
57 
58 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
59                                    uint32_t interface_index, DNSServiceErrorType error_code,
60                                    const char* hostname, const sockaddr* address, uint32_t ttl,
61                                    void* context);
62 
63 void pump_service_ref(int /*fd*/, unsigned ev, void* data) {
64     DNSServiceRef* ref = reinterpret_cast<DNSServiceRef*>(data);
65 
66     if (ev & FDE_READ) DNSServiceProcessResult(*ref);
67 }
68 
69 class AsyncServiceRef {
70   public:
71     bool Initialized() const { return initialized_; }
72 
73     void DestroyServiceRef() {
74         if (!initialized_) {
75             return;
76         }
77 
78         // Order matters here! Must destroy the fdevent first since it has a
79         // reference to |sdref_|.
80         fdevent_destroy(fde_);
81         D("DNSServiceRefDeallocate(sdref=%p)", sdref_);
82         DNSServiceRefDeallocate(sdref_);
83         initialized_ = false;
84     }
85 
86     virtual ~AsyncServiceRef() { DestroyServiceRef(); }
87 
88   protected:
89     DNSServiceRef sdref_;
90 
91     void Initialize() {
92         fde_ = fdevent_create(adb_DNSServiceRefSockFD(sdref_), pump_service_ref, &sdref_);
93         if (fde_ == nullptr) {
94             D("Unable to create fdevent");
95             return;
96         }
97         fdevent_set(fde_, FDE_READ);
98         initialized_ = true;
99     }
100 
101   private:
102     bool initialized_ = false;
103     fdevent* fde_;
104 };
105 
106 class ResolvedService : public AsyncServiceRef {
107   public:
108     virtual ~ResolvedService() = default;
109 
110     ResolvedService(const std::string& service_name, const std::string& reg_type,
111                     uint32_t interface_index, const std::string& host_target, uint16_t port,
112                     int version)
113         : service_name_(service_name),
114           reg_type_(reg_type),
115           host_target_(host_target),
116           port_(port),
117           sa_family_(0),
118           service_version_(version) {
119         /* TODO: We should be able to get IPv6 support by adding
120          * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
121          * this, we get served link-local addresses that are usually useless to
122          * connect to. What's more, we seem to /only/ get those and nothing else.
123          * If we want IPv6 in the future we'll have to figure out why.
124          */
125         DNSServiceErrorType ret = DNSServiceGetAddrInfo(
126                 &sdref_, 0, interface_index, kDNSServiceProtocol_IPv4, host_target_.c_str(),
127                 register_service_ip, reinterpret_cast<void*>(this));
128 
129         if (ret != kDNSServiceErr_NoError) {
130             D("Got %d from DNSServiceGetAddrInfo.", ret);
131         } else {
132             D("DNSServiceGetAddrInfo(sdref=%p, host_target=%s)", sdref_, host_target_.c_str());
133             Initialize();
134         }
135 
136         D("Client version: %d Service version: %d\n", clientVersion_, service_version_);
137     }
138 
139     bool ConnectSecureWifiDevice() {
140         if (!adb_wifi_is_known_host(service_name_)) {
141             LOG(INFO) << "service_name=" << service_name_ << " not in keystore";
142             return false;
143         }
144 
145         std::string response;
146         connect_device(
147                 android::base::StringPrintf("%s.%s", service_name_.c_str(), reg_type_.c_str()),
148                 &response);
149         D("Secure connect to %s regtype %s (%s:%hu) : %s", service_name_.c_str(), reg_type_.c_str(),
150           ip_addr_.c_str(), port_, response.c_str());
151         return true;
152     }
153 
154     bool RegisterIpAddress(const sockaddr* address) {
155         sa_family_ = address->sa_family;
156 
157         const void* ip_addr_data;
158         if (sa_family_ == AF_INET) {
159             ip_addr_data = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
160             addr_format_ = "%s:%hu";
161         } else if (sa_family_ == AF_INET6) {
162             ip_addr_data = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
163             addr_format_ = "[%s]:%hu";
164         } else {  // Should be impossible
165             D("mDNS resolved non-IP address.");
166             return false;
167         }
168 
169         // Winsock version requires the const cast mingw defines inet_ntop differently from msvc.
170         char ip_addr[INET6_ADDRSTRLEN] = {};
171         if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data), ip_addr, sizeof(ip_addr))) {
172             D("Could not convert IP address to string.");
173             return false;
174         }
175         ip_addr_ = ip_addr;
176 
177         return true;
178     }
179 
180     static void AddToServiceRegistry(std::unique_ptr<ResolvedService> service) {
181         // Add to the service registry before trying to auto-connect, since socket_spec_connect will
182         // check these registries for the ip address when connecting via mdns instance name.
183         auto service_index = service->service_index();
184         if (!service_index) {
185             return;
186         }
187 
188         // Remove any services with the same instance name, as it may be a stale registration.
189         RemoveDNSService(service->reg_type(), service->service_name());
190 
191         ServiceRegistry* services = nullptr;
192         switch (*service_index) {
193             case kADBTransportServiceRefIndex:
194                 services = sAdbTransportServices;
195                 break;
196             case kADBSecurePairingServiceRefIndex:
197                 services = sAdbSecurePairingServices;
198                 break;
199             case kADBSecureConnectServiceRefIndex:
200                 services = sAdbSecureConnectServices;
201                 break;
202             default:
203                 LOG(WARNING) << "No registry available for reg_type=[" << service->reg_type()
204                              << "]";
205                 return;
206         }
207 
208         services->push_back(std::move(service));
209         const auto& s = services->back();
210 
211         auto reg_type = s->reg_type();
212         auto service_name = s->service_name();
213 
214         auto ip_addr = s->ip_address();
215         auto port = s->port();
216         if (adb_DNSServiceShouldAutoConnect(reg_type, service_name)) {
217             std::string response;
218             D("Attempting to connect service_name=[%s], regtype=[%s] ip_addr=(%s:%hu)",
219               service_name.c_str(), reg_type.c_str(), ip_addr.c_str(), port);
220 
221             if (*service_index == kADBSecureConnectServiceRefIndex) {
222                 s->ConnectSecureWifiDevice();
223             } else {
224                 connect_device(android::base::StringPrintf("%s.%s", service_name.c_str(),
225                                                            reg_type.c_str()),
226                                &response);
227                 D("Connect to %s regtype %s (%s:%hu) : %s", service_name.c_str(), reg_type.c_str(),
228                   ip_addr.c_str(), port, response.c_str());
229             }
230         } else {
231             D("Not immediately connecting to service_name=[%s], regtype=[%s] ip_addr=(%s:%hu)",
232               service_name.c_str(), reg_type.c_str(), ip_addr.c_str(), port);
233         }
234     }
235 
236     std::optional<int> service_index() const {
237         return adb_DNSServiceIndexByName(reg_type_.c_str());
238     }
239 
240     const std::string& host_target() const { return host_target_; }
241 
242     const std::string& service_name() const { return service_name_; }
243 
244     const std::string& reg_type() const { return reg_type_; }
245 
246     const std::string& ip_address() const { return ip_addr_; }
247 
248     uint16_t port() const { return port_; }
249 
250     using ServiceRegistry = std::vector<std::unique_ptr<ResolvedService>>;
251 
252     // unencrypted tcp connections
253     static ServiceRegistry* sAdbTransportServices;
254 
255     static ServiceRegistry* sAdbSecurePairingServices;
256     static ServiceRegistry* sAdbSecureConnectServices;
257 
258     static void InitAdbServiceRegistries();
259 
260     static void ForEachService(const ServiceRegistry& services, const std::string& hostname,
261                                adb_secure_foreach_service_callback cb);
262 
263     static bool ConnectByServiceName(const ServiceRegistry& services,
264                                      const std::string& service_name);
265 
266     static void RemoveDNSService(const std::string& reg_type, const std::string& service_name);
267 
268   private:
269     int clientVersion_ = ADB_SECURE_CLIENT_VERSION;
270     std::string addr_format_;
271     std::string service_name_;
272     std::string reg_type_;
273     std::string host_target_;
274     const uint16_t port_;
275     int sa_family_;
276     std::string ip_addr_;
277     int service_version_;
278 };
279 
280 // static
281 ResolvedService::ServiceRegistry* ResolvedService::sAdbTransportServices = NULL;
282 
283 // static
284 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecurePairingServices = NULL;
285 
286 // static
287 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecureConnectServices = NULL;
288 
289 // static
290 void ResolvedService::InitAdbServiceRegistries() {
291     if (!sAdbTransportServices) {
292         sAdbTransportServices = new ServiceRegistry;
293     }
294     if (!sAdbSecurePairingServices) {
295         sAdbSecurePairingServices = new ServiceRegistry;
296     }
297     if (!sAdbSecureConnectServices) {
298         sAdbSecureConnectServices = new ServiceRegistry;
299     }
300 }
301 
302 // static
303 void ResolvedService::ForEachService(const ServiceRegistry& services,
304                                      const std::string& wanted_service_name,
305                                      adb_secure_foreach_service_callback cb) {
306     InitAdbServiceRegistries();
307 
308     for (const auto& service : services) {
309         auto service_name = service->service_name();
310         auto reg_type = service->reg_type();
311         auto ip = service->ip_address();
312         auto port = service->port();
313 
314         if (wanted_service_name.empty()) {
315             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
316         } else if (service_name == wanted_service_name) {
317             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
318         }
319     }
320 }
321 
322 // static
323 bool ResolvedService::ConnectByServiceName(const ServiceRegistry& services,
324                                            const std::string& service_name) {
325     InitAdbServiceRegistries();
326     for (const auto& service : services) {
327         auto wanted_name = service->service_name();
328         if (wanted_name == service_name) {
329             D("Got service_name match [%s]", wanted_name.c_str());
330             return service->ConnectSecureWifiDevice();
331         }
332     }
333     D("No registered service_names matched [%s]", service_name.c_str());
334     return false;
335 }
336 
337 // static
338 void ResolvedService::RemoveDNSService(const std::string& reg_type,
339                                        const std::string& service_name) {
340     D("%s: reg_type=[%s] service_name=[%s]", __func__, reg_type.c_str(), service_name.c_str());
341     auto index = adb_DNSServiceIndexByName(reg_type);
342     if (!index) {
343         return;
344     }
345     ServiceRegistry* services;
346     switch (*index) {
347         case kADBTransportServiceRefIndex:
348             services = sAdbTransportServices;
349             break;
350         case kADBSecurePairingServiceRefIndex:
351             services = sAdbSecurePairingServices;
352             break;
353         case kADBSecureConnectServiceRefIndex:
354             services = sAdbSecureConnectServices;
355             break;
356         default:
357             return;
358     }
359 
360     if (services->empty()) {
361         return;
362     }
363 
364     services->erase(std::remove_if(services->begin(), services->end(),
365                                    [&service_name](std::unique_ptr<ResolvedService>& service) {
366                                        return (service_name == service->service_name());
367                                    }),
368                     services->end());
369 }
370 
371 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
372                                    uint32_t /*interface_index*/, DNSServiceErrorType error_code,
373                                    const char* hostname, const sockaddr* address, uint32_t ttl,
374                                    void* context) {
375     D("%s: sdref=%p flags=0x%08x error_code=%u ttl=%u", __func__, sdref, flags, error_code, ttl);
376     std::unique_ptr<ResolvedService> data(static_cast<ResolvedService*>(context));
377     // Only resolve the address once. If the address or port changes, we'll just get another
378     // registration.
379     data->DestroyServiceRef();
380 
381     if (error_code != kDNSServiceErr_NoError) {
382         D("Got error while looking up ip_addr [%u]", error_code);
383         return;
384     }
385 
386     if (flags & kDNSServiceFlagsAdd) {
387         if (data->RegisterIpAddress(address)) {
388             D("Resolved IP address for [%s]. Adding to service registry.", hostname);
389             ResolvedService::AddToServiceRegistry(std::move(data));
390         }
391     }
392 }
393 
394 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
395                                               uint32_t interface_index,
396                                               DNSServiceErrorType error_code, const char* fullname,
397                                               const char* host_target, uint16_t port,
398                                               uint16_t txt_len, const unsigned char* txt_record,
399                                               void* context);
400 
401 class DiscoveredService : public AsyncServiceRef {
402   public:
403     DiscoveredService(uint32_t interface_index, const char* service_name, const char* regtype,
404                       const char* domain)
405         : service_name_(service_name), reg_type_(regtype) {
406         DNSServiceErrorType ret =
407                 DNSServiceResolve(&sdref_, 0, interface_index, service_name, regtype, domain,
408                                   register_resolved_mdns_service, reinterpret_cast<void*>(this));
409 
410         D("DNSServiceResolve for "
411           "interface_index %u "
412           "service_name %s "
413           "regtype %s "
414           "domain %s "
415           ": %d",
416           interface_index, service_name, regtype, domain, ret);
417 
418         if (ret == kDNSServiceErr_NoError) {
419             Initialize();
420         }
421     }
422 
423     const std::string& service_name() { return service_name_; }
424 
425     const std::string& reg_type() { return reg_type_; }
426 
427   private:
428     std::string service_name_;
429     std::string reg_type_;
430 };
431 
432 // Returns the version the device wanted to advertise,
433 // or -1 if parsing fails.
434 int ParseVersionFromTxtRecord(uint16_t txt_len, const unsigned char* txt_record) {
435     if (!txt_len) return -1;
436     if (!txt_record) return -1;
437 
438     // https://tools.ietf.org/html/rfc6763
439     // """
440     // 6.1.  General Format Rules for DNS TXT Records
441     //
442     // A DNS TXT record can be up to 65535 (0xFFFF) bytes long.  The total
443     // length is indicated by the length given in the resource record header
444     // in the DNS message.  There is no way to tell directly from the data
445     // alone how long it is (e.g., there is no length count at the start, or
446     // terminating NULL byte at the end).
447     // """
448 
449     // Let's trust the TXT record's length byte
450     // Worst case, it wastes 255 bytes
451     std::vector<char> record_str(txt_len + 1, '\0');
452     char* str = record_str.data();
453 
454     memcpy(str, txt_record + 1 /* skip the length byte */, txt_len);
455 
456     // Check if it's the version key
457     static const char* version_key = "v=";
458     size_t version_key_len = strlen(version_key);
459 
460     if (strncmp(version_key, str, version_key_len)) return -1;
461 
462     auto value_start = str + version_key_len;
463 
464     long parsed_number = strtol(value_start, 0, 10);
465 
466     // No valid conversion. Also, 0
467     // is not a valid version.
468     if (!parsed_number) return -1;
469 
470     // Outside bounds of int.
471     if (parsed_number < INT_MIN || parsed_number > INT_MAX) return -1;
472 
473     // Possibly valid version
474     return static_cast<int>(parsed_number);
475 }
476 
477 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
478                                               uint32_t interface_index,
479                                               DNSServiceErrorType error_code, const char* fullname,
480                                               const char* host_target, uint16_t port,
481                                               uint16_t txt_len, const unsigned char* txt_record,
482                                               void* context) {
483     D("Resolved a service.");
484     std::unique_ptr<DiscoveredService> discovered(reinterpret_cast<DiscoveredService*>(context));
485 
486     if (error_code != kDNSServiceErr_NoError) {
487         D("Got error %d resolving service.", error_code);
488         return;
489     }
490 
491     // TODO: Reject certain combinations of invalid or mismatched client and
492     // service versions here before creating anything.
493     // At the moment, there is nothing to reject, so accept everything
494     // as an optimistic default.
495     auto service_version = ParseVersionFromTxtRecord(txt_len, txt_record);
496 
497     auto resolved = new ResolvedService(discovered->service_name(), discovered->reg_type(),
498                                         interface_index, host_target, ntohs(port), service_version);
499 
500     if (!resolved->Initialized()) {
501         D("Unable to init resolved service");
502         delete resolved;
503     }
504 
505     if (flags) { /* Only ever equals MoreComing or 0 */
506         D("releasing discovered service");
507         discovered.release();
508     }
509 }
510 
511 void DNSSD_API on_service_browsed(DNSServiceRef sdref, DNSServiceFlags flags,
512                                   uint32_t interface_index, DNSServiceErrorType error_code,
513                                   const char* service_name, const char* regtype, const char* domain,
514                                   void* /*context*/) {
515     if (error_code != kDNSServiceErr_NoError) {
516         D("Got error %d during mDNS browse.", error_code);
517         DNSServiceRefDeallocate(sdref);
518         auto service_index = adb_DNSServiceIndexByName(regtype);
519         if (service_index) {
520             fdevent_destroy(g_service_ref_fdes[*service_index]);
521         }
522         return;
523     }
524 
525     if (flags & kDNSServiceFlagsAdd) {
526         D("%s: Discover found new service_name=[%s] regtype=[%s] domain=[%s]", __func__,
527           service_name, regtype, domain);
528         auto discovered = new DiscoveredService(interface_index, service_name, regtype, domain);
529         if (!discovered->Initialized()) {
530             delete discovered;
531         }
532     } else {
533         D("%s: Discover lost service_name=[%s] regtype=[%s] domain=[%s]", __func__, service_name,
534           regtype, domain);
535         ResolvedService::RemoveDNSService(regtype, service_name);
536     }
537 }
538 
539 void init_mdns_transport_discovery_thread(void) {
540     int error_codes[kNumADBDNSServices];
541     for (int i = 0; i < kNumADBDNSServices; ++i) {
542         error_codes[i] = DNSServiceBrowse(&g_service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
543                                           on_service_browsed, nullptr);
544 
545         if (error_codes[i] != kDNSServiceErr_NoError) {
546             D("Got %d browsing for mDNS service %s.", error_codes[i], kADBDNSServices[i]);
547         } else {
548             fdevent_run_on_main_thread([i]() {
549                 g_service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(g_service_refs[i]),
550                                                        pump_service_ref, &g_service_refs[i]);
551                 fdevent_set(g_service_ref_fdes[i], FDE_READ);
552             });
553         }
554     }
555 }
556 
557 namespace MdnsResponder {
558 
559 bool adb_secure_connect_by_service_name(const std::string& instance_name) {
560     return ResolvedService::ConnectByServiceName(*ResolvedService::sAdbSecureConnectServices,
561                                                  instance_name);
562 }
563 
564 std::string mdns_check() {
565     uint32_t daemon_version;
566     uint32_t sz = sizeof(daemon_version);
567 
568     auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
569     if (dnserr != kDNSServiceErr_NoError) {
570         return "ERROR: mdns daemon unavailable";
571     }
572 
573     return android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
574 }
575 
576 std::string mdns_list_discovered_services() {
577     std::string result;
578     auto cb = [&](const std::string& service_name, const std::string& reg_type,
579                   const std::string& ip_addr, uint16_t port) {
580         result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name.c_str(),
581                                               reg_type.c_str(), ip_addr.c_str(), port);
582     };
583 
584     ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices, "", cb);
585     ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
586     ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
587     return result;
588 }
589 
590 std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) {
591     CHECK(!name.empty());
592 
593     // only adb server creates these registries
594     if (!ResolvedService::sAdbTransportServices && !ResolvedService::sAdbSecureConnectServices) {
595         return std::nullopt;
596     }
597     CHECK(ResolvedService::sAdbTransportServices);
598     CHECK(ResolvedService::sAdbSecureConnectServices);
599 
600     auto mdns_instance = mdns::mdns_parse_instance_name(name);
601     if (!mdns_instance.has_value()) {
602         D("Failed to parse mDNS name [%s]", name.c_str());
603         return std::nullopt;
604     }
605 
606     std::optional<MdnsInfo> info;
607     auto cb = [&](const std::string& service_name, const std::string& reg_type,
608                   const std::string& ip_addr,
609                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
610 
611     std::string reg_type;
612     if (!mdns_instance->service_name.empty()) {
613         reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
614                                                mdns_instance->transport_type.c_str());
615         auto index = adb_DNSServiceIndexByName(reg_type);
616         if (!index) {
617             return std::nullopt;
618         }
619         switch (*index) {
620             case kADBTransportServiceRefIndex:
621                 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices,
622                                                 mdns_instance->instance_name, cb);
623                 break;
624             case kADBSecureConnectServiceRefIndex:
625                 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices,
626                                                 mdns_instance->instance_name, cb);
627                 break;
628             default:
629                 D("Unknown reg_type [%s]", reg_type.c_str());
630                 return std::nullopt;
631         }
632         return info;
633     }
634 
635     for (const auto& service :
636          {ResolvedService::sAdbTransportServices, ResolvedService::sAdbSecureConnectServices}) {
637         ResolvedService::ForEachService(*service, name, cb);
638         if (info.has_value()) {
639             return info;
640         }
641     }
642 
643     return std::nullopt;
644 }
645 
646 std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) {
647     CHECK(!name.empty());
648 
649     auto mdns_instance = mdns::mdns_parse_instance_name(name);
650     if (!mdns_instance.has_value()) {
651         D("Failed to parse mDNS pairing name [%s]", name.c_str());
652         return std::nullopt;
653     }
654 
655     std::optional<MdnsInfo> info;
656     auto cb = [&](const std::string& service_name, const std::string& reg_type,
657                   const std::string& ip_addr,
658                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
659 
660     // Verify it's a pairing service if user explicitly inputs it.
661     if (!mdns_instance->service_name.empty()) {
662         auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
663                                                     mdns_instance->transport_type.c_str());
664         auto index = adb_DNSServiceIndexByName(reg_type);
665         if (!index) {
666             return std::nullopt;
667         }
668         switch (*index) {
669             case kADBSecurePairingServiceRefIndex:
670                 break;
671             default:
672                 D("Not an adb pairing reg_type [%s]", reg_type.c_str());
673                 return std::nullopt;
674         }
675     }
676 
677     ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
678     return info;
679 }
680 
681 void mdns_cleanup() {}
682 
683 }  // namespace MdnsResponder
684 }  // namespace
685 
686 AdbMdnsResponderFuncs StartMdnsResponderDiscovery() {
687     ResolvedService::InitAdbServiceRegistries();
688     std::thread(init_mdns_transport_discovery_thread).detach();
689     AdbMdnsResponderFuncs f = {
690             .mdns_check = MdnsResponder::mdns_check,
691             .mdns_list_discovered_services = MdnsResponder::mdns_list_discovered_services,
692             .mdns_get_connect_service_info = MdnsResponder::mdns_get_connect_service_info,
693             .mdns_get_pairing_service_info = MdnsResponder::mdns_get_pairing_service_info,
694             .mdns_cleanup = MdnsResponder::mdns_cleanup,
695             .adb_secure_connect_by_service_name = MdnsResponder::adb_secure_connect_by_service_name,
696     };
697     return f;
698 }
699