am 57532b2a: Merge "adb: improve network error info"
* commit '57532b2a067082fa5968094c2c615f1832fa1971': adb: improve network error info
This commit is contained in:
commit
5563b77a13
4 changed files with 50 additions and 22 deletions
|
|
@ -858,7 +858,7 @@ int handle_forward_request(const char* service, TransportType type, const char*
|
||||||
case INSTALL_STATUS_OK: message = "success (!)"; break;
|
case INSTALL_STATUS_OK: message = "success (!)"; break;
|
||||||
case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
|
case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break;
|
||||||
case INSTALL_STATUS_CANNOT_BIND:
|
case INSTALL_STATUS_CANNOT_BIND:
|
||||||
message = android::base::StringPrintf("cannot bind to socket: %s",
|
message = android::base::StringPrintf("cannot bind listener: %s",
|
||||||
error.c_str());
|
error.c_str());
|
||||||
break;
|
break;
|
||||||
case INSTALL_STATUS_CANNOT_REBIND:
|
case INSTALL_STATUS_CANNOT_REBIND:
|
||||||
|
|
|
||||||
|
|
@ -190,16 +190,19 @@ InstallStatus install_listener(const std::string& local_name,
|
||||||
|
|
||||||
/* can't repurpose a smartsocket */
|
/* can't repurpose a smartsocket */
|
||||||
if(l->connect_to[0] == '*') {
|
if(l->connect_to[0] == '*') {
|
||||||
|
*error = "cannot repurpose smartsocket";
|
||||||
return INSTALL_STATUS_INTERNAL_ERROR;
|
return INSTALL_STATUS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can't repurpose a listener if 'no_rebind' is true */
|
/* can't repurpose a listener if 'no_rebind' is true */
|
||||||
if (no_rebind) {
|
if (no_rebind) {
|
||||||
|
*error = "cannot rebind";
|
||||||
return INSTALL_STATUS_CANNOT_REBIND;
|
return INSTALL_STATUS_CANNOT_REBIND;
|
||||||
}
|
}
|
||||||
|
|
||||||
cto = strdup(connect_to);
|
cto = strdup(connect_to);
|
||||||
if(cto == 0) {
|
if(cto == 0) {
|
||||||
|
*error = "cannot duplicate string";
|
||||||
return INSTALL_STATUS_INTERNAL_ERROR;
|
return INSTALL_STATUS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,7 +235,6 @@ InstallStatus install_listener(const std::string& local_name,
|
||||||
|
|
||||||
listener->fd = local_name_to_fd(listener->local_name, error);
|
listener->fd = local_name_to_fd(listener->local_name, error);
|
||||||
if (listener->fd < 0) {
|
if (listener->fd < 0) {
|
||||||
printf("cannot bind '%s': %s\n", listener->local_name, error->c_str());
|
|
||||||
free(listener->local_name);
|
free(listener->local_name);
|
||||||
free(listener->connect_to);
|
free(listener->connect_to);
|
||||||
free(listener);
|
free(listener);
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ int adb_main(int is_daemon, int server_port, int ack_reply_fd) {
|
||||||
std::string error;
|
std::string error;
|
||||||
std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
|
std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
|
||||||
if (install_listener(local_name, "*smartsocket*", nullptr, 0, &error)) {
|
if (install_listener(local_name, "*smartsocket*", nullptr, 0, &error)) {
|
||||||
LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
|
fatal("could not install *smartsocket* listener: %s", error.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform our parent that we are up and running.
|
// Inform our parent that we are up and running.
|
||||||
|
|
|
||||||
|
|
@ -554,6 +554,9 @@ static void _socket_set_errno( const DWORD err ) {
|
||||||
// POSIX and socket error codes, so this can only meaningfully map so much.
|
// POSIX and socket error codes, so this can only meaningfully map so much.
|
||||||
switch ( err ) {
|
switch ( err ) {
|
||||||
case 0: errno = 0; break;
|
case 0: errno = 0; break;
|
||||||
|
// Mapping WSAEWOULDBLOCK to EAGAIN is absolutely critical because
|
||||||
|
// non-blocking sockets can cause an error code of WSAEWOULDBLOCK and
|
||||||
|
// callers check specifically for EAGAIN.
|
||||||
case WSAEWOULDBLOCK: errno = EAGAIN; break;
|
case WSAEWOULDBLOCK: errno = EAGAIN; break;
|
||||||
case WSAEINTR: errno = EINTR; break;
|
case WSAEINTR: errno = EINTR; break;
|
||||||
case WSAEFAULT: errno = EFAULT; break;
|
case WSAEFAULT: errno = EFAULT; break;
|
||||||
|
|
@ -619,8 +622,12 @@ static int _fh_socket_read(FH f, void* buf, int len) {
|
||||||
int result = recv(f->fh_socket, reinterpret_cast<char*>(buf), len, 0);
|
int result = recv(f->fh_socket, reinterpret_cast<char*>(buf), len, 0);
|
||||||
if (result == SOCKET_ERROR) {
|
if (result == SOCKET_ERROR) {
|
||||||
const DWORD err = WSAGetLastError();
|
const DWORD err = WSAGetLastError();
|
||||||
D("recv fd %d failed: %s\n", _fh_to_int(f),
|
// WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
|
||||||
SystemErrorCodeToString(err).c_str());
|
// that to reduce spam and confusion.
|
||||||
|
if (err != WSAEWOULDBLOCK) {
|
||||||
|
D("recv fd %d failed: %s\n", _fh_to_int(f),
|
||||||
|
SystemErrorCodeToString(err).c_str());
|
||||||
|
}
|
||||||
_socket_set_errno(err);
|
_socket_set_errno(err);
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -701,14 +708,19 @@ int network_loopback_client(int port, int type, std::string* error) {
|
||||||
|
|
||||||
s = socket(AF_INET, type, 0);
|
s = socket(AF_INET, type, 0);
|
||||||
if(s == INVALID_SOCKET) {
|
if(s == INVALID_SOCKET) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf("cannot create socket: %s",
|
||||||
D("could not create socket: %s\n", error->c_str());
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
|
D("%s\n", error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
f->fh_socket = s;
|
f->fh_socket = s;
|
||||||
|
|
||||||
if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
|
if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
// Save err just in case inet_ntoa() or ntohs() changes the last error.
|
||||||
|
const DWORD err = WSAGetLastError();
|
||||||
|
*error = android::base::StringPrintf("cannot connect to %s:%u: %s",
|
||||||
|
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
|
||||||
|
SystemErrorCodeToString(err).c_str());
|
||||||
D("could not connect to %s:%d: %s\n",
|
D("could not connect to %s:%d: %s\n",
|
||||||
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -750,31 +762,40 @@ static int _network_server(int port, int type, u_long interface_address,
|
||||||
// IPv4 and IPv6.
|
// IPv4 and IPv6.
|
||||||
s = socket(AF_INET, type, 0);
|
s = socket(AF_INET, type, 0);
|
||||||
if (s == INVALID_SOCKET) {
|
if (s == INVALID_SOCKET) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf("cannot create socket: %s",
|
||||||
D("could not create socket: %s\n", error->c_str());
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
|
D("%s\n", error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->fh_socket = s;
|
f->fh_socket = s;
|
||||||
|
|
||||||
|
// Note: SO_REUSEADDR on Windows allows multiple processes to bind to the
|
||||||
|
// same port, so instead use SO_EXCLUSIVEADDRUSE.
|
||||||
n = 1;
|
n = 1;
|
||||||
if (setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n,
|
if (setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n,
|
||||||
sizeof(n)) == SOCKET_ERROR) {
|
sizeof(n)) == SOCKET_ERROR) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf(
|
||||||
D("setsockopt level %d optname %d failed: %s\n",
|
"cannot set socket option SO_EXCLUSIVEADDRUSE: %s",
|
||||||
SOL_SOCKET, SO_EXCLUSIVEADDRUSE, error->c_str());
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
|
D("%s\n", error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
|
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
// Save err just in case inet_ntoa() or ntohs() changes the last error.
|
||||||
|
const DWORD err = WSAGetLastError();
|
||||||
|
*error = android::base::StringPrintf("cannot bind to %s:%u: %s",
|
||||||
|
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
|
||||||
|
SystemErrorCodeToString(err).c_str());
|
||||||
D("could not bind to %s:%d: %s\n",
|
D("could not bind to %s:%d: %s\n",
|
||||||
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (type == SOCK_STREAM) {
|
if (type == SOCK_STREAM) {
|
||||||
if (listen(s, LISTEN_BACKLOG) == SOCKET_ERROR) {
|
if (listen(s, LISTEN_BACKLOG) == SOCKET_ERROR) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf("cannot listen on socket: %s",
|
||||||
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
D("could not listen on %s:%d: %s\n",
|
D("could not listen on %s:%d: %s\n",
|
||||||
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -825,9 +846,10 @@ int network_connect(const std::string& host, int port, int type, int timeout, st
|
||||||
// with GetProcAddress("GetAddrInfoW").
|
// with GetProcAddress("GetAddrInfoW").
|
||||||
#endif
|
#endif
|
||||||
if (getaddrinfo(host.c_str(), port_str, &hints, &addrinfo_ptr) != 0) {
|
if (getaddrinfo(host.c_str(), port_str, &hints, &addrinfo_ptr) != 0) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf(
|
||||||
D("could not resolve host '%s' and port %s: %s\n", host.c_str(),
|
"cannot resolve host '%s' and port %s: %s", host.c_str(),
|
||||||
port_str, error->c_str());
|
port_str, SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
|
D("%s\n", error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
std::unique_ptr<struct addrinfo, decltype(freeaddrinfo)*>
|
std::unique_ptr<struct addrinfo, decltype(freeaddrinfo)*>
|
||||||
|
|
@ -840,8 +862,9 @@ int network_connect(const std::string& host, int port, int type, int timeout, st
|
||||||
SOCKET s = socket(addrinfo->ai_family, addrinfo->ai_socktype,
|
SOCKET s = socket(addrinfo->ai_family, addrinfo->ai_socktype,
|
||||||
addrinfo->ai_protocol);
|
addrinfo->ai_protocol);
|
||||||
if(s == INVALID_SOCKET) {
|
if(s == INVALID_SOCKET) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
*error = android::base::StringPrintf("cannot create socket: %s",
|
||||||
D("could not create socket: %s\n", error->c_str());
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
|
D("%s\n", error->c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
f->fh_socket = s;
|
f->fh_socket = s;
|
||||||
|
|
@ -849,7 +872,10 @@ int network_connect(const std::string& host, int port, int type, int timeout, st
|
||||||
// TODO: Implement timeouts for Windows. Seems like the default in theory
|
// TODO: Implement timeouts for Windows. Seems like the default in theory
|
||||||
// (according to http://serverfault.com/a/671453) and in practice is 21 sec.
|
// (according to http://serverfault.com/a/671453) and in practice is 21 sec.
|
||||||
if(connect(s, addrinfo->ai_addr, addrinfo->ai_addrlen) == SOCKET_ERROR) {
|
if(connect(s, addrinfo->ai_addr, addrinfo->ai_addrlen) == SOCKET_ERROR) {
|
||||||
*error = SystemErrorCodeToString(WSAGetLastError());
|
// TODO: Use WSAAddressToString or inet_ntop on address.
|
||||||
|
*error = android::base::StringPrintf("cannot connect to %s:%s: %s",
|
||||||
|
host.c_str(), port_str,
|
||||||
|
SystemErrorCodeToString(WSAGetLastError()).c_str());
|
||||||
D("could not connect to %s:%s:%s: %s\n",
|
D("could not connect to %s:%s:%s: %s\n",
|
||||||
type != SOCK_STREAM ? "udp" : "tcp", host.c_str(), port_str,
|
type != SOCK_STREAM ? "udp" : "tcp", host.c_str(), port_str,
|
||||||
error->c_str());
|
error->c_str());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue