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 <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 "fdevent/fdevent.h"
41 #include "sysdeps.h"
42
43 static DNSServiceRef service_refs[kNumADBDNSServices];
44 static fdevent* service_ref_fdes[kNumADBDNSServices];
45
adb_DNSServiceIndexByName(const char * regType)46 static int adb_DNSServiceIndexByName(const char* regType) {
47 for (int i = 0; i < kNumADBDNSServices; ++i) {
48 if (!strncmp(regType, kADBDNSServices[i], strlen(kADBDNSServices[i]))) {
49 return i;
50 }
51 }
52 return -1;
53 }
54
adb_DNSServiceShouldConnect(const char * regType,const char * serviceName)55 static bool adb_DNSServiceShouldConnect(const char* regType, const char* serviceName) {
56 int index = adb_DNSServiceIndexByName(regType);
57 if (index == kADBTransportServiceRefIndex) {
58 // Ignore adb-EMULATOR* service names, as it interferes with the
59 // emulator ports that are already connected.
60 if (android::base::StartsWith(serviceName, "adb-EMULATOR")) {
61 LOG(INFO) << "Ignoring emulator transport service [" << serviceName << "]";
62 return false;
63 }
64 }
65 return (index == kADBTransportServiceRefIndex || index == kADBSecureConnectServiceRefIndex);
66 }
67
68 // Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD()
69 // directly so that the socket is put through the appropriate compatibility
70 // layers to work with the rest of ADB's internal APIs.
adb_DNSServiceRefSockFD(DNSServiceRef ref)71 static inline int adb_DNSServiceRefSockFD(DNSServiceRef ref) {
72 return adb_register_socket(DNSServiceRefSockFD(ref));
73 }
74 #define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD
75
76 static void DNSSD_API register_service_ip(DNSServiceRef sdRef,
77 DNSServiceFlags flags,
78 uint32_t interfaceIndex,
79 DNSServiceErrorType errorCode,
80 const char* hostname,
81 const sockaddr* address,
82 uint32_t ttl,
83 void* context);
84
pump_service_ref(int,unsigned ev,void * data)85 static void pump_service_ref(int /*fd*/, unsigned ev, void* data) {
86 DNSServiceRef* ref = reinterpret_cast<DNSServiceRef*>(data);
87
88 if (ev & FDE_READ)
89 DNSServiceProcessResult(*ref);
90 }
91
92 class AsyncServiceRef {
93 public:
Initialized()94 bool Initialized() {
95 return initialized_;
96 }
97
~AsyncServiceRef()98 virtual ~AsyncServiceRef() {
99 if (!initialized_) {
100 return;
101 }
102
103 // Order matters here! Must destroy the fdevent first since it has a
104 // reference to |sdRef_|.
105 fdevent_destroy(fde_);
106 DNSServiceRefDeallocate(sdRef_);
107 }
108
109 protected:
110 DNSServiceRef sdRef_;
111
Initialize()112 void Initialize() {
113 fde_ = fdevent_create(adb_DNSServiceRefSockFD(sdRef_), pump_service_ref, &sdRef_);
114 if (fde_ == nullptr) {
115 D("Unable to create fdevent");
116 return;
117 }
118 fdevent_set(fde_, FDE_READ);
119 initialized_ = true;
120 }
121
122 private:
123 bool initialized_ = false;
124 fdevent* fde_;
125 };
126
127 class ResolvedService : public AsyncServiceRef {
128 public:
129 virtual ~ResolvedService() = default;
130
ResolvedService(std::string serviceName,std::string regType,uint32_t interfaceIndex,const char * hosttarget,uint16_t port,int version)131 ResolvedService(std::string serviceName, std::string regType, uint32_t interfaceIndex,
132 const char* hosttarget, uint16_t port, int version)
133 : serviceName_(serviceName),
134 regType_(regType),
135 hosttarget_(hosttarget),
136 port_(port),
137 sa_family_(0),
138 ip_addr_data_(NULL),
139 serviceVersion_(version) {
140 memset(ip_addr_, 0, sizeof(ip_addr_));
141
142 /* TODO: We should be able to get IPv6 support by adding
143 * kDNSServiceProtocol_IPv6 to the flags below. However, when we do
144 * this, we get served link-local addresses that are usually useless to
145 * connect to. What's more, we seem to /only/ get those and nothing else.
146 * If we want IPv6 in the future we'll have to figure out why.
147 */
148 DNSServiceErrorType ret =
149 DNSServiceGetAddrInfo(
150 &sdRef_, 0, interfaceIndex,
151 kDNSServiceProtocol_IPv4, hosttarget,
152 register_service_ip, reinterpret_cast<void*>(this));
153
154 if (ret != kDNSServiceErr_NoError) {
155 D("Got %d from DNSServiceGetAddrInfo.", ret);
156 } else {
157 Initialize();
158 }
159
160 D("Client version: %d Service version: %d\n", clientVersion_, serviceVersion_);
161 }
162
ConnectSecureWifiDevice()163 bool ConnectSecureWifiDevice() {
164 if (!adb_wifi_is_known_host(serviceName_)) {
165 LOG(INFO) << "serviceName=" << serviceName_ << " not in keystore";
166 return false;
167 }
168
169 std::string response;
170 connect_device(android::base::StringPrintf(addr_format_.c_str(), ip_addr_, port_),
171 &response);
172 D("Secure connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
173 ip_addr_, port_, response.c_str());
174 return true;
175 }
176
Connect(const sockaddr * address)177 void Connect(const sockaddr* address) {
178 sa_family_ = address->sa_family;
179
180 if (sa_family_ == AF_INET) {
181 ip_addr_data_ = &reinterpret_cast<const sockaddr_in*>(address)->sin_addr;
182 addr_format_ = "%s:%hu";
183 } else if (sa_family_ == AF_INET6) {
184 ip_addr_data_ = &reinterpret_cast<const sockaddr_in6*>(address)->sin6_addr;
185 addr_format_ = "[%s]:%hu";
186 } else { // Should be impossible
187 D("mDNS resolved non-IP address.");
188 return;
189 }
190
191 // Winsock version requires the const cast Because Microsoft.
192 if (!inet_ntop(sa_family_, const_cast<void*>(ip_addr_data_), ip_addr_, sizeof(ip_addr_))) {
193 D("Could not convert IP address to string.");
194 return;
195 }
196
197 // adb secure service needs to do something different from just
198 // connecting here.
199 if (adb_DNSServiceShouldConnect(regType_.c_str(), serviceName_.c_str())) {
200 std::string response;
201 D("Attempting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)", serviceName_.c_str(),
202 regType_.c_str(), ip_addr_, port_);
203 int index = adb_DNSServiceIndexByName(regType_.c_str());
204 if (index == kADBSecureConnectServiceRefIndex) {
205 ConnectSecureWifiDevice();
206 } else {
207 connect_device(android::base::StringPrintf(addr_format_.c_str(), ip_addr_, port_),
208 &response);
209 D("Connect to %s regtype %s (%s:%hu) : %s", serviceName_.c_str(), regType_.c_str(),
210 ip_addr_, port_, response.c_str());
211 }
212 } else {
213 D("Not immediately connecting to serviceName=[%s], regtype=[%s] ipaddr=(%s:%hu)",
214 serviceName_.c_str(), regType_.c_str(), ip_addr_, port_);
215 }
216
217 int adbSecureServiceType = serviceIndex();
218 switch (adbSecureServiceType) {
219 case kADBSecurePairingServiceRefIndex:
220 sAdbSecurePairingServices->push_back(this);
221 break;
222 case kADBSecureConnectServiceRefIndex:
223 sAdbSecureConnectServices->push_back(this);
224 break;
225 default:
226 break;
227 }
228 }
229
serviceIndex() const230 int serviceIndex() const { return adb_DNSServiceIndexByName(regType_.c_str()); }
231
hostTarget() const232 std::string hostTarget() const { return hosttarget_; }
233
serviceName() const234 std::string serviceName() const { return serviceName_; }
235
ipAddress() const236 std::string ipAddress() const { return ip_addr_; }
237
port() const238 uint16_t port() const { return port_; }
239
240 using ServiceRegistry = std::vector<ResolvedService*>;
241
242 static ServiceRegistry* sAdbSecurePairingServices;
243 static ServiceRegistry* sAdbSecureConnectServices;
244
245 static void initAdbSecure();
246
247 static void forEachService(const ServiceRegistry& services, const std::string& hostname,
248 adb_secure_foreach_service_callback cb);
249
250 static bool connectByServiceName(const ServiceRegistry& services,
251 const std::string& service_name);
252
253 private:
254 int clientVersion_ = ADB_SECURE_CLIENT_VERSION;
255 std::string addr_format_;
256 std::string serviceName_;
257 std::string regType_;
258 std::string hosttarget_;
259 const uint16_t port_;
260 int sa_family_;
261 const void* ip_addr_data_;
262 char ip_addr_[INET6_ADDRSTRLEN];
263 int serviceVersion_;
264 };
265
266 // static
267 std::vector<ResolvedService*>* ResolvedService::sAdbSecurePairingServices = NULL;
268
269 // static
270 std::vector<ResolvedService*>* ResolvedService::sAdbSecureConnectServices = NULL;
271
272 // static
initAdbSecure()273 void ResolvedService::initAdbSecure() {
274 if (!sAdbSecurePairingServices) {
275 sAdbSecurePairingServices = new ServiceRegistry;
276 }
277 if (!sAdbSecureConnectServices) {
278 sAdbSecureConnectServices = new ServiceRegistry;
279 }
280 }
281
282 // static
forEachService(const ServiceRegistry & services,const std::string & wanted_service_name,adb_secure_foreach_service_callback cb)283 void ResolvedService::forEachService(const ServiceRegistry& services,
284 const std::string& wanted_service_name,
285 adb_secure_foreach_service_callback cb) {
286 initAdbSecure();
287
288 for (auto service : services) {
289 auto service_name = service->serviceName();
290 auto ip = service->ipAddress();
291 auto port = service->port();
292
293 if (wanted_service_name == "") {
294 cb(service_name.c_str(), ip.c_str(), port);
295 } else if (service_name == wanted_service_name) {
296 cb(service_name.c_str(), ip.c_str(), port);
297 }
298 }
299 }
300
301 // static
connectByServiceName(const ServiceRegistry & services,const std::string & service_name)302 bool ResolvedService::connectByServiceName(const ServiceRegistry& services,
303 const std::string& service_name) {
304 initAdbSecure();
305 for (auto service : services) {
306 if (service_name == service->serviceName()) {
307 D("Got service_name match [%s]", service->serviceName().c_str());
308 return service->ConnectSecureWifiDevice();
309 }
310 }
311 D("No registered serviceNames matched [%s]", service_name.c_str());
312 return false;
313 }
314
adb_secure_foreach_pairing_service(const char * service_name,adb_secure_foreach_service_callback cb)315 void adb_secure_foreach_pairing_service(const char* service_name,
316 adb_secure_foreach_service_callback cb) {
317 ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices,
318 service_name ? service_name : "", cb);
319 }
320
adb_secure_foreach_connect_service(const char * service_name,adb_secure_foreach_service_callback cb)321 void adb_secure_foreach_connect_service(const char* service_name,
322 adb_secure_foreach_service_callback cb) {
323 ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices,
324 service_name ? service_name : "", cb);
325 }
326
adb_secure_connect_by_service_name(const char * service_name)327 bool adb_secure_connect_by_service_name(const char* service_name) {
328 return ResolvedService::connectByServiceName(*ResolvedService::sAdbSecureConnectServices,
329 service_name);
330 }
331
register_service_ip(DNSServiceRef,DNSServiceFlags,uint32_t,DNSServiceErrorType,const char *,const sockaddr * address,uint32_t,void * context)332 static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/,
333 DNSServiceFlags /*flags*/,
334 uint32_t /*interfaceIndex*/,
335 DNSServiceErrorType /*errorCode*/,
336 const char* /*hostname*/,
337 const sockaddr* address,
338 uint32_t /*ttl*/,
339 void* context) {
340 D("Got IP for service.");
341 std::unique_ptr<ResolvedService> data(
342 reinterpret_cast<ResolvedService*>(context));
343 data->Connect(address);
344
345 // For ADB Secure services, keep those ResolvedService's around
346 // for later processing with secure connection establishment.
347 if (data->serviceIndex() != kADBTransportServiceRefIndex) {
348 data.release();
349 }
350 }
351
352 static void DNSSD_API register_resolved_mdns_service(DNSServiceRef sdRef,
353 DNSServiceFlags flags,
354 uint32_t interfaceIndex,
355 DNSServiceErrorType errorCode,
356 const char* fullname,
357 const char* hosttarget,
358 uint16_t port,
359 uint16_t txtLen,
360 const unsigned char* txtRecord,
361 void* context);
362
363 class DiscoveredService : public AsyncServiceRef {
364 public:
DiscoveredService(uint32_t interfaceIndex,const char * serviceName,const char * regtype,const char * domain)365 DiscoveredService(uint32_t interfaceIndex, const char* serviceName, const char* regtype,
366 const char* domain)
367 : serviceName_(serviceName), regType_(regtype) {
368 DNSServiceErrorType ret =
369 DNSServiceResolve(&sdRef_, 0, interfaceIndex, serviceName, regtype,
370 domain, register_resolved_mdns_service,
371 reinterpret_cast<void*>(this));
372
373 D("DNSServiceResolve for "
374 "interfaceIndex %u "
375 "serviceName %s "
376 "regtype %s "
377 "domain %s "
378 ": %d",
379 interfaceIndex, serviceName, regtype, domain, ret);
380
381 if (ret == kDNSServiceErr_NoError) {
382 Initialize();
383 }
384 }
385
ServiceName()386 const char* ServiceName() {
387 return serviceName_.c_str();
388 }
389
RegType()390 const char* RegType() { return regType_.c_str(); }
391
392 private:
393 std::string serviceName_;
394 std::string regType_;
395 };
396
adb_RemoveDNSService(const char * regType,const char * serviceName)397 static void adb_RemoveDNSService(const char* regType, const char* serviceName) {
398 int index = adb_DNSServiceIndexByName(regType);
399 ResolvedService::ServiceRegistry* services;
400 switch (index) {
401 case kADBSecurePairingServiceRefIndex:
402 services = ResolvedService::sAdbSecurePairingServices;
403 break;
404 case kADBSecureConnectServiceRefIndex:
405 services = ResolvedService::sAdbSecureConnectServices;
406 break;
407 default:
408 return;
409 }
410
411 std::string sName(serviceName);
412 services->erase(std::remove_if(
413 services->begin(), services->end(),
414 [&sName](ResolvedService* service) { return (sName == service->serviceName()); }));
415 }
416
417 // Returns the version the device wanted to advertise,
418 // or -1 if parsing fails.
parse_version_from_txt_record(uint16_t txtLen,const unsigned char * txtRecord)419 static int parse_version_from_txt_record(uint16_t txtLen, const unsigned char* txtRecord) {
420 if (!txtLen) return -1;
421 if (!txtRecord) return -1;
422
423 // https://tools.ietf.org/html/rfc6763
424 // """
425 // 6.1. General Format Rules for DNS TXT Records
426 //
427 // A DNS TXT record can be up to 65535 (0xFFFF) bytes long. The total
428 // length is indicated by the length given in the resource record header
429 // in the DNS message. There is no way to tell directly from the data
430 // alone how long it is (e.g., there is no length count at the start, or
431 // terminating NULL byte at the end).
432 // """
433
434 // Let's trust the TXT record's length byte
435 // Worst case, it wastes 255 bytes
436 std::vector<char> recordAsString(txtLen + 1, '\0');
437 char* str = recordAsString.data();
438
439 memcpy(str, txtRecord + 1 /* skip the length byte */, txtLen);
440
441 // Check if it's the version key
442 static const char* versionKey = "v=";
443 size_t versionKeyLen = strlen(versionKey);
444
445 if (strncmp(versionKey, str, versionKeyLen)) return -1;
446
447 auto valueStart = str + versionKeyLen;
448
449 long parsedNumber = strtol(valueStart, 0, 10);
450
451 // No valid conversion. Also, 0
452 // is not a valid version.
453 if (!parsedNumber) return -1;
454
455 // Outside bounds of long.
456 if (parsedNumber == LONG_MIN || parsedNumber == LONG_MAX) return -1;
457
458 // Possibly valid version
459 return static_cast<int>(parsedNumber);
460 }
461
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)462 static void DNSSD_API register_resolved_mdns_service(
463 DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
464 DNSServiceErrorType errorCode, const char* fullname, const char* hosttarget, uint16_t port,
465 uint16_t txtLen, const unsigned char* txtRecord, void* context) {
466 D("Resolved a service.");
467 std::unique_ptr<DiscoveredService> discovered(
468 reinterpret_cast<DiscoveredService*>(context));
469
470 if (errorCode != kDNSServiceErr_NoError) {
471 D("Got error %d resolving service.", errorCode);
472 return;
473 }
474
475 // TODO: Reject certain combinations of invalid or mismatched client and
476 // service versions here before creating anything.
477 // At the moment, there is nothing to reject, so accept everything
478 // as an optimistic default.
479 auto serviceVersion = parse_version_from_txt_record(txtLen, txtRecord);
480
481 auto resolved = new ResolvedService(discovered->ServiceName(), discovered->RegType(),
482 interfaceIndex, hosttarget, ntohs(port), serviceVersion);
483
484 if (! resolved->Initialized()) {
485 D("Unable to init resolved service");
486 delete resolved;
487 }
488
489 if (flags) { /* Only ever equals MoreComing or 0 */
490 D("releasing discovered service");
491 discovered.release();
492 }
493 }
494
on_service_browsed(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * serviceName,const char * regtype,const char * domain,void *)495 static void DNSSD_API on_service_browsed(DNSServiceRef sdRef, DNSServiceFlags flags,
496 uint32_t interfaceIndex, DNSServiceErrorType errorCode,
497 const char* serviceName, const char* regtype,
498 const char* domain, void* /*context*/) {
499 if (errorCode != kDNSServiceErr_NoError) {
500 D("Got error %d during mDNS browse.", errorCode);
501 DNSServiceRefDeallocate(sdRef);
502 int serviceIndex = adb_DNSServiceIndexByName(regtype);
503 if (serviceIndex != -1) {
504 fdevent_destroy(service_ref_fdes[serviceIndex]);
505 }
506 return;
507 }
508
509 if (flags & kDNSServiceFlagsAdd) {
510 D("%s: Discover found new serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
511 regtype, domain);
512 auto discovered = new DiscoveredService(interfaceIndex, serviceName, regtype, domain);
513 if (!discovered->Initialized()) {
514 delete discovered;
515 }
516 } else {
517 D("%s: Discover lost serviceName=[%s] regtype=[%s] domain=[%s]", __func__, serviceName,
518 regtype, domain);
519 adb_RemoveDNSService(regtype, serviceName);
520 }
521 }
522
init_mdns_transport_discovery_thread(void)523 void init_mdns_transport_discovery_thread(void) {
524 int errorCodes[kNumADBDNSServices];
525
526 for (int i = 0; i < kNumADBDNSServices; ++i) {
527 errorCodes[i] = DNSServiceBrowse(&service_refs[i], 0, 0, kADBDNSServices[i], nullptr,
528 on_service_browsed, nullptr);
529
530 if (errorCodes[i] != kDNSServiceErr_NoError) {
531 D("Got %d browsing for mDNS service %s.", errorCodes[i], kADBDNSServices[i]);
532 }
533
534 if (errorCodes[i] == kDNSServiceErr_NoError) {
535 fdevent_run_on_main_thread([i]() {
536 service_ref_fdes[i] = fdevent_create(adb_DNSServiceRefSockFD(service_refs[i]),
537 pump_service_ref, &service_refs[i]);
538 fdevent_set(service_ref_fdes[i], FDE_READ);
539 });
540 }
541 }
542 }
543
init_mdns_transport_discovery(void)544 void init_mdns_transport_discovery(void) {
545 ResolvedService::initAdbSecure();
546 std::thread(init_mdns_transport_discovery_thread).detach();
547 }
548