am 97267755: am c3358875: am 6e7343b8: Merge "adb: implement "adb reverse <local> <remote>""
* commit '972677557bd2c3a0678a945765783e85c7ec7b9c': adb: implement "adb reverse <local> <remote>"
This commit is contained in:
commit
7291ac6082
|
@ -240,3 +240,20 @@ sync:
|
|||
This starts the file synchronisation service, used to implement "adb push"
|
||||
and "adb pull". Since this service is pretty complex, it will be detailed
|
||||
in a companion document named SYNC.TXT
|
||||
|
||||
reverse:<forward-command>
|
||||
This implements the 'adb reverse' feature, i.e. the ability to reverse
|
||||
socket connections from a device to the host. <forward-command> is one
|
||||
of the forwarding commands that are described above, as in:
|
||||
|
||||
list-forward
|
||||
forward:<local>;<remote>
|
||||
forward:norebind:<local>;<remote>
|
||||
killforward-all
|
||||
killforward:<local>
|
||||
|
||||
Note that in this case, <local> corresponds to the socket on the device
|
||||
and <remote> corresponds to the socket on the host.
|
||||
|
||||
The output of reverse:list-forward is the same as host:list-forward
|
||||
except that <serial> will be just 'host'.
|
||||
|
|
221
adb/adb.c
221
adb/adb.c
|
@ -318,7 +318,18 @@ static size_t fill_connect_data(char *buf, size_t bufsize)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void send_msg_with_okay(int fd, char* msg, size_t msglen) {
|
||||
#if !ADB_HOST
|
||||
static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
|
||||
char header[5];
|
||||
if (msglen > 0xffff)
|
||||
msglen = 0xffff;
|
||||
snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
|
||||
writex(fd, header, 4);
|
||||
writex(fd, msg, msglen);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
|
||||
char header[9];
|
||||
if (msglen > 0xffff)
|
||||
msglen = 0xffff;
|
||||
|
@ -1427,6 +1438,120 @@ int adb_main(int is_daemon, int server_port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Try to handle a network forwarding request.
|
||||
// This returns 1 on success, 0 on failure, and -1 to indicate this is not
|
||||
// a forwarding-related request.
|
||||
int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
|
||||
{
|
||||
if (!strcmp(service, "list-forward")) {
|
||||
// Create the list of forward redirections.
|
||||
int buffer_size = format_listeners(NULL, 0);
|
||||
// Add one byte for the trailing zero.
|
||||
char* buffer = malloc(buffer_size + 1);
|
||||
if (buffer == NULL) {
|
||||
sendfailmsg(reply_fd, "not enough memory");
|
||||
return 1;
|
||||
}
|
||||
(void) format_listeners(buffer, buffer_size + 1);
|
||||
#if ADB_HOST
|
||||
send_msg_with_okay(reply_fd, buffer, buffer_size);
|
||||
#else
|
||||
send_msg_with_header(reply_fd, buffer, buffer_size);
|
||||
#endif
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(service, "killforward-all")) {
|
||||
remove_all_listeners();
|
||||
#if ADB_HOST
|
||||
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
|
||||
adb_write(reply_fd, "OKAY", 4);
|
||||
#endif
|
||||
adb_write(reply_fd, "OKAY", 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(service, "forward:",8) ||
|
||||
!strncmp(service, "killforward:",12)) {
|
||||
char *local, *remote, *err;
|
||||
int r;
|
||||
atransport *transport;
|
||||
|
||||
int createForward = strncmp(service, "kill", 4);
|
||||
int no_rebind = 0;
|
||||
|
||||
local = strchr(service, ':') + 1;
|
||||
|
||||
// Handle forward:norebind:<local>... here
|
||||
if (createForward && !strncmp(local, "norebind:", 9)) {
|
||||
no_rebind = 1;
|
||||
local = strchr(local, ':') + 1;
|
||||
}
|
||||
|
||||
remote = strchr(local,';');
|
||||
|
||||
if (createForward) {
|
||||
// Check forward: parameter format: '<local>;<remote>'
|
||||
if(remote == 0) {
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*remote++ = 0;
|
||||
if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
// Check killforward: parameter format: '<local>'
|
||||
if (local[0] == 0) {
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
|
||||
if (!transport) {
|
||||
sendfailmsg(reply_fd, err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (createForward) {
|
||||
r = install_listener(local, remote, transport, no_rebind);
|
||||
} else {
|
||||
r = remove_listener(local, transport);
|
||||
}
|
||||
if(r == 0) {
|
||||
#if ADB_HOST
|
||||
/* On the host: 1st OKAY is connect, 2nd OKAY is status */
|
||||
writex(reply_fd, "OKAY", 4);
|
||||
#endif
|
||||
writex(reply_fd, "OKAY", 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (createForward) {
|
||||
const char* message;
|
||||
switch (r) {
|
||||
case INSTALL_STATUS_CANNOT_BIND:
|
||||
message = "cannot bind to socket";
|
||||
break;
|
||||
case INSTALL_STATUS_CANNOT_REBIND:
|
||||
message = "cannot rebind existing socket";
|
||||
break;
|
||||
default:
|
||||
message = "internal error";
|
||||
}
|
||||
sendfailmsg(reply_fd, message);
|
||||
} else {
|
||||
sendfailmsg(reply_fd, "cannot remove listener");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
|
||||
{
|
||||
atransport *transport = NULL;
|
||||
|
@ -1547,97 +1672,9 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
|
|||
}
|
||||
#endif // ADB_HOST
|
||||
|
||||
if(!strcmp(service,"list-forward")) {
|
||||
// Create the list of forward redirections.
|
||||
int buffer_size = format_listeners(NULL, 0);
|
||||
// Add one byte for the trailing zero.
|
||||
char* buffer = malloc(buffer_size+1);
|
||||
(void) format_listeners(buffer, buffer_size+1);
|
||||
send_msg_with_okay(reply_fd, buffer, buffer_size);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(service,"killforward-all")) {
|
||||
remove_all_listeners();
|
||||
adb_write(reply_fd, "OKAYOKAY", 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!strncmp(service,"forward:",8) ||
|
||||
!strncmp(service,"killforward:",12)) {
|
||||
char *local, *remote, *err;
|
||||
int r;
|
||||
atransport *transport;
|
||||
|
||||
int createForward = strncmp(service,"kill",4);
|
||||
int no_rebind = 0;
|
||||
|
||||
local = strchr(service, ':') + 1;
|
||||
|
||||
// Handle forward:norebind:<local>... here
|
||||
if (createForward && !strncmp(local, "norebind:", 9)) {
|
||||
no_rebind = 1;
|
||||
local = strchr(local, ':') + 1;
|
||||
}
|
||||
|
||||
remote = strchr(local,';');
|
||||
|
||||
if (createForward) {
|
||||
// Check forward: parameter format: '<local>;<remote>'
|
||||
if(remote == 0) {
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*remote++ = 0;
|
||||
if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Check killforward: parameter format: '<local>'
|
||||
if (local[0] == 0) {
|
||||
sendfailmsg(reply_fd, "malformed forward spec");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
|
||||
if (!transport) {
|
||||
sendfailmsg(reply_fd, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (createForward) {
|
||||
r = install_listener(local, remote, transport, no_rebind);
|
||||
} else {
|
||||
r = remove_listener(local, transport);
|
||||
}
|
||||
if(r == 0) {
|
||||
/* 1st OKAY is connect, 2nd OKAY is status */
|
||||
writex(reply_fd, "OKAYOKAY", 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (createForward) {
|
||||
const char* message;
|
||||
switch (r) {
|
||||
case INSTALL_STATUS_CANNOT_BIND:
|
||||
message = "cannot bind to socket";
|
||||
break;
|
||||
case INSTALL_STATUS_CANNOT_REBIND:
|
||||
message = "cannot rebind existing socket";
|
||||
break;
|
||||
default:
|
||||
message = "internal error";
|
||||
}
|
||||
sendfailmsg(reply_fd, message);
|
||||
} else {
|
||||
sendfailmsg(reply_fd, "cannot remove listener");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int ret = handle_forward_request(service, ttype, serial, reply_fd);
|
||||
if (ret >= 0)
|
||||
return ret - 1;
|
||||
|
||||
if(!strncmp(service,"get-state",strlen("get-state"))) {
|
||||
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
|
||||
|
|
|
@ -323,6 +323,8 @@ asocket* create_jdwp_tracker_service_socket();
|
|||
int create_jdwp_connection_fd(int jdwp_pid);
|
||||
#endif
|
||||
|
||||
int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd);
|
||||
|
||||
#if !ADB_HOST
|
||||
typedef enum {
|
||||
BACKUP,
|
||||
|
|
|
@ -137,6 +137,19 @@ void help()
|
|||
" if <local> is already forwarded\n"
|
||||
" adb forward --remove <local> - remove a specific forward socket connection\n"
|
||||
" adb forward --remove-all - remove all forward socket connections\n"
|
||||
" adb reverse --list - list all reverse socket connections from device\n"
|
||||
" adb reverse <remote> <local> - reverse socket connections\n"
|
||||
" reverse specs are one of:\n"
|
||||
" tcp:<port>\n"
|
||||
" localabstract:<unix domain socket name>\n"
|
||||
" localreserved:<unix domain socket name>\n"
|
||||
" localfilesystem:<unix domain socket name>\n"
|
||||
" adb reverse --norebind <remote> <local>\n"
|
||||
" - same as 'adb reverse <remote> <local>' but fails\n"
|
||||
" if <remote> is already reversed.\n"
|
||||
" adb reverse --remove <remote>\n"
|
||||
" - remove a specific reversed socket connection\n"
|
||||
" adb reverse --remove-all - remove all reversed socket connections from device\n"
|
||||
" adb jdwp - list PIDs of processes hosting a JDWP transport\n"
|
||||
" adb install [-l] [-r] [-d] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n"
|
||||
" - push this package file to the device and install it\n"
|
||||
|
@ -1308,8 +1321,11 @@ top:
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(!strcmp(argv[0], "forward")) {
|
||||
if(!strcmp(argv[0], "forward") ||
|
||||
!strcmp(argv[0], "reverse"))
|
||||
{
|
||||
char host_prefix[64];
|
||||
char reverse = (char) !strcmp(argv[0], "reverse");
|
||||
char remove = 0;
|
||||
char remove_all = 0;
|
||||
char list = 0;
|
||||
|
@ -1338,15 +1354,19 @@ top:
|
|||
}
|
||||
|
||||
// Determine the <host-prefix> for this command.
|
||||
if (serial) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
|
||||
serial);
|
||||
} else if (ttype == kTransportUsb) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-usb");
|
||||
} else if (ttype == kTransportLocal) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-local");
|
||||
if (reverse) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "reverse");
|
||||
} else {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host");
|
||||
if (serial) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
|
||||
serial);
|
||||
} else if (ttype == kTransportUsb) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-usb");
|
||||
} else if (ttype == kTransportLocal) {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host-local");
|
||||
} else {
|
||||
snprintf(host_prefix, sizeof host_prefix, "host");
|
||||
}
|
||||
}
|
||||
|
||||
// Implement forward --list
|
||||
|
|
|
@ -141,6 +141,17 @@ cleanup:
|
|||
adb_close(fd);
|
||||
}
|
||||
|
||||
void reverse_service(int fd, void* arg)
|
||||
{
|
||||
const char* command = arg;
|
||||
|
||||
if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
|
||||
sendfailmsg(fd, "not a reverse forwarding command");
|
||||
}
|
||||
free(arg);
|
||||
adb_close(fd);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int create_service_thread(void (*func)(int, void *), void *cookie)
|
||||
|
@ -385,6 +396,16 @@ int service_to_fd(const char *name)
|
|||
ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
|
||||
} else if(!strncmp(name, "usb:", 4)) {
|
||||
ret = create_service_thread(restart_usb_service, NULL);
|
||||
} else if (!strncmp(name, "reverse:", 8)) {
|
||||
char* cookie = strdup(name + 8);
|
||||
if (cookie == NULL) {
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = create_service_thread(reverse_service, cookie);
|
||||
if (ret < 0) {
|
||||
free(cookie);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ret >= 0) {
|
||||
|
|
Loading…
Reference in New Issue