1 /*
2  * Copyright (C) 2016 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 <unordered_set>
30 #include <vector>
31 
32 #include <android-base/stringprintf.h>
33 #include <android-base/strings.h>
34 #include <dns_sd.h>
35 
36 #include "adb_client.h"
37 #include "adb_mdns.h"
38 #include "adb_trace.h"
39 #include "adb_utils.h"
40 #include "adb_wifi.h"
41 #include "client/mdns_utils.h"
42 #include "fdevent/fdevent.h"
43 #include "sysdeps.h"
44 
45 static DNSServiceRef service_refs[kNumADBDNSServices];
46 static fdevent* service_ref_fdes[kNumADBDNSServices];
47 static auto& g_autoconn_whitelist = *new std::unordered_set<int>();
48 
adb_DNSServiceIndexByName(std::string_view regType)49 static int adb_DNSServiceIndexByName(std::string_view regType) {
50     for (int i = 0; i < kNumADBDNSServices; ++i) {
51         if (!strncmp(regType.data(), kADBDNSServices[i], strlen(kADBDNSServices[i]))) {
52             return i;
53         }
54     }
55     return -1;
56 }
57 
config_auto_connect_services()58 static void config_auto_connect_services() {
59     // ADB_MDNS_AUTO_CONNECT is a comma-delimited list of mdns services
60     // that are allowed to auto-connect. By default, only allow "adb-tls-connect"
61     // to auto-connect, since this is filtered down to auto-connect only to paired
62     // devices.
63     g_autoconn_whitelist.insert(kADBSecureConnectServiceRefIndex);
64     const char* srvs = getenv("ADB_MDNS_AUTO_CONNECT");
65     if (!srvs) {
66         return;
67     }
68 
69     if (strcmp(srvs, "0") == 0) {
70         D("Disabling all auto-connecting");
71         g_autoconn_whitelist.clear();
72         return;
73     }
74 
75     if (strcmp(srvs, "1") == 0) {
76         D("Allow all auto-connecting");
77         g_autoconn_whitelist.insert(kADBTransportServiceRefIndex);
78         return;
79     }
80 
81     // Selectively choose which services to allow auto-connect.
82     // E.g. ADB_MDNS_AUTO_CONNECT=adb,adb-tls-connect would allow
83     // _adb._tcp and _adb-tls-connnect._tcp services to auto-connect.
84     auto srvs_list = android::base::Split(srvs, ",");
85     std::unordered_set<int> new_whitelist;
86     for (const auto& item : srvs_list) {
87         auto full_srv = android::base::StringPrintf("_%s._tcp", item.data());
88         int idx = adb_DNSServiceIndexByName(full_srv);
89         if (idx >= 0) {
90             new_whitelist.insert(idx);
91         }
92     }
93 
94     if (!new_whitelist.empty()) {
95         g_autoconn_whitelist = std::move(new_whitelist);
96     }
97 }
98 
adb_DNSServiceShouldAutoConnect(const char * regType,const char * serviceName)99 static bool adb_DNSServiceShouldAutoConnect(const char* regType, const char* serviceName) {
100     // Try to auto-connect to any "_adb" or "_adb-tls-connect" services excluding emulator services.
101     int index = adb_DNSServiceIndexByName(regType);
102     if (index != kADBTransportServiceRefIndex && index != kADBSecureConnectServiceRefIndex) {
103         return false;
104     }
105     if (g_autoconn_whitelist.find(index) == g_autoconn_whitelist.end()) {
106         D("Auto-connect for regType '%s' disabled", regType);
107         return false;
108     }
109     // Ignore adb-EMULATOR* service names, as it interferes with the
110     // emulator ports that are already connected.
111     if (android::base::StartsWith(serviceName, "adb-EMULATOR")) {
112         LOG(INFO) << "Ignoring emulator transport service [" << serviceName << "]";
113         return false;
114     }
115     return true;
116 }
117 
118 // Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
119 // directly so that the socket is put through the appropriate compatibility
120 // layers to work with the rest of ADB's internal APIs.
adb_DNSServiceRefSockFD(DNSServiceRef ref)121 static inline int adb_DNSServiceRefSockFD(DNSServiceRef ref) {
122     return adb_register_socket(DNSServiceRefSockFD(ref));
123 }
124 #define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD
125 
126 static void DNSSD_API register_service_ip(DNSServiceRef sdRef,
127                                           DNSServiceFlags flags,
128                                           uint32_t interfaceIndex,
129                                           DNSServiceErrorType errorCode,
130                                           const char* hostname,
131                                           const sockaddr* address,
132                                           uint32_t ttl,
133                                           void* context);
134 
pump_service_ref(int,unsigned ev,void * data)135 static void pump_service_ref(int /*fd*/, unsigned ev, void* data) {
136     DNSServiceRef* ref = reinterpret_cast<DNSServiceRef*>(data);
137 
138     if (ev & FDE_READ)
139         DNSServiceProcessResult(*ref);
140 }
141 
142 class AsyncServiceRef {
143   public:
Initialized()144     bool Initialized() {
145         return initialized_;
146     }
147 
DestroyServiceRef()148     void DestroyServiceRef() {
149         if (!initialized_) {
150             return;
151         }
152 
153         // Order matters here! Must destroy the fdevent first since it has a
154         // reference to |sdRef_|.
155         fdevent_destroy(fde_);
156         D("DNSServiceRefDeallocate(sdRef=%p)", sdRef_);
157         DNSServiceRefDeallocate(sdRef_);
158         initialized_ = false;
159     }
160 
~AsyncServiceRef()161     virtual ~AsyncServiceRef() { DestroyServiceRef(); }
162 
163   protected:
164     DNSServiceRef sdRef_;
165 
Initialize()166     void Initialize() {
167         fde_ = fdevent_create(adb_DNSServiceRefSockFD(sdRef_), pump_service_ref, &sdRef_);
168         if (fde_ == nullptr) {
169             D("Unable to create fdevent");
170             return;
171         }
172         fdevent_set(fde_, FDE_READ);
173         initialized_ = true;
174     }
175 
176   private:
177     bool initialized_ = false;
178     fdevent* fde_;
179 };
180 
181 class ResolvedService : public AsyncServiceRef {
182   public:
183     virtual ~ResolvedService() = default;
184 
ResolvedService(std::string serviceName,std::string regType,uint32_t interfaceIndex,const char * hosttarget,uint16_t port,int version)185     ResolvedService(std::string serviceName, std::string regType, uint32_t interfaceIndex,
186                     const char* hosttarget, uint16_t port, int version)
187         : serviceName_(serviceName),
188           regType_(regType),
189           hosttarget_(hosttarget),
190           port_(port),
191           sa_family_(0),
192           ip_addr_data_(NULL),
193           serviceVersion_(version) {
194         memset(ip_addr_, 0, sizeof(ip_addr_));
195 
196         /* TODO: We should be able to get IPv6 support by adding
197          * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
198          * this, we get served link-local addresses that are usually useless to
199          * connect to. What's more, we seem to /only/ get those and nothing else.
200          * If we want IPv6 in the future we'll have to figure out why.
201          */
202         DNSServiceErrorType ret =
203             DNSServiceGetAddrInfo(
204                 &sdRef_, 0, interfaceIndex,
205                 kDNSServiceProtocol_IPv4, hosttarget,
206                 register_service_ip, reinterpret_cast<void*>(this));
207 
208         if (ret != kDNSServiceErr_NoError) {
209             D("Got %d from DNSServiceGetAddrInfo.", ret);
210         } else {
211             D("DNSServiceGetAddrInfo(sdRef=%p, hosttarget=%s)", sdRef_, hosttarget);
212             Initialize();
213         }
214 
215         D("Client version: %d Service version: %d\n", clientVersion_, serviceVersion_);
216     }
217 
ConnectSecureWifiDevice()218     bool ConnectSecureWifiDevice() {
219         if (!adb_wifi_is_known_host(serviceName_)) {
220             LOG(INFO) << "serviceName=" << serviceName_ << " not in keystore";
221             return false;
222         }
223 
224         std::string response;
225         connect_device(android::base::StringPrintf("%s.%s", serviceName_.c_str(), regType_.c_str()),
226                        &response);
227         D("Secure connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
228           ip_addr_, port_, response.c_str());
229         return true;
230     }
231 
AddToServiceRegistry(const sockaddr * address)232     bool AddToServiceRegistry(const sockaddr* address) {
233         sa_family_ = address->sa_family;
234 
235         if (sa_family_ == AF_INET) {
236             ip_addr_data_ = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
237             addr_format_ = "%s:%hu";
238         } else if (sa_family_ == AF_INET6) {
239             ip_addr_data_ = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
240             addr_format_ = "[%s]:%hu";
241         } else {  // Should be impossible
242             D("mDNS resolved non-IP address.");
243             return false;
244         }
245 
246         // Winsock version requires the const cast Because Microsoft.
247         if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data_), ip_addr_, sizeof(ip_addr_))) {
248             D("Could not convert IP address to string.");
249             return false;
250         }
251 
252         // Remove any services with the same instance name, as it may be a stale registration.
253         removeDNSService(regType_.c_str(), serviceName_.c_str());
254 
255         // Add to the service registry before trying to auto-connect, since socket_spec_connect will
256         // check these registries for the ip address when connecting via mdns instance name.
257         int adbSecureServiceType = serviceIndex();
258         ServiceRegistry* services = nullptr;
259         switch (adbSecureServiceType) {
260             case kADBTransportServiceRefIndex:
261                 services = sAdbTransportServices;
262                 break;
263             case kADBSecurePairingServiceRefIndex:
264                 services = sAdbSecurePairingServices;
265                 break;
266             case kADBSecureConnectServiceRefIndex:
267                 services = sAdbSecureConnectServices;
268                 break;
269             default:
270                 LOG(WARNING) << "No registry available for reg_type=[" << regType_ << "]";
271                 return false;
272         }
273 
274         services->push_back(std::unique_ptr<ResolvedService>(this));
275 
276         if (adb_DNSServiceShouldAutoConnect(regType_.c_str(), serviceName_.c_str())) {
277             std::string response;
278             D("Attempting to connect serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)",
279               serviceName_.c_str(), regType_.c_str(), ip_addr_, port_);
280             int index = adb_DNSServiceIndexByName(regType_.c_str());
281             if (index == kADBSecureConnectServiceRefIndex) {
282                 ConnectSecureWifiDevice();
283             } else {
284                 connect_device(android::base::StringPrintf("%s.%s", serviceName_.c_str(),
285                                                            regType_.c_str()),
286                                &response);
287                 D("Connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
288                   ip_addr_, port_, response.c_str());
289             }
290         } else {
291             D("Not immediately connecting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)",
292               serviceName_.c_str(), regType_.c_str(), ip_addr_, port_);
293         }
294 
295         return true;
296     }
297 
serviceIndex() const298     int serviceIndex() const { return adb_DNSServiceIndexByName(regType_.c_str()); }
299 
hostTarget() const300     std::string hostTarget() const { return hosttarget_; }
301 
serviceName() const302     std::string serviceName() const { return serviceName_; }
303 
regType() const304     std::string regType() const { return regType_; }
305 
ipAddress() const306     std::string ipAddress() const { return ip_addr_; }
307 
port() const308     uint16_t port() const { return port_; }
309 
310     using ServiceRegistry = std::vector<std::unique_ptr<ResolvedService>>;
311 
312     // unencrypted tcp connections
313     static ServiceRegistry* sAdbTransportServices;
314 
315     static ServiceRegistry* sAdbSecurePairingServices;
316     static ServiceRegistry* sAdbSecureConnectServices;
317 
318     static void initAdbServiceRegistries();
319 
320     static void forEachService(const ServiceRegistry& services, std::string_view hostname,
321                                adb_secure_foreach_service_callback cb);
322 
323     static bool connectByServiceName(const ServiceRegistry& services,
324                                      const std::string& service_name);
325 
326     static void removeDNSService(const char* regType, const char* serviceName);
327 
328   private:
329     int clientVersion_ = ADB_SECURE_CLIENT_VERSION;
330     std::string addr_format_;
331     std::string serviceName_;
332     std::string regType_;
333     std::string hosttarget_;
334     const uint16_t port_;
335     int sa_family_;
336     const void* ip_addr_data_;
337     char ip_addr_[INET6_ADDRSTRLEN];
338     int serviceVersion_;
339 };
340 
341 // static
342 ResolvedService::ServiceRegistry* ResolvedService::sAdbTransportServices = NULL;
343 
344 // static
345 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecurePairingServices = NULL;
346 
347 // static
348 ResolvedService::ServiceRegistry* ResolvedService::sAdbSecureConnectServices = NULL;
349 
350 // static
initAdbServiceRegistries()351 void ResolvedService::initAdbServiceRegistries() {
352     if (!sAdbTransportServices) {
353         sAdbTransportServices = new ServiceRegistry;
354     }
355     if (!sAdbSecurePairingServices) {
356         sAdbSecurePairingServices = new ServiceRegistry;
357     }
358     if (!sAdbSecureConnectServices) {
359         sAdbSecureConnectServices = new ServiceRegistry;
360     }
361 }
362 
363 // static
forEachService(const ServiceRegistry & services,std::string_view wanted_service_name,adb_secure_foreach_service_callback cb)364 void ResolvedService::forEachService(const ServiceRegistry& services,
365                                      std::string_view wanted_service_name,
366                                      adb_secure_foreach_service_callback cb) {
367     initAdbServiceRegistries();
368 
369     for (const auto& service : services) {
370         auto service_name = service->serviceName();
371         auto reg_type = service->regType();
372         auto ip = service->ipAddress();
373         auto port = service->port();
374 
375         if (wanted_service_name.empty()) {
376             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
377         } else if (service_name == wanted_service_name) {
378             cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
379         }
380     }
381 }
382 
383 // static
connectByServiceName(const ServiceRegistry & services,const std::string & service_name)384 bool ResolvedService::connectByServiceName(const ServiceRegistry& services,
385                                            const std::string& service_name) {
386     initAdbServiceRegistries();
387     for (const auto& service : services) {
388         if (service_name == service->serviceName()) {
389             D("Got service_name match [%s]", service->serviceName().c_str());
390             return service->ConnectSecureWifiDevice();
391         }
392     }
393     D("No registered serviceNames matched [%s]", service_name.c_str());
394     return false;
395 }
396 
397 // static
removeDNSService(const char * regType,const char * serviceName)398 void ResolvedService::removeDNSService(const char* regType, const char* serviceName) {
399     D("%s: regType=[%s] serviceName=[%s]", __func__, regType, serviceName);
400     int index = adb_DNSServiceIndexByName(regType);
401     ServiceRegistry* services;
402     switch (index) {
403         case kADBTransportServiceRefIndex:
404             services = sAdbTransportServices;
405             break;
406         case kADBSecurePairingServiceRefIndex:
407             services = sAdbSecurePairingServices;
408             break;
409         case kADBSecureConnectServiceRefIndex:
410             services = sAdbSecureConnectServices;
411             break;
412         default:
413             return;
414     }
415 
416     if (services->empty()) {
417         return;
418     }
419 
420     std::string sName(serviceName);
421     services->erase(std::remove_if(services->begin(), services->end(),
422                                    [&sName](std::unique_ptr<ResolvedService>& service) {
423                                        return (sName == service->serviceName());
424                                    }),
425                     services->end());
426 }
427 
adb_secure_foreach_pairing_service(const char * service_name,adb_secure_foreach_service_callback cb)428 void adb_secure_foreach_pairing_service(const char* service_name,
429                                         adb_secure_foreach_service_callback cb) {
430     ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices, service_name, cb);
431 }
432 
adb_secure_foreach_connect_service(const char * service_name,adb_secure_foreach_service_callback cb)433 void adb_secure_foreach_connect_service(const char* service_name,
434                                         adb_secure_foreach_service_callback cb) {
435     ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices, service_name, cb);
436 }
437 
adb_secure_connect_by_service_name(const char * service_name)438 bool adb_secure_connect_by_service_name(const char* service_name) {
439     return ResolvedService::connectByServiceName(*ResolvedService::sAdbSecureConnectServices,
440                                                  service_name);
441 }
442 
register_service_ip(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t,DNSServiceErrorType errorCode,const char * hostname,const sockaddr * address,uint32_t ttl,void * context)443 static void DNSSD_API register_service_ip(DNSServiceRef sdRef, DNSServiceFlags flags,
444                                           uint32_t /*interfaceIndex*/,
445                                           DNSServiceErrorType errorCode, const char* hostname,
446                                           const sockaddr* address, uint32_t ttl, void* context) {
447     D("%s: sdRef=%p flags=0x%08x errorCode=%u ttl=%u", __func__, sdRef, flags, errorCode, ttl);
448     std::unique_ptr<ResolvedService> data(
449         reinterpret_cast<ResolvedService*>(context));
450     // Only resolve the address once. If the address or port changes, we'll just get another
451     // registration.
452     data->DestroyServiceRef();
453 
454     if (errorCode != kDNSServiceErr_NoError) {
455         D("Got error while looking up ipaddr [%u]", errorCode);
456         return;
457     }
458 
459     if (flags & kDNSServiceFlagsAdd) {
460         D("Resolved IP address for [%s]. Adding to service registry.", hostname);
461         auto* ptr = data.release();
462         if (!ptr->AddToServiceRegistry(address)) {
463             data.reset(ptr);
464         }
465     }
466 }
467 
468 static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
469                                                      DNSServiceFlags flags,
470                                                      uint32_t interfaceIndex,
471                                                      DNSServiceErrorType errorCode,
472                                                      const char* fullname,
473                                                      const char* hosttarget,
474                                                      uint16_t port,
475                                                      uint16_t txtLen,
476                                                      const unsigned char* txtRecord,
477                                                      void* context);
478 
479 class DiscoveredService : public AsyncServiceRef {
480   public:
DiscoveredService(uint32_t interfaceIndex,const char * serviceName,const char * regtype,const char * domain)481     DiscoveredService(uint32_t interfaceIndex, const char* serviceName, const char* regtype,
482                       const char* domain)
483         : serviceName_(serviceName), regType_(regtype) {
484         DNSServiceErrorType ret =
485             DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype,
486                               domain, register_resolved_mdns_service,
487                               reinterpret_cast<void*>(this));
488 
489         D("DNSServiceResolve for "
490           "interfaceIndex %u "
491           "serviceName %s "
492           "regtype %s "
493           "domain %s "
494           ": %d",
495           interfaceIndex, serviceName, regtype, domain, ret);
496 
497         if (ret == kDNSServiceErr_NoError) {
498             Initialize();
499         }
500     }
501 
ServiceName()502     const char* ServiceName() {
503         return serviceName_.c_str();
504     }
505 
RegType()506     const char* RegType() { return regType_.c_str(); }
507 
508   private:
509     std::string serviceName_;
510     std::string regType_;
511 };
512 
513 // Returns the version the device wanted to advertise,
514 // or -1 if parsing fails.
parse_version_from_txt_record(uint16_t txtLen,const unsigned char * txtRecord)515 static int parse_version_from_txt_record(uint16_t txtLen, const unsigned char* txtRecord) {
516     if (!txtLen) return -1;
517     if (!txtRecord) return -1;
518 
519     // https://tools.ietf.org/html/rfc6763
520     // """
521     // 6.1.  General Format Rules for DNS TXT Records
522     //
523     // A DNS TXT record can be up to 65535 (0xFFFF) bytes long.  The total
524     // length is indicated by the length given in the resource record header
525     // in the DNS message.  There is no way to tell directly from the data
526     // alone how long it is (e.g., there is no length count at the start, or
527     // terminating NULL byte at the end).
528     // """
529 
530     // Let's trust the TXT record's length byte
531     // Worst case, it wastes 255 bytes
532     std::vector<char> recordAsString(txtLen + 1, '\0');
533     char* str = recordAsString.data();
534 
535     memcpy(str, txtRecord + 1 /* skip the length byte */, txtLen);
536 
537     // Check if it's the version key
538     static const char* versionKey = "v=";
539     size_t versionKeyLen = strlen(versionKey);
540 
541     if (strncmp(versionKey, str, versionKeyLen)) return -1;
542 
543     auto valueStart = str + versionKeyLen;
544 
545     long parsedNumber = strtol(valueStart, 0, 10);
546 
547     // No valid conversion. Also, 0
548     // is not a valid version.
549     if (!parsedNumber) return -1;
550 
551     // Outside bounds of long.
552     if (parsedNumber == LONG_MIN || parsedNumber == LONG_MAX) return -1;
553 
554     // Possibly valid version
555     return static_cast<int>(parsedNumber);
556 }
557 
register_resolved_mdns_service(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * fullname,const char * hosttarget,uint16_t port,uint16_t txtLen,const unsigned char * txtRecord,void * context)558 static void DNSSD_API register_resolved_mdns_service(
559         DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
560         DNSServiceErrorType errorCode, const char* fullname, const char* hosttarget, uint16_t port,
561         uint16_t txtLen, const unsigned char* txtRecord, void* context) {
562     D("Resolved a service.");
563     std::unique_ptr<DiscoveredService> discovered(
564         reinterpret_cast<DiscoveredService*>(context));
565 
566     if (errorCode != kDNSServiceErr_NoError) {
567         D("Got error %d resolving service.", errorCode);
568         return;
569     }
570 
571     // TODO: Reject certain combinations of invalid or mismatched client and
572     // service versions here before creating anything.
573     // At the moment, there is nothing to reject, so accept everything
574     // as an optimistic default.
575     auto serviceVersion = parse_version_from_txt_record(txtLen, txtRecord);
576 
577     auto resolved = new ResolvedService(discovered->ServiceName(), discovered->RegType(),
578                                         interfaceIndex, hosttarget, ntohs(port), serviceVersion);
579 
580     if (! resolved->Initialized()) {
581         D("Unable to init resolved service");
582         delete resolved;
583     }
584 
585     if (flags) { /* Only ever equals MoreComing or 0 */
586         D("releasing discovered service");
587         discovered.release();
588     }
589 }
590 
on_service_browsed(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * serviceName,const char * regtype,const char * domain,void *)591 static void DNSSD_API on_service_browsed(DNSServiceRef sdRef, DNSServiceFlags flags,
592                                          uint32_t interfaceIndex, DNSServiceErrorType errorCode,
593                                          const char* serviceName, const char* regtype,
594                                          const char* domain, void* /*context*/) {
595     if (errorCode != kDNSServiceErr_NoError) {
596         D("Got error %d during mDNS browse.", errorCode);
597         DNSServiceRefDeallocate(sdRef);
598         int serviceIndex = adb_DNSServiceIndexByName(regtype);
599         if (serviceIndex != -1) {
600             fdevent_destroy(service_ref_fdes[serviceIndex]);
601         }
602         return;
603     }
604 
605     if (flags & kDNSServiceFlagsAdd) {
606         D("%s: Discover found new serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
607           regtype, domain);
608         auto discovered = new DiscoveredService(interfaceIndex, serviceName, regtype, domain);
609         if (!discovered->Initialized()) {
610             delete discovered;
611         }
612     } else {
613         D("%s: Discover lost serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
614           regtype, domain);
615         ResolvedService::removeDNSService(regtype, serviceName);
616     }
617 }
618 
init_mdns_transport_discovery_thread(void)619 void init_mdns_transport_discovery_thread(void) {
620     config_auto_connect_services();
621     std::string res;
622     std::for_each(g_autoconn_whitelist.begin(), g_autoconn_whitelist.end(), [&](const int& i) {
623         res += kADBDNSServices[i];
624         res += ",";
625     });
626     D("mdns auto-connect whitelist: [%s]", res.data());
627 
628     int errorCodes[kNumADBDNSServices];
629     for (int i = 0; i < kNumADBDNSServices; ++i) {
630         errorCodes[i] = DNSServiceBrowse(&service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
631                                          on_service_browsed, nullptr);
632 
633         if (errorCodes[i] != kDNSServiceErr_NoError) {
634             D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]);
635         }
636 
637         if (errorCodes[i] == kDNSServiceErr_NoError) {
638             fdevent_run_on_main_thread([i]() {
639                 service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(service_refs[i]),
640                                                      pump_service_ref, &service_refs[i]);
641                 fdevent_set(service_ref_fdes[i], FDE_READ);
642             });
643         }
644     }
645 }
646 
init_mdns_transport_discovery(void)647 void init_mdns_transport_discovery(void) {
648     ResolvedService::initAdbServiceRegistries();
649     std::thread(init_mdns_transport_discovery_thread).detach();
650 }
651 
mdns_check()652 std::string mdns_check() {
653     uint32_t daemon_version;
654     uint32_t sz = sizeof(daemon_version);
655 
656     auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
657     std::string result = "ERROR: mdns daemon unavailable";
658     if (dnserr != kDNSServiceErr_NoError) {
659         return result;
660     }
661 
662     result = android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
663     return result;
664 }
665 
mdns_list_discovered_services()666 std::string mdns_list_discovered_services() {
667     std::string result;
668     auto cb = [&](const char* service_name, const char* reg_type, const char* ip_addr,
669                   uint16_t port) {
670         result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name, reg_type, ip_addr,
671                                               port);
672     };
673 
674     ResolvedService::forEachService(*ResolvedService::sAdbTransportServices, "", cb);
675     ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
676     ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
677     return result;
678 }
679 
mdns_get_connect_service_info(std::string_view name)680 std::optional<MdnsInfo> mdns_get_connect_service_info(std::string_view name) {
681     CHECK(!name.empty());
682 
683     // only adb server creates these registries
684     if (!ResolvedService::sAdbTransportServices && !ResolvedService::sAdbSecureConnectServices) {
685         return std::nullopt;
686     }
687     CHECK(ResolvedService::sAdbTransportServices);
688     CHECK(ResolvedService::sAdbSecureConnectServices);
689 
690     auto mdns_instance = mdns::mdns_parse_instance_name(name);
691     if (!mdns_instance.has_value()) {
692         D("Failed to parse mDNS name [%s]", name.data());
693         return std::nullopt;
694     }
695 
696     std::optional<MdnsInfo> info;
697     auto cb = [&](const char* service_name, const char* reg_type, const char* ip_addr,
698                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
699 
700     std::string reg_type;
701     if (!mdns_instance->service_name.empty()) {
702         reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(),
703                                                mdns_instance->transport_type.data());
704         int index = adb_DNSServiceIndexByName(reg_type);
705         switch (index) {
706             case kADBTransportServiceRefIndex:
707                 ResolvedService::forEachService(*ResolvedService::sAdbTransportServices,
708                                                 mdns_instance->instance_name, cb);
709                 break;
710             case kADBSecureConnectServiceRefIndex:
711                 ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices,
712                                                 mdns_instance->instance_name, cb);
713                 break;
714             default:
715                 D("Unknown reg_type [%s]", reg_type.data());
716                 return std::nullopt;
717         }
718         return info;
719     }
720 
721     for (const auto& service :
722          {ResolvedService::sAdbTransportServices, ResolvedService::sAdbSecureConnectServices}) {
723         ResolvedService::forEachService(*service, name, cb);
724         if (info.has_value()) {
725             return info;
726         }
727     }
728 
729     return std::nullopt;
730 }
731 
mdns_get_pairing_service_info(std::string_view name)732 std::optional<MdnsInfo> mdns_get_pairing_service_info(std::string_view name) {
733     CHECK(!name.empty());
734 
735     auto mdns_instance = mdns::mdns_parse_instance_name(name);
736     if (!mdns_instance.has_value()) {
737         D("Failed to parse mDNS pairing name [%s]", name.data());
738         return std::nullopt;
739     }
740 
741     std::optional<MdnsInfo> info;
742     auto cb = [&](const char* service_name, const char* reg_type, const char* ip_addr,
743                   uint16_t port) { info.emplace(service_name, reg_type, ip_addr, port); };
744 
745     // Verify it's a pairing service if user explicitly inputs it.
746     if (!mdns_instance->service_name.empty()) {
747         auto reg_type = android::base::StringPrintf("%s.%s", mdns_instance->service_name.data(),
748                                                     mdns_instance->transport_type.data());
749         int index = adb_DNSServiceIndexByName(reg_type);
750         switch (index) {
751             case kADBSecurePairingServiceRefIndex:
752                 break;
753             default:
754                 D("Not an adb pairing reg_type [%s]", reg_type.data());
755                 return std::nullopt;
756         }
757     }
758 
759     ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices, name, cb);
760     return info;
761 }
762