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.
adb_DNSServiceRefSockFD(DNSServiceRef ref)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 
pump_service_ref(int,unsigned ev,void * data)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:
Initialized() const71     bool Initialized() const { return initialized_; }
72 
DestroyServiceRef()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 
~AsyncServiceRef()86     virtual ~AsyncServiceRef() { DestroyServiceRef(); }
87 
88   protected:
89     DNSServiceRef sdref_;
90 
Initialize()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 
ResolvedService(const std::string & service_name,const std::string & reg_type,uint32_t interface_index,const std::string & host_target,uint16_t port,int version)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", ADB_SECURE_CLIENT_VERSION, service_version_);
137     }
138 
ConnectSecureWifiDevice()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 
RegisterIpAddress(const sockaddr * address)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 
AddToServiceRegistry(std::unique_ptr<ResolvedService> service)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 
service_index() const236     std::optional<int> service_index() const {
237         return adb_DNSServiceIndexByName(reg_type_.c_str());
238     }
239 
service_name() const240     const std::string& service_name() const { return service_name_; }
241 
reg_type() const242     const std::string& reg_type() const { return reg_type_; }
243 
ip_address() const244     const std::string& ip_address() const { return ip_addr_; }
245 
port() const246     uint16_t port() const { return port_; }
247 
248     using ServiceRegistry = std::vector<std::unique_ptr<ResolvedService>>;
249 
250     // unencrypted tcp connections
251     static ServiceRegistry* sAdbTransportServices;
252 
253     static ServiceRegistry* sAdbSecurePairingServices;
254     static ServiceRegistry* sAdbSecureConnectServices;
255 
256     static void InitAdbServiceRegistries();
257 
258     static void ForEachService(const ServiceRegistry& services, const std::string& hostname,
259                                adb_secure_foreach_service_callback cb);
260 
261     static bool ConnectByServiceName(const ServiceRegistry& services,
262                                      const std::string& service_name);
263 
264     static void RemoveDNSService(const std::string& reg_type, const std::string& service_name);
265 
266   private:
267     std::string addr_format_;
268     std::string service_name_;
269     std::string reg_type_;
270     std::string host_target_;
271     const uint16_t port_;
272     int sa_family_;
273     std::string ip_addr_;
274     int service_version_;
275 };
276 
277 // static
278 ResolvedService::ServiceRegistry* ResolvedService::sAdbTransportServices = NULL;
279 
280 // static
281 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecurePairingServices = NULL;
282 
283 // static
284 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecureConnectServices = NULL;
285 
286 // static
InitAdbServiceRegistries()287 void ResolvedService::InitAdbServiceRegistries() {
288     if (!sAdbTransportServices) {
289         sAdbTransportServices = new ServiceRegistry;
290     }
291     if (!sAdbSecurePairingServices) {
292         sAdbSecurePairingServices = new ServiceRegistry;
293     }
294     if (!sAdbSecureConnectServices) {
295         sAdbSecureConnectServices = new ServiceRegistry;
296     }
297 }
298 
299 // static
ForEachService(const ServiceRegistry & services,const std::string & wanted_service_name,adb_secure_foreach_service_callback cb)300 void ResolvedService::ForEachService(const ServiceRegistry& services,
301                                      const std::string& wanted_service_name,
302                                      adb_secure_foreach_service_callback cb) {
303     InitAdbServiceRegistries();
304 
305     for (const auto& service : services) {
306         auto service_name = service->service_name();
307         auto reg_type = service->reg_type();
308         auto ip = service->ip_address();
309         auto port = service->port();
310 
311         if (wanted_service_name.empty()) {
312             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
313         } else if (service_name == wanted_service_name) {
314             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
315         }
316     }
317 }
318 
319 // static
ConnectByServiceName(const ServiceRegistry & services,const std::string & service_name)320 bool ResolvedService::ConnectByServiceName(const ServiceRegistry& services,
321                                            const std::string& service_name) {
322     InitAdbServiceRegistries();
323     for (const auto& service : services) {
324         auto wanted_name = service->service_name();
325         if (wanted_name == service_name) {
326             D("Got service_name match [%s]", wanted_name.c_str());
327             return service->ConnectSecureWifiDevice();
328         }
329     }
330     D("No registered service_names matched [%s]", service_name.c_str());
331     return false;
332 }
333 
334 // static
RemoveDNSService(const std::string & reg_type,const std::string & service_name)335 void ResolvedService::RemoveDNSService(const std::string& reg_type,
336                                        const std::string& service_name) {
337     D("%s: reg_type=[%s] service_name=[%s]", __func__, reg_type.c_str(), service_name.c_str());
338     auto index = adb_DNSServiceIndexByName(reg_type);
339     if (!index) {
340         return;
341     }
342     ServiceRegistry* services;
343     switch (*index) {
344         case kADBTransportServiceRefIndex:
345             services = sAdbTransportServices;
346             break;
347         case kADBSecurePairingServiceRefIndex:
348             services = sAdbSecurePairingServices;
349             break;
350         case kADBSecureConnectServiceRefIndex:
351             services = sAdbSecureConnectServices;
352             break;
353         default:
354             return;
355     }
356 
357     if (services->empty()) {
358         return;
359     }
360 
361     services->erase(std::remove_if(services->begin(), services->end(),
362                                    [&service_name](std::unique_ptr<ResolvedService>& service) {
363                                        return (service_name == service->service_name());
364                                    }),
365                     services->end());
366 }
367 
register_service_ip(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t,DNSServiceErrorType error_code,const char * hostname,const sockaddr * address,uint32_t ttl,void * context)368 void DNSSD_API register_service_ip(DNSServiceRef sdref, DNSServiceFlags flags,
369                                    uint32_t /*interface_index*/, DNSServiceErrorType error_code,
370                                    const char* hostname, const sockaddr* address, uint32_t ttl,
371                                    void* context) {
372     D("%s: sdref=%p flags=0x%08x error_code=%u ttl=%u", __func__, sdref, flags, error_code, ttl);
373     std::unique_ptr<ResolvedService> data(static_cast<ResolvedService*>(context));
374     // Only resolve the address once. If the address or port changes, we'll just get another
375     // registration.
376     data->DestroyServiceRef();
377 
378     if (error_code != kDNSServiceErr_NoError) {
379         D("Got error while looking up ip_addr [%u]", error_code);
380         return;
381     }
382 
383     if (flags & kDNSServiceFlagsAdd) {
384         if (data->RegisterIpAddress(address)) {
385             D("Resolved IP address for [%s]. Adding to service registry.", hostname);
386             ResolvedService::AddToServiceRegistry(std::move(data));
387         }
388     }
389 }
390 
391 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
392                                               uint32_t interface_index,
393                                               DNSServiceErrorType error_code, const char* fullname,
394                                               const char* host_target, uint16_t port,
395                                               uint16_t txt_len, const unsigned char* txt_record,
396                                               void* context);
397 
398 class DiscoveredService : public AsyncServiceRef {
399   public:
DiscoveredService(uint32_t interface_index,const char * service_name,const char * regtype,const char * domain)400     DiscoveredService(uint32_t interface_index, const char* service_name, const char* regtype,
401                       const char* domain)
402         : service_name_(service_name), reg_type_(regtype) {
403         DNSServiceErrorType ret =
404                 DNSServiceResolve(&sdref_, 0, interface_index, service_name, regtype, domain,
405                                   register_resolved_mdns_service, reinterpret_cast<void*>(this));
406 
407         D("DNSServiceResolve for "
408           "interface_index %u "
409           "service_name %s "
410           "regtype %s "
411           "domain %s "
412           ": %d",
413           interface_index, service_name, regtype, domain, ret);
414 
415         if (ret == kDNSServiceErr_NoError) {
416             Initialize();
417         }
418     }
419 
service_name()420     const std::string& service_name() { return service_name_; }
421 
reg_type()422     const std::string& reg_type() { return reg_type_; }
423 
424   private:
425     std::string service_name_;
426     std::string reg_type_;
427 };
428 
429 // Returns the version the device wanted to advertise,
430 // or -1 if parsing fails.
ParseVersionFromTxtRecord(uint16_t txt_len,const unsigned char * txt_record)431 int ParseVersionFromTxtRecord(uint16_t txt_len, const unsigned char* txt_record) {
432     if (!txt_len) return -1;
433     if (!txt_record) return -1;
434 
435     // https://tools.ietf.org/html/rfc6763
436     // """
437     // 6.1.  General Format Rules for DNS TXT Records
438     //
439     // A DNS TXT record can be up to 65535 (0xFFFF) bytes long.  The total
440     // length is indicated by the length given in the resource record header
441     // in the DNS message.  There is no way to tell directly from the data
442     // alone how long it is (e.g., there is no length count at the start, or
443     // terminating NULL byte at the end).
444     //
445     // The format of the data within a DNS TXT record is zero or more strings,
446     // packed together in memory without any intervening gaps or padding bytes
447     // for word alignment. The format of each constituent string within the DNS
448     // TXT record is a single length byte, followed by 0-255 bytes of text data.
449     // """
450 
451     // We only parse the first string in the record.
452     // Let's not trust the length byte (txt_record[0]).
453     // Worst case, it wastes 65,535 bytes.
454     std::vector<char> record_str(txt_len + 1, '\0');
455     char* str = record_str.data();
456 
457     memcpy(str, txt_record + 1 /* skip the length byte */, txt_len - 1);
458 
459     // Check if it's the version key
460     static const char* version_key = "v=";
461     size_t version_key_len = strlen(version_key);
462 
463     if (strncmp(version_key, str, version_key_len)) return -1;
464 
465     auto value_start = str + version_key_len;
466 
467     long parsed_number = strtol(value_start, 0, 10);
468 
469     // No valid conversion. Also, 0
470     // is not a valid version.
471     if (!parsed_number) return -1;
472 
473     // Outside bounds of int.
474     if (parsed_number < INT_MIN || parsed_number > INT_MAX) return -1;
475 
476     // Possibly valid version
477     return static_cast<int>(parsed_number);
478 }
479 
register_resolved_mdns_service(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t interface_index,DNSServiceErrorType error_code,const char * fullname,const char * host_target,uint16_t port,uint16_t txt_len,const unsigned char * txt_record,void * context)480 void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdref, DNSServiceFlags flags,
481                                               uint32_t interface_index,
482                                               DNSServiceErrorType error_code, const char* fullname,
483                                               const char* host_target, uint16_t port,
484                                               uint16_t txt_len, const unsigned char* txt_record,
485                                               void* context) {
486     D("Resolved a service.");
487     std::unique_ptr<DiscoveredService> discovered(reinterpret_cast<DiscoveredService*>(context));
488 
489     if (error_code != kDNSServiceErr_NoError) {
490         D("Got error %d resolving service.", error_code);
491         return;
492     }
493 
494     // TODO: Reject certain combinations of invalid or mismatched client and
495     // service versions here before creating anything.
496     // At the moment, there is nothing to reject, so accept everything
497     // as an optimistic default.
498     auto service_version = ParseVersionFromTxtRecord(txt_len, txt_record);
499 
500     auto resolved = new ResolvedService(discovered->service_name(), discovered->reg_type(),
501                                         interface_index, host_target, ntohs(port), service_version);
502 
503     if (!resolved->Initialized()) {
504         D("Unable to init resolved service");
505         delete resolved;
506     }
507 
508     if (flags) { /* Only ever equals MoreComing or 0 */
509         D("releasing discovered service");
510         discovered.release();
511     }
512 }
513 
on_service_browsed(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t interface_index,DNSServiceErrorType error_code,const char * service_name,const char * regtype,const char * domain,void *)514 void DNSSD_API on_service_browsed(DNSServiceRef sdref, DNSServiceFlags flags,
515                                   uint32_t interface_index, DNSServiceErrorType error_code,
516                                   const char* service_name, const char* regtype, const char* domain,
517                                   void* /*context*/) {
518     if (error_code != kDNSServiceErr_NoError) {
519         D("Got error %d during mDNS browse.", error_code);
520         DNSServiceRefDeallocate(sdref);
521         auto service_index = adb_DNSServiceIndexByName(regtype);
522         if (service_index) {
523             fdevent_destroy(g_service_ref_fdes[*service_index]);
524         }
525         return;
526     }
527 
528     if (flags & kDNSServiceFlagsAdd) {
529         D("%s: Discover found new service_name=[%s] regtype=[%s] domain=[%s]", __func__,
530           service_name, regtype, domain);
531         auto discovered = new DiscoveredService(interface_index, service_name, regtype, domain);
532         if (!discovered->Initialized()) {
533             delete discovered;
534         }
535     } else {
536         D("%s: Discover lost service_name=[%s] regtype=[%s] domain=[%s]", __func__, service_name,
537           regtype, domain);
538         ResolvedService::RemoveDNSService(regtype, service_name);
539     }
540 }
541 
init_mdns_transport_discovery_thread(void)542 void init_mdns_transport_discovery_thread(void) {
543     int error_codes[kNumADBDNSServices];
544     for (int i = 0; i < kNumADBDNSServices; ++i) {
545         error_codes[i] = DNSServiceBrowse(&g_service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
546                                           on_service_browsed, nullptr);
547 
548         if (error_codes[i] != kDNSServiceErr_NoError) {
549             D("Got %d browsing for mDNS service %s.", error_codes[i], kADBDNSServices[i]);
550         } else {
551             fdevent_run_on_looper([i]() {
552                 g_service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(g_service_refs[i]),
553                                                        pump_service_ref, &g_service_refs[i]);
554                 fdevent_set(g_service_ref_fdes[i], FDE_READ);
555             });
556         }
557     }
558 }
559 
560 namespace MdnsResponder {
561 
adb_secure_connect_by_service_name(const std::string & instance_name)562 bool adb_secure_connect_by_service_name(const std::string& instance_name) {
563     return ResolvedService::ConnectByServiceName(*ResolvedService::sAdbSecureConnectServices,
564                                                  instance_name);
565 }
566 
mdns_check()567 std::string mdns_check() {
568     uint32_t daemon_version;
569     uint32_t sz = sizeof(daemon_version);
570 
571     auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
572     if (dnserr != kDNSServiceErr_NoError) {
573         return "ERROR: mdns daemon unavailable";
574     }
575 
576     return android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
577 }
578 
mdns_list_discovered_services()579 std::string mdns_list_discovered_services() {
580     std::string result;
581     auto cb = [&](const std::string& service_name, const std::string& reg_type,
582                   const std::string& ip_addr, uint16_t port) {
583         result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name.c_str(),
584                                               reg_type.c_str(), ip_addr.c_str(), port);
585     };
586 
587     ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices, "", cb);
588     ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
589     ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
590     return result;
591 }
592 
mdns_get_connect_service_info(const std::string & name)593 std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name) {
594     CHECK(!name.empty());
595 
596     // only adb server creates these registries
597     if (!ResolvedService::sAdbTransportServices && !ResolvedService::sAdbSecureConnectServices) {
598         return std::nullopt;
599     }
600     CHECK(ResolvedService::sAdbTransportServices);
601     CHECK(ResolvedService::sAdbSecureConnectServices);
602 
603     auto mdns_instance = mdns::mdns_parse_instance_name(name);
604     if (!mdns_instance.has_value()) {
605         D("Failed to parse mDNS name [%s]", name.c_str());
606         return std::nullopt;
607     }
608 
609     std::optional<MdnsInfo> info;
610     auto cb = [&](const std::string& service_name, const std::string& reg_type,
611                   const std::string& ip_addr,
612                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
613 
614     std::string reg_type;
615     if (!mdns_instance->service_name.empty()) {
616         reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
617                                                mdns_instance->transport_type.c_str());
618         auto index = adb_DNSServiceIndexByName(reg_type);
619         if (!index) {
620             return std::nullopt;
621         }
622         switch (*index) {
623             case kADBTransportServiceRefIndex:
624                 ResolvedService::ForEachService(*ResolvedService::sAdbTransportServices,
625                                                 mdns_instance->instance_name, cb);
626                 break;
627             case kADBSecureConnectServiceRefIndex:
628                 ResolvedService::ForEachService(*ResolvedService::sAdbSecureConnectServices,
629                                                 mdns_instance->instance_name, cb);
630                 break;
631             default:
632                 D("Unknown reg_type [%s]", reg_type.c_str());
633                 return std::nullopt;
634         }
635         return info;
636     }
637 
638     for (const auto& service :
639          {ResolvedService::sAdbTransportServices, ResolvedService::sAdbSecureConnectServices}) {
640         ResolvedService::ForEachService(*service, name, cb);
641         if (info.has_value()) {
642             return info;
643         }
644     }
645 
646     return std::nullopt;
647 }
648 
mdns_get_pairing_service_info(const std::string & name)649 std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name) {
650     CHECK(!name.empty());
651 
652     auto mdns_instance = mdns::mdns_parse_instance_name(name);
653     if (!mdns_instance.has_value()) {
654         D("Failed to parse mDNS pairing name [%s]", name.c_str());
655         return std::nullopt;
656     }
657 
658     std::optional<MdnsInfo> info;
659     auto cb = [&](const std::string& service_name, const std::string& reg_type,
660                   const std::string& ip_addr,
661                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
662 
663     // Verify it's a pairing service if user explicitly inputs it.
664     if (!mdns_instance->service_name.empty()) {
665         auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.c_str(),
666                                                     mdns_instance->transport_type.c_str());
667         auto index = adb_DNSServiceIndexByName(reg_type);
668         if (!index) {
669             return std::nullopt;
670         }
671         switch (*index) {
672             case kADBSecurePairingServiceRefIndex:
673                 break;
674             default:
675                 D("Not an adb pairing reg_type [%s]", reg_type.c_str());
676                 return std::nullopt;
677         }
678     }
679 
680     ResolvedService::ForEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
681     return info;
682 }
683 
mdns_cleanup()684 void mdns_cleanup() {}
685 
686 }  // namespace MdnsResponder
687 }  // namespace
688 
StartMdnsResponderDiscovery()689 AdbMdnsResponderFuncs StartMdnsResponderDiscovery() {
690     ResolvedService::InitAdbServiceRegistries();
691     std::thread(init_mdns_transport_discovery_thread).detach();
692     AdbMdnsResponderFuncs f = {
693             .mdns_check = MdnsResponder::mdns_check,
694             .mdns_list_discovered_services = MdnsResponder::mdns_list_discovered_services,
695             .mdns_get_connect_service_info = MdnsResponder::mdns_get_connect_service_info,
696             .mdns_get_pairing_service_info = MdnsResponder::mdns_get_pairing_service_info,
697             .mdns_cleanup = MdnsResponder::mdns_cleanup,
698             .adb_secure_connect_by_service_name = MdnsResponder::adb_secure_connect_by_service_name,
699     };
700     return f;
701 }
702