• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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