From 2fe9b6047536e1dbb3e6253bd6c2b3400d6f5903 Mon Sep 17 00:00:00 2001 From: Casey Dahlin Date: Wed, 21 Sep 2016 14:03:39 -0700 Subject: [PATCH] Make ADB over mDNS work on Windows Test: Verified ADB over mDNS on a Windows machine Bug: 30482671 (cherry picked from 9fdd77101f49d03ff29342e12e23edf241f68522) Change-Id: If955ca304db71a5b08c5a9654f1e27ab74af9af8 --- adb/Android.mk | 21 ++++---- adb/sysdeps.h | 7 +++ adb/sysdeps_win32.cpp | 17 ++++--- adb/transport_mdns.cpp | 112 +++++++++++++++++++++++------------------ 4 files changed, 92 insertions(+), 65 deletions(-) diff --git a/adb/Android.mk b/adb/Android.mk index b12a9f8a7..8a43e37bc 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -144,22 +144,19 @@ LOCAL_CFLAGS_linux := $(LIBADB_linux_CFLAGS) LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS) LOCAL_SRC_FILES := \ $(LIBADB_SRC_FILES) \ - adb_auth_host.cpp + adb_auth_host.cpp \ + transport_mdns.cpp \ LOCAL_SRC_FILES_darwin := $(LIBADB_darwin_SRC_FILES) LOCAL_SRC_FILES_linux := $(LIBADB_linux_SRC_FILES) LOCAL_SRC_FILES_windows := $(LIBADB_windows_SRC_FILES) -LOCAL_SRC_FILES_linux += transport_mdns.cpp -LOCAL_SRC_FILES_darwin += transport_mdns.cpp -LOCAL_SRC_FILES_windows += transport_mdns_unsupported.cpp - LOCAL_SANITIZE := $(adb_host_sanitize) # Even though we're building a static library (and thus there's no link step for # this to take effect), this adds the includes to our path. -LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase -LOCAL_STATIC_LIBRARIES_linux := libusb libmdnssd +LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase libmdnssd +LOCAL_STATIC_LIBRARIES_linux := libusb LOCAL_STATIC_LIBRARIES_darwin := libusb LOCAL_C_INCLUDES_windows := development/host/windows/usb/api/ @@ -180,7 +177,7 @@ LOCAL_SRC_FILES := \ shell_service_test.cpp \ LOCAL_SANITIZE := $(adb_target_sanitize) -LOCAL_STATIC_LIBRARIES := libadbd libcrypto_utils libcrypto libusb +LOCAL_STATIC_LIBRARIES := libadbd libcrypto_utils libcrypto libusb libmdnssd LOCAL_SHARED_LIBRARIES := liblog libbase libcutils include $(BUILD_NATIVE_TEST) @@ -228,9 +225,10 @@ LOCAL_STATIC_LIBRARIES := \ libcrypto \ libcutils \ libdiagnose_usb \ + libmdnssd \ libgmock_host -LOCAL_STATIC_LIBRARIES_linux := libusb libmdnssd +LOCAL_STATIC_LIBRARIES_linux := libusb LOCAL_STATIC_LIBRARIES_darwin := libusb # Set entrypoint to wmain from sysdeps_win32.cpp instead of main @@ -295,11 +293,12 @@ LOCAL_STATIC_LIBRARIES := \ libcrypto_utils \ libcrypto \ libdiagnose_usb \ - liblog + liblog \ + libmdnssd # Don't use libcutils on Windows. LOCAL_STATIC_LIBRARIES_darwin := libcutils -LOCAL_STATIC_LIBRARIES_linux := libcutils libmdnssd +LOCAL_STATIC_LIBRARIES_linux := libcutils LOCAL_STATIC_LIBRARIES_darwin += libusb LOCAL_STATIC_LIBRARIES_linux += libusb diff --git a/adb/sysdeps.h b/adb/sysdeps.h index 654072c35..f195b4eb4 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -197,6 +197,7 @@ extern int adb_write(int fd, const void* buf, int len); extern int adb_lseek(int fd, int pos, int where); extern int adb_shutdown(int fd); extern int adb_close(int fd); +extern int adb_register_socket(SOCKET s); // See the comments for the !defined(_WIN32) version of unix_close(). static __inline__ int unix_close(int fd) @@ -523,6 +524,12 @@ __inline__ int adb_close(int fd) { #undef close #define close ____xxx_close +// On Windows, ADB has an indirection layer for file descriptors. If we get a +// Win32 SOCKET object from an external library, we have to map it in to that +// indirection layer, which this does. +__inline__ int adb_register_socket(int s) { + return s; +} static __inline__ int adb_read(int fd, void* buf, size_t len) { diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp index a4b5e6978..f997e6b84 100644 --- a/adb/sysdeps_win32.cpp +++ b/adb/sysdeps_win32.cpp @@ -126,10 +126,7 @@ typedef struct FHRec_ SOCKET socket; } u; - int mask; - char name[32]; - } FHRec; #define fh_handle u.handle @@ -577,7 +574,6 @@ extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) { static void _fh_socket_init(FH f) { f->fh_socket = INVALID_SOCKET; - f->mask = 0; } static int _fh_socket_close( FH f ) { @@ -598,7 +594,6 @@ static int _fh_socket_close( FH f ) { } f->fh_socket = INVALID_SOCKET; } - f->mask = 0; return 0; } @@ -913,6 +908,12 @@ int network_connect(const std::string& host, int port, int type, int timeout, st return fd; } +int adb_register_socket(SOCKET s) { + FH f = _fh_alloc( &_fh_socket_class ); + f->fh_socket = s; + return _fh_to_int(f); +} + #undef accept int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) { @@ -1113,18 +1114,22 @@ bool set_file_block_mode(int fd, bool block) { if (!fh || !fh->used) { errno = EBADF; + D("Setting nonblocking on bad file descriptor %d", fd); return false; } if (fh->clazz == &_fh_socket_class) { u_long x = !block; if (ioctlsocket(fh->u.socket, FIONBIO, &x) != 0) { - _socket_set_errno(WSAGetLastError()); + int error = WSAGetLastError(); + _socket_set_errno(error); + D("Setting %d nonblocking failed (%d)", fd, error); return false; } return true; } else { errno = ENOTSOCK; + D("Setting nonblocking on non-socket %d", fd); return false; } } diff --git a/adb/transport_mdns.cpp b/adb/transport_mdns.cpp index 384845252..e49b1c668 100644 --- a/adb/transport_mdns.cpp +++ b/adb/transport_mdns.cpp @@ -18,7 +18,11 @@ #include "transport.h" +#ifdef _WIN32 +#include +#else #include +#endif #include #include @@ -31,14 +35,22 @@ static DNSServiceRef service_ref; static fdevent service_ref_fde; -static void register_service_ip(DNSServiceRef sdRef, - DNSServiceFlags flags, - uint32_t interfaceIndex, - DNSServiceErrorType errorCode, - const char* hostname, - const sockaddr* address, - uint32_t ttl, - void* context); +// Use adb_DNSServiceRefSockFD() instead of calling DNSServiceRefSockFD() +// directly so that the socket is put through the appropriate compatibility +// layers to work with the rest of ADB's internal APIs. +static inline int adb_DNSServiceRefSockFD(DNSServiceRef ref) { + return adb_register_socket(DNSServiceRefSockFD(ref)); +} +#define DNSServiceRefSockFD ___xxx_DNSServiceRefSockFD + +static void DNSSD_API register_service_ip(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* hostname, + const sockaddr* address, + uint32_t ttl, + void* context); static void pump_service_ref(int /*fd*/, unsigned ev, void* data) { DNSServiceRef* ref = reinterpret_cast(data); @@ -66,7 +78,7 @@ class AsyncServiceRef { DNSServiceRef sdRef_; void Initialize() { - fdevent_install(&fde_, DNSServiceRefSockFD(sdRef_), + fdevent_install(&fde_, adb_DNSServiceRefSockFD(sdRef_), pump_service_ref, &sdRef_); fdevent_set(&fde_, FDE_READ); initialized_ = true; @@ -123,8 +135,9 @@ class ResolvedService : public AsyncServiceRef { return; } - if (!inet_ntop(address->sa_family, ip_addr_data, ip_addr, - INET6_ADDRSTRLEN)) { + // Winsock version requires the const cast Because Microsoft. + if (!inet_ntop(address->sa_family, const_cast(ip_addr_data), + ip_addr, INET6_ADDRSTRLEN)) { D("Could not convert IP address to string."); return; } @@ -141,29 +154,30 @@ class ResolvedService : public AsyncServiceRef { const uint16_t port_; }; -static void register_service_ip(DNSServiceRef /*sdRef*/, - DNSServiceFlags /*flags*/, - uint32_t /*interfaceIndex*/, - DNSServiceErrorType /*errorCode*/, - const char* /*hostname*/, - const sockaddr* address, - uint32_t /*ttl*/, - void* context) { +static void DNSSD_API register_service_ip(DNSServiceRef /*sdRef*/, + DNSServiceFlags /*flags*/, + uint32_t /*interfaceIndex*/, + DNSServiceErrorType /*errorCode*/, + const char* /*hostname*/, + const sockaddr* address, + uint32_t /*ttl*/, + void* context) { + D("Got IP for service."); std::unique_ptr data( reinterpret_cast(context)); data->Connect(address); } -static void 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); +static void DNSSD_API 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); class DiscoveredService : public AsyncServiceRef { public: @@ -191,16 +205,17 @@ class DiscoveredService : public AsyncServiceRef { std::string serviceName_; }; -static void 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) { +static void DNSSD_API 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) { + D("Resolved a service."); std::unique_ptr discovered( reinterpret_cast(context)); @@ -223,14 +238,15 @@ static void register_resolved_mdns_service(DNSServiceRef sdRef, } } -static void register_mdns_transport(DNSServiceRef sdRef, - DNSServiceFlags flags, - uint32_t interfaceIndex, - DNSServiceErrorType errorCode, - const char* serviceName, - const char* regtype, - const char* domain, - void* /*context*/) { +static void DNSSD_API register_mdns_transport(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char* serviceName, + const char* regtype, + const char* domain, + void* /*context*/) { + D("Registering a transport."); if (errorCode != kDNSServiceErr_NoError) { D("Got error %d during mDNS browse.", errorCode); DNSServiceRefDeallocate(sdRef); @@ -257,7 +273,7 @@ void init_mdns_transport_discovery(void) { } fdevent_install(&service_ref_fde, - DNSServiceRefSockFD(service_ref), + adb_DNSServiceRefSockFD(service_ref), pump_service_ref, &service_ref); fdevent_set(&service_ref_fde, FDE_READ);