2015-02-25 00:51:19 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2015-09-23 00:52:57 +02:00
|
|
|
#define TRACE_TAG ADB
|
2015-03-19 23:21:08 +01:00
|
|
|
|
|
|
|
#include "sysdeps.h"
|
|
|
|
#include "adb_client.h"
|
|
|
|
|
2009-03-04 04:32:55 +01:00
|
|
|
#include <errno.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdarg.h>
|
2015-02-25 00:51:19 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-03-04 04:32:55 +01:00
|
|
|
#include <sys/stat.h>
|
2015-02-25 00:51:19 +01:00
|
|
|
#include <sys/types.h>
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-04-27 23:20:17 +02:00
|
|
|
#include <string>
|
2015-04-29 17:35:59 +02:00
|
|
|
#include <vector>
|
|
|
|
|
2015-12-05 07:00:26 +01:00
|
|
|
#include <android-base/stringprintf.h>
|
|
|
|
#include <android-base/strings.h>
|
2015-07-24 02:12:58 +02:00
|
|
|
#include <cutils/sockets.h>
|
2015-04-27 23:20:17 +02:00
|
|
|
|
2015-02-25 06:26:58 +01:00
|
|
|
#include "adb_io.h"
|
2015-07-24 02:12:58 +02:00
|
|
|
#include "adb_utils.h"
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-05-05 22:10:43 +02:00
|
|
|
static TransportType __adb_transport = kTransportAny;
|
2009-03-04 04:32:55 +01:00
|
|
|
static const char* __adb_serial = NULL;
|
|
|
|
|
2010-04-19 13:21:12 +02:00
|
|
|
static int __adb_server_port = DEFAULT_ADB_PORT;
|
2012-11-14 19:16:17 +01:00
|
|
|
static const char* __adb_server_name = NULL;
|
2010-04-19 13:21:12 +02:00
|
|
|
|
2015-05-05 22:10:43 +02:00
|
|
|
void adb_set_transport(TransportType type, const char* serial)
|
2009-03-04 04:32:55 +01:00
|
|
|
{
|
|
|
|
__adb_transport = type;
|
|
|
|
__adb_serial = serial;
|
|
|
|
}
|
|
|
|
|
2016-03-05 00:16:18 +01:00
|
|
|
void adb_get_transport(TransportType* type, const char** serial) {
|
|
|
|
if (type) {
|
|
|
|
*type = __adb_transport;
|
|
|
|
}
|
|
|
|
if (serial) {
|
|
|
|
*serial = __adb_serial;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-19 13:21:12 +02:00
|
|
|
void adb_set_tcp_specifics(int server_port)
|
|
|
|
{
|
|
|
|
__adb_server_port = server_port;
|
|
|
|
}
|
|
|
|
|
2012-11-14 19:16:17 +01:00
|
|
|
void adb_set_tcp_name(const char* hostname)
|
|
|
|
{
|
|
|
|
__adb_server_name = hostname;
|
|
|
|
}
|
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
static int switch_socket_transport(int fd, std::string* error) {
|
2015-04-27 23:20:17 +02:00
|
|
|
std::string service;
|
|
|
|
if (__adb_serial) {
|
|
|
|
service += "host:transport:";
|
|
|
|
service += __adb_serial;
|
|
|
|
} else {
|
2015-02-26 02:51:28 +01:00
|
|
|
const char* transport_type = "???";
|
2015-04-27 23:20:17 +02:00
|
|
|
switch (__adb_transport) {
|
|
|
|
case kTransportUsb:
|
|
|
|
transport_type = "transport-usb";
|
|
|
|
break;
|
|
|
|
case kTransportLocal:
|
|
|
|
transport_type = "transport-local";
|
|
|
|
break;
|
|
|
|
case kTransportAny:
|
|
|
|
transport_type = "transport-any";
|
|
|
|
break;
|
|
|
|
case kTransportHost:
|
|
|
|
// no switch necessary
|
|
|
|
return 0;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
2015-04-27 23:20:17 +02:00
|
|
|
service += "host:";
|
|
|
|
service += transport_type;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-05-01 02:32:03 +02:00
|
|
|
if (!SendProtocolString(fd, service)) {
|
2015-04-29 17:35:59 +02:00
|
|
|
*error = perror_str("write failure during connection");
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-09-03 02:44:28 +02:00
|
|
|
D("Switch transport in progress");
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
if (!adb_status(fd, error)) {
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
2015-09-03 02:44:28 +02:00
|
|
|
D("Switch transport failed: %s", error->c_str());
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2015-09-03 02:44:28 +02:00
|
|
|
D("Switch transport success");
|
2009-03-04 04:32:55 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
bool adb_status(int fd, std::string* error) {
|
|
|
|
char buf[5];
|
|
|
|
if (!ReadFdExactly(fd, buf, 4)) {
|
|
|
|
*error = perror_str("protocol fault (couldn't read status)");
|
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
if (!memcmp(buf, "OKAY", 4)) {
|
|
|
|
return true;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
if (memcmp(buf, "FAIL", 4)) {
|
|
|
|
*error = android::base::StringPrintf("protocol fault (status %02x %02x %02x %02x?!)",
|
|
|
|
buf[0], buf[1], buf[2], buf[3]);
|
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
ReadProtocolString(fd, error, error);
|
2015-04-29 17:35:59 +02:00
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
int _adb_connect(const std::string& service, std::string* error) {
|
2015-09-03 02:44:28 +02:00
|
|
|
D("_adb_connect: %s", service.c_str());
|
2016-01-15 23:35:54 +01:00
|
|
|
if (service.empty() || service.size() > MAX_PAYLOAD_V1) {
|
2015-05-13 09:02:55 +02:00
|
|
|
*error = android::base::StringPrintf("bad service name length (%zd)",
|
|
|
|
service.size());
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
int fd;
|
2015-07-31 08:07:55 +02:00
|
|
|
std::string reason;
|
2015-04-29 21:28:13 +02:00
|
|
|
if (__adb_server_name) {
|
2015-07-24 02:12:58 +02:00
|
|
|
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;
|
|
|
|
}
|
2015-04-29 21:28:13 +02:00
|
|
|
} else {
|
2015-07-31 08:07:55 +02:00
|
|
|
fd = network_loopback_client(__adb_server_port, SOCK_STREAM, &reason);
|
2015-07-24 02:12:58 +02:00
|
|
|
if (fd == -1) {
|
2015-07-31 08:07:55 +02:00
|
|
|
*error = android::base::StringPrintf("cannot connect to daemon: %s",
|
|
|
|
reason.c_str());
|
2015-07-24 02:12:58 +02:00
|
|
|
return -2;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2016-04-05 22:50:44 +02:00
|
|
|
if ((memcmp(&service[0],"host",4) != 0 || service == "host:reconnect") &&
|
|
|
|
switch_socket_transport(fd, error)) {
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-08-03 19:38:08 +02:00
|
|
|
if (!SendProtocolString(fd, service)) {
|
2015-04-29 17:35:59 +02:00
|
|
|
*error = perror_str("write failure during connection");
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-04-05 22:50:44 +02:00
|
|
|
if (service != "reconnect") {
|
|
|
|
if (!adb_status(fd, error)) {
|
|
|
|
adb_close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-09-03 02:44:28 +02:00
|
|
|
D("_adb_connect: return fd %d", fd);
|
2009-03-04 04:32:55 +01:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
int adb_connect(const std::string& service, std::string* error) {
|
2009-03-04 04:32:55 +01:00
|
|
|
// first query the adb server's version
|
2015-04-29 17:35:59 +02:00
|
|
|
int fd = _adb_connect("host:version", error);
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-09-03 02:44:28 +02:00
|
|
|
D("adb_connect: service %s", service.c_str());
|
2015-04-29 17:35:59 +02:00
|
|
|
if (fd == -2 && __adb_server_name) {
|
2012-11-14 19:16:17 +01:00
|
|
|
fprintf(stderr,"** Cannot start server on remote host\n");
|
2015-08-12 02:05:02 +02:00
|
|
|
// error is the original network connection error
|
2012-11-14 19:16:17 +01:00
|
|
|
return fd;
|
2015-04-29 17:35:59 +02:00
|
|
|
} else if (fd == -2) {
|
2010-04-19 13:21:12 +02:00
|
|
|
fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
|
|
|
|
__adb_server_port);
|
2009-03-04 04:32:55 +01:00
|
|
|
start_server:
|
2015-04-29 17:35:59 +02:00
|
|
|
if (launch_server(__adb_server_port)) {
|
2009-03-04 04:32:55 +01:00
|
|
|
fprintf(stderr,"* failed to start daemon *\n");
|
2015-08-12 02:05:02 +02:00
|
|
|
// launch_server() has already printed detailed error info, so just
|
|
|
|
// return a generic error string about the overall adb_connect()
|
|
|
|
// that the caller requested.
|
|
|
|
*error = "cannot connect to daemon";
|
2009-03-04 04:32:55 +01:00
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
fprintf(stdout,"* daemon started successfully *\n");
|
|
|
|
}
|
|
|
|
/* give the server some time to start properly and detect devices */
|
2009-05-22 02:47:43 +02:00
|
|
|
adb_sleep_ms(3000);
|
2009-03-04 04:32:55 +01:00
|
|
|
// fall through to _adb_connect
|
|
|
|
} else {
|
2015-10-03 04:49:10 +02:00
|
|
|
// If a server is already running, check its version matches.
|
2009-03-04 04:32:55 +01:00
|
|
|
int version = ADB_SERVER_VERSION - 1;
|
|
|
|
|
2015-10-03 04:49:10 +02:00
|
|
|
// If we have a file descriptor, then parse version result.
|
2015-04-29 17:35:59 +02:00
|
|
|
if (fd >= 0) {
|
2015-04-29 21:28:13 +02:00
|
|
|
std::string version_string;
|
|
|
|
if (!ReadProtocolString(fd, &version_string, error)) {
|
2015-10-03 04:49:10 +02:00
|
|
|
adb_close(fd);
|
|
|
|
return -1;
|
2015-04-29 21:28:13 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
ReadOrderlyShutdown(fd);
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
if (sscanf(&version_string[0], "%04x", &version) != 1) {
|
2015-10-07 23:55:10 +02:00
|
|
|
*error = android::base::StringPrintf("cannot parse version string: %s",
|
|
|
|
version_string.c_str());
|
2015-08-12 02:05:02 +02:00
|
|
|
return -1;
|
2015-04-29 21:28:13 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
} else {
|
2015-10-03 04:49:10 +02:00
|
|
|
// If fd is -1 check for "unknown host service" which would
|
|
|
|
// indicate a version of adb that does not support the
|
2015-08-06 04:26:50 +02:00
|
|
|
// version command, in which case we should fall-through to kill it.
|
|
|
|
if (*error != "unknown host service") {
|
2009-03-04 04:32:55 +01:00
|
|
|
return fd;
|
2015-04-29 17:35:59 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
if (version != ADB_SERVER_VERSION) {
|
2015-10-03 04:49:10 +02:00
|
|
|
printf("adb server version (%d) doesn't match this client (%d); killing...\n",
|
|
|
|
version, ADB_SERVER_VERSION);
|
2015-04-29 17:35:59 +02:00
|
|
|
fd = _adb_connect("host:kill", error);
|
2015-08-12 02:05:02 +02:00
|
|
|
if (fd >= 0) {
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
ReadOrderlyShutdown(fd);
|
2015-08-12 02:05:02 +02:00
|
|
|
adb_close(fd);
|
|
|
|
} else {
|
|
|
|
// If we couldn't connect to the server or had some other error,
|
|
|
|
// report it, but still try to start the server.
|
|
|
|
fprintf(stderr, "error: %s\n", error->c_str());
|
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
|
|
|
/* XXX can we better detect its death? */
|
|
|
|
adb_sleep_ms(2000);
|
|
|
|
goto start_server;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the command is start-server, we are done.
|
2015-04-29 21:28:13 +02:00
|
|
|
if (service == "host:start-server") {
|
2009-03-04 04:32:55 +01:00
|
|
|
return 0;
|
2015-04-29 17:35:59 +02:00
|
|
|
}
|
2009-03-04 04:32:55 +01:00
|
|
|
|
2015-04-29 17:35:59 +02:00
|
|
|
fd = _adb_connect(service, error);
|
|
|
|
if (fd == -1) {
|
2015-09-03 02:44:28 +02:00
|
|
|
D("_adb_connect error: %s", error->c_str());
|
2013-10-18 22:58:48 +02:00
|
|
|
} else if(fd == -2) {
|
2012-11-14 19:16:17 +01:00
|
|
|
fprintf(stderr,"** daemon still not running\n");
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
2015-09-03 02:44:28 +02:00
|
|
|
D("adb_connect: return fd %d", fd);
|
2009-03-04 04:32:55 +01:00
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-30 02:55:19 +02:00
|
|
|
bool adb_command(const std::string& service) {
|
|
|
|
std::string error;
|
|
|
|
int fd = adb_connect(service, &error);
|
2015-04-29 17:35:59 +02:00
|
|
|
if (fd < 0) {
|
2015-05-30 02:55:19 +02:00
|
|
|
fprintf(stderr, "error: %s\n", error.c_str());
|
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-05-30 02:55:19 +02:00
|
|
|
if (!adb_status(fd, &error)) {
|
|
|
|
fprintf(stderr, "error: %s\n", error.c_str());
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
2015-05-30 02:55:19 +02:00
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
ReadOrderlyShutdown(fd);
|
|
|
|
adb_close(fd);
|
2015-05-30 02:55:19 +02:00
|
|
|
return true;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
bool adb_query(const std::string& service, std::string* result, std::string* error) {
|
2015-09-03 02:44:28 +02:00
|
|
|
D("adb_query: %s", service.c_str());
|
2015-04-29 17:35:59 +02:00
|
|
|
int fd = adb_connect(service, error);
|
|
|
|
if (fd < 0) {
|
2015-07-18 21:21:30 +02:00
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 21:28:13 +02:00
|
|
|
result->clear();
|
|
|
|
if (!ReadProtocolString(fd, result, error)) {
|
2009-03-04 04:32:55 +01:00
|
|
|
adb_close(fd);
|
2015-04-29 21:28:13 +02:00
|
|
|
return false;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
adb: fix adb client running out of sockets on Windows
Background
==========
On Windows, if you run "adb shell exit" in a loop in two windows,
eventually the adb client will be unable to connect to the adb server. I
think connect() is returning WSAEADDRINUSE: "Only one usage of each
socket address (protocol/network address/port) is normally permitted.
(10048)". The Windows System Event Log may also show Event 4227, Tcpip.
Netstat output is filled with:
# for the adb server
TCP 127.0.0.1:5037 127.0.0.1:65523 TIME_WAIT
# for the adb client
TCP 127.0.0.1:65523 127.0.0.1:5037 TIME_WAIT
The error probably means that the client is running out of free
address:port pairs.
The first netstat line is unavoidable, but the second line exists
because the adb client is not waiting for orderly/graceful shutdown of
the socket, and that is apparently required on Windows to get rid of the
second line. For more info, see
https://github.com/CompareAndSwap/SocketCloseTest .
This is exacerbated by the fact that "adb shell exit" makes 4 socket
connections to the adb server: 1) host:version, 2) host:features, 3)
host:version (again), 4) shell:exit. Also exacerbating is the fact that
the adb protocol is length-prefixed so the client typically does not
have to 'read() until zero' which effectively waits for orderly/graceful
shutdown.
The Fix
=======
Introduce a function, ReadOrderlyShutdown(), that should be called in
the adb client to wait for the server to close its socket, before
closing the client socket.
I reviewed all code where the adb client makes a connection to the adb
server and added ReadOrderlyShutdown() when it made sense. I wasn't able
to add it to the following:
* interactive_shell: this doesn't matter because this is interactive and
thus can't be run fast enough to use up ports.
* adb sideload: I couldn't get enough test coverage and I don't think
this is being called frequently enough to be a problem.
* send_shell_command, backup, adb_connect_command, adb shell, adb
exec-out, install_multiple_app, adb_send_emulator_command: These
already wait for server socket shutdown since they already call
recv() until zero.
* restore, adb exec-in: protocol design can't have the server close
first.
* adb start-server: no fd is actually returned
* create_local_service_socket, local_connect_arbitrary_ports,
connect_device: probably called rarely enough not to be a problem.
Also in this change
===================
* Clarify comments in when adb_shutdown() is called before exit().
* add some missing adb_close() in adb sideload.
* Fixup error handling and comments in adb_send_emulator_command().
* Make SyncConnection::SendQuit return a success boolean.
* Add unittest for adb emu kill command. This gets code coverage over
this very careful piece of code.
Change-Id: Iad0b1336f5b74186af2cd35f7ea827d0fa77a17c
Signed-off-by: Spencer Low <CompareAndSwap@gmail.com>
2015-10-15 02:32:44 +02:00
|
|
|
|
|
|
|
ReadOrderlyShutdown(fd);
|
|
|
|
adb_close(fd);
|
2015-04-29 21:28:13 +02:00
|
|
|
return true;
|
2009-03-04 04:32:55 +01:00
|
|
|
}
|
2016-02-01 04:12:26 +01:00
|
|
|
|
|
|
|
std::string format_host_command(const char* command, TransportType type, const char* serial) {
|
|
|
|
if (serial) {
|
|
|
|
return android::base::StringPrintf("host-serial:%s:%s", serial, command);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* prefix = "host";
|
|
|
|
if (type == kTransportUsb) {
|
|
|
|
prefix = "host-usb";
|
|
|
|
} else if (type == kTransportLocal) {
|
|
|
|
prefix = "host-local";
|
|
|
|
}
|
|
|
|
return android::base::StringPrintf("%s:%s", prefix, command);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) {
|
|
|
|
std::string result;
|
|
|
|
if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) {
|
|
|
|
*feature_set = StringToFeatureSet(result);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
feature_set->clear();
|
|
|
|
return false;
|
|
|
|
}
|