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