Merge "Report getaddrinfo failures correctly."
This commit is contained in:
commit
9727a6a019
13 changed files with 83 additions and 52 deletions
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include <base/macros.h>
|
#include <base/macros.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "adb_trace.h"
|
#include "adb_trace.h"
|
||||||
#include "fdevent.h"
|
#include "fdevent.h"
|
||||||
|
|
||||||
|
|
@ -357,8 +359,8 @@ void put_apacket(apacket *p);
|
||||||
|
|
||||||
|
|
||||||
void local_init(int port);
|
void local_init(int port);
|
||||||
int local_connect(int port);
|
void local_connect(int port);
|
||||||
int local_connect_arbitrary_ports(int console_port, int adb_port);
|
int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error);
|
||||||
|
|
||||||
/* usb host/client interface */
|
/* usb host/client interface */
|
||||||
void usb_init();
|
void usb_init();
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,10 @@
|
||||||
|
|
||||||
#include <base/stringprintf.h>
|
#include <base/stringprintf.h>
|
||||||
#include <base/strings.h>
|
#include <base/strings.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#include "adb_io.h"
|
#include "adb_io.h"
|
||||||
|
#include "adb_utils.h"
|
||||||
|
|
||||||
static TransportType __adb_transport = kTransportAny;
|
static TransportType __adb_transport = kTransportAny;
|
||||||
static const char* __adb_serial = NULL;
|
static const char* __adb_serial = NULL;
|
||||||
|
|
@ -152,13 +154,20 @@ int _adb_connect(const std::string& service, std::string* error) {
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
if (__adb_server_name) {
|
if (__adb_server_name) {
|
||||||
fd = socket_network_client(__adb_server_name, __adb_server_port, SOCK_STREAM);
|
std::string reason;
|
||||||
|
fd = network_connect(__adb_server_name, __adb_server_port, SOCK_STREAM, 0, &reason);
|
||||||
|
if (fd == -1) {
|
||||||
|
*error = android::base::StringPrintf("can't connect to %s:%d: %s",
|
||||||
|
__adb_server_name, __adb_server_port,
|
||||||
|
reason.c_str());
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
|
fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);
|
||||||
}
|
if (fd == -1) {
|
||||||
if (fd < 0) {
|
*error = perror_str("cannot connect to daemon");
|
||||||
*error = perror_str("cannot connect to daemon");
|
return -2;
|
||||||
return -2;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
|
if (memcmp(&service[0],"host",4) != 0 && switch_socket_transport(fd, error)) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <base/stringprintf.h>
|
#include <base/stringprintf.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "adb_utils.h"
|
#include "adb_utils.h"
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
@ -28,6 +29,7 @@
|
||||||
#include <base/logging.h>
|
#include <base/logging.h>
|
||||||
#include <base/stringprintf.h>
|
#include <base/stringprintf.h>
|
||||||
#include <base/strings.h>
|
#include <base/strings.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#include "adb_trace.h"
|
#include "adb_trace.h"
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
|
|
@ -158,3 +160,18 @@ bool parse_host_and_port(const std::string& address,
|
||||||
<< " (" << *canonical_address << ")";
|
<< " (" << *canonical_address << ")";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int network_connect(const std::string& host, int port, int type, int timeout, std::string* error) {
|
||||||
|
int getaddrinfo_error = 0;
|
||||||
|
int fd = socket_network_client_timeout(host.c_str(), port, type, timeout, &getaddrinfo_error);
|
||||||
|
if (fd != -1) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
if (getaddrinfo_error != 0) {
|
||||||
|
// TODO: not thread safe on Win32.
|
||||||
|
*error = gai_strerror(getaddrinfo_error);
|
||||||
|
} else {
|
||||||
|
*error = strerror(errno);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,4 +39,6 @@ bool parse_host_and_port(const std::string& address,
|
||||||
std::string* host, int* port,
|
std::string* host, int* port,
|
||||||
std::string* error);
|
std::string* error);
|
||||||
|
|
||||||
|
int network_connect(const std::string& host, int port, int type, int timeout, std::string* error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,10 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "base/file.h"
|
#include <base/file.h>
|
||||||
#include "base/logging.h"
|
#include <base/logging.h>
|
||||||
#include "base/strings.h"
|
#include <base/strings.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_client.h"
|
#include "adb_client.h"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <base/file.h>
|
#include <base/file.h>
|
||||||
#include <base/stringprintf.h>
|
#include <base/stringprintf.h>
|
||||||
#include <base/strings.h>
|
#include <base/strings.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#if !ADB_HOST
|
#if !ADB_HOST
|
||||||
#include "cutils/android_reboot.h"
|
#include "cutils/android_reboot.h"
|
||||||
|
|
@ -436,7 +437,8 @@ int service_to_fd(const char *name)
|
||||||
disable_tcp_nagle(ret);
|
disable_tcp_nagle(ret);
|
||||||
} else {
|
} else {
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
ret = socket_network_client(name + 1, port, SOCK_STREAM);
|
std::string error;
|
||||||
|
ret = network_connect(name + 1, port, SOCK_STREAM, 0, &error);
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -555,10 +557,11 @@ static void connect_device(const std::string& address, std::string* response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = socket_network_client_timeout(host.c_str(), port, SOCK_STREAM, 10);
|
std::string error;
|
||||||
|
int fd = network_connect(host.c_str(), port, SOCK_STREAM, 10, &error);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
*response = android::base::StringPrintf("unable to connect to %s: %s",
|
*response = android::base::StringPrintf("unable to connect to %s: %s",
|
||||||
serial.c_str(), strerror(errno));
|
serial.c_str(), error.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -612,12 +615,13 @@ void connect_emulator(const std::string& port_spec, std::string* response) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preconditions met, try to connect to the emulator.
|
// Preconditions met, try to connect to the emulator.
|
||||||
if (!local_connect_arbitrary_ports(console_port, adb_port)) {
|
std::string error;
|
||||||
|
if (!local_connect_arbitrary_ports(console_port, adb_port, &error)) {
|
||||||
*response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
|
*response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
|
||||||
console_port, adb_port);
|
console_port, adb_port);
|
||||||
} else {
|
} else {
|
||||||
*response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d",
|
*response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d: %s",
|
||||||
console_port, adb_port);
|
console_port, adb_port, error.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
# undef _WIN32
|
# undef _WIN32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||||
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
|
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
|
||||||
|
|
@ -187,9 +189,6 @@ extern void* load_file(const char* pathname, unsigned* psize);
|
||||||
|
|
||||||
/* normally provided by <cutils/sockets.h> */
|
/* normally provided by <cutils/sockets.h> */
|
||||||
extern int socket_loopback_client(int port, int type);
|
extern int socket_loopback_client(int port, int type);
|
||||||
extern int socket_network_client(const char *host, int port, int type);
|
|
||||||
extern int socket_network_client_timeout(const char *host, int port, int type,
|
|
||||||
int timeout);
|
|
||||||
extern int socket_loopback_server(int port, int type);
|
extern int socket_loopback_server(int port, int type);
|
||||||
extern int socket_inaddr_any_server(int port, int type);
|
extern int socket_inaddr_any_server(int port, int type);
|
||||||
|
|
||||||
|
|
@ -274,7 +273,6 @@ static __inline__ int adb_is_absolute_host_path( const char* path )
|
||||||
#else /* !_WIN32 a.k.a. Unix */
|
#else /* !_WIN32 a.k.a. Unix */
|
||||||
|
|
||||||
#include "fdevent.h"
|
#include "fdevent.h"
|
||||||
#include <cutils/sockets.h>
|
|
||||||
#include <cutils/misc.h>
|
#include <cutils/misc.h>
|
||||||
#include <cutils/threads.h>
|
#include <cutils/threads.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
|
||||||
|
|
@ -668,55 +668,45 @@ int socket_loopback_server(int port, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int socket_network_client(const char *host, int port, int type)
|
int socket_network_client_timeout(const char *host, int port, int type, int timeout,
|
||||||
{
|
std::string* error) {
|
||||||
FH f = _fh_alloc( &_fh_socket_class );
|
FH f = _fh_alloc( &_fh_socket_class );
|
||||||
struct hostent *hp;
|
if (!f) return -1;
|
||||||
struct sockaddr_in addr;
|
|
||||||
SOCKET s;
|
|
||||||
|
|
||||||
if (!f)
|
if (!_winsock_init) _init_winsock();
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!_winsock_init)
|
hostent* hp = gethostbyname(host);
|
||||||
_init_winsock();
|
|
||||||
|
|
||||||
hp = gethostbyname(host);
|
|
||||||
if(hp == 0) {
|
if(hp == 0) {
|
||||||
_fh_close(f);
|
_fh_close(f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sockaddr_in addr;
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = hp->h_addrtype;
|
addr.sin_family = hp->h_addrtype;
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
|
memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
|
||||||
|
|
||||||
s = socket(hp->h_addrtype, type, 0);
|
SOCKET s = socket(hp->h_addrtype, type, 0);
|
||||||
if(s == INVALID_SOCKET) {
|
if(s == INVALID_SOCKET) {
|
||||||
_fh_close(f);
|
_fh_close(f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
f->fh_socket = s;
|
f->fh_socket = s;
|
||||||
|
|
||||||
|
// TODO: implement timeouts for Windows.
|
||||||
|
|
||||||
if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
_fh_close(f);
|
_fh_close(f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
|
snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
|
||||||
D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
|
D( "socket_network_client_timeout: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
|
||||||
return _fh_to_int(f);
|
return _fh_to_int(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int socket_network_client_timeout(const char *host, int port, int type, int timeout)
|
|
||||||
{
|
|
||||||
// TODO: implement timeouts for Windows.
|
|
||||||
return socket_network_client(host, port, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int socket_inaddr_any_server(int port, int type)
|
int socket_inaddr_any_server(int port, int type)
|
||||||
{
|
{
|
||||||
FH f = _fh_alloc( &_fh_socket_class );
|
FH f = _fh_alloc( &_fh_socket_class );
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <base/stringprintf.h>
|
#include <base/stringprintf.h>
|
||||||
|
#include <cutils/sockets.h>
|
||||||
|
|
||||||
#if !ADB_HOST
|
#if !ADB_HOST
|
||||||
#include "cutils/properties.h"
|
#include "cutils/properties.h"
|
||||||
|
|
@ -33,6 +34,7 @@
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_io.h"
|
#include "adb_io.h"
|
||||||
|
#include "adb_utils.h"
|
||||||
|
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
/* we keep a list of opened transports. The atransport struct knows to which
|
/* we keep a list of opened transports. The atransport struct knows to which
|
||||||
|
|
@ -83,19 +85,18 @@ static int remote_write(apacket *p, atransport *t)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void local_connect(int port) {
|
||||||
int local_connect(int port) {
|
std::string dummy;
|
||||||
return local_connect_arbitrary_ports(port-1, port);
|
local_connect_arbitrary_ports(port-1, port, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int local_connect_arbitrary_ports(int console_port, int adb_port)
|
int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) {
|
||||||
{
|
int fd = -1;
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
const char *host = getenv("ADBHOST");
|
const char *host = getenv("ADBHOST");
|
||||||
if (host) {
|
if (host) {
|
||||||
fd = socket_network_client(host, adb_port, SOCK_STREAM);
|
fd = network_connect(host, adb_port, SOCK_STREAM, 0, error);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|
@ -126,7 +127,7 @@ static void *client_socket_thread(void *x)
|
||||||
/* this is only done when ADB starts up. later, each new emulator */
|
/* this is only done when ADB starts up. later, each new emulator */
|
||||||
/* will send a message to ADB to indicate that is is starting up */
|
/* will send a message to ADB to indicate that is is starting up */
|
||||||
for ( ; count > 0; count--, port += 2 ) {
|
for ( ; count > 0; count--, port += 2 ) {
|
||||||
(void) local_connect(port);
|
local_connect(port);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ static inline int android_get_control_socket(const char *name)
|
||||||
extern int socket_loopback_client(int port, int type);
|
extern int socket_loopback_client(int port, int type);
|
||||||
extern int socket_network_client(const char *host, int port, int type);
|
extern int socket_network_client(const char *host, int port, int type);
|
||||||
extern int socket_network_client_timeout(const char *host, int port, int type,
|
extern int socket_network_client_timeout(const char *host, int port, int type,
|
||||||
int timeout);
|
int timeout, int* getaddrinfo_error);
|
||||||
extern int socket_loopback_server(int port, int type);
|
extern int socket_loopback_server(int port, int type);
|
||||||
extern int socket_local_server(const char *name, int namespaceId, int type);
|
extern int socket_local_server(const char *name, int namespaceId, int type);
|
||||||
extern int socket_local_server_bind(int s, const char *name, int namespaceId);
|
extern int socket_local_server_bind(int s, const char *name, int namespaceId);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@ static int toggle_O_NONBLOCK(int s) {
|
||||||
// Connect to the given host and port.
|
// Connect to the given host and port.
|
||||||
// 'timeout' is in seconds (0 for no timeout).
|
// 'timeout' is in seconds (0 for no timeout).
|
||||||
// Returns a file descriptor or -1 on error.
|
// Returns a file descriptor or -1 on error.
|
||||||
int socket_network_client_timeout(const char* host, int port, int type, int timeout) {
|
// On error, check *getaddrinfo_error (for use with gai_strerror) first;
|
||||||
|
// if that's 0, use errno instead.
|
||||||
|
int socket_network_client_timeout(const char* host, int port, int type, int timeout,
|
||||||
|
int* getaddrinfo_error) {
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
|
@ -51,7 +54,8 @@ int socket_network_client_timeout(const char* host, int port, int type, int time
|
||||||
snprintf(port_str, sizeof(port_str), "%d", port);
|
snprintf(port_str, sizeof(port_str), "%d", port);
|
||||||
|
|
||||||
struct addrinfo* addrs;
|
struct addrinfo* addrs;
|
||||||
if (getaddrinfo(host, port_str, &hints, &addrs) != 0) {
|
*getaddrinfo_error = getaddrinfo(host, port_str, &hints, &addrs);
|
||||||
|
if (getaddrinfo_error != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,5 +120,6 @@ int socket_network_client_timeout(const char* host, int port, int type, int time
|
||||||
}
|
}
|
||||||
|
|
||||||
int socket_network_client(const char* host, int port, int type) {
|
int socket_network_client(const char* host, int port, int type) {
|
||||||
return socket_network_client_timeout(host, port, type, 0);
|
int getaddrinfo_error;
|
||||||
|
return socket_network_client_timeout(host, port, type, 0, &getaddrinfo_error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue