Loading adb/adb.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -1134,7 +1134,9 @@ bool handle_host_request(const char* service, TransportType type, const char* se std::string host; int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; std::string error; if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) { if (address.starts_with("vsock:")) { serial = address; } else if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) { SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s", address.c_str(), error.c_str())); return true; Loading adb/daemon/transport_qemu.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ void qemu_socket_thread(int port) { /* This could be an older version of the emulator, that doesn't * implement adb QEMUD service. Fall back to the old TCP way. */ D("adb service is not available. Falling back to TCP socket."); std::thread(server_socket_thread, port).detach(); std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach(); return; } Loading adb/socket_spec.cpp +116 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,11 @@ using android::base::StringPrintf; #define ADB_WINDOWS 0 #endif #if ADB_LINUX #include <sys/socket.h> #include "sysdeps/vm_sockets.h" #endif // Not static because it is used in commandline.c. int gListenAll = 0; Loading Loading @@ -174,6 +179,62 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std return true; } return false; } else if (address.starts_with("vsock:")) { #if ADB_LINUX std::string spec_str(address); std::vector<std::string> fragments = android::base::Split(spec_str, ":"); unsigned int port_value = port ? *port : 0; if (fragments.size() != 2 && fragments.size() != 3) { *error = android::base::StringPrintf("expected vsock:cid or vsock:port:cid in '%s'", spec_str.c_str()); errno = EINVAL; return false; } unsigned int cid = 0; if (!android::base::ParseUint(fragments[1], &cid)) { *error = android::base::StringPrintf("could not parse vsock cid in '%s'", spec_str.c_str()); errno = EINVAL; return false; } if (fragments.size() == 3 && !android::base::ParseUint(fragments[2], &port_value)) { *error = android::base::StringPrintf("could not parse vsock port in '%s'", spec_str.c_str()); errno = EINVAL; return false; } if (port_value == 0) { *error = android::base::StringPrintf("vsock port was not provided."); errno = EINVAL; return false; } fd->reset(socket(AF_VSOCK, SOCK_STREAM, 0)); if (fd->get() == -1) { *error = "could not open vsock socket"; return false; } sockaddr_vm addr{}; addr.svm_family = AF_VSOCK; addr.svm_port = port_value; addr.svm_cid = cid; if (serial) { *serial = android::base::StringPrintf("vsock:%u:%d", cid, port_value); } if (connect(fd->get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { int error_num = errno; *error = android::base::StringPrintf("could not connect to vsock address '%s'", spec_str.c_str()); errno = error_num; return false; } if (port) { *port = port_value; } return true; #else // ADB_LINUX *error = "vsock is only supported on linux"; return false; #endif // ADB_LINUX } for (const auto& it : kLocalSocketTypes) { Loading @@ -187,6 +248,9 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace, SOCK_STREAM, error)); if (serial) { *serial = address; } return true; } } Loading @@ -196,7 +260,7 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std return false; } int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) { int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) { if (spec.starts_with("tcp:")) { std::string hostname; int port; Loading @@ -215,10 +279,59 @@ int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_ return -1; } if (result >= 0 && port == 0 && resolved_tcp_port) { *resolved_tcp_port = adb_socket_get_local_port(result); if (result >= 0 && resolved_port) { *resolved_port = adb_socket_get_local_port(result); } return result; } else if (spec.starts_with("vsock:")) { #if ADB_LINUX std::string spec_str(spec); std::vector<std::string> fragments = android::base::Split(spec_str, ":"); if (fragments.size() != 2) { *error = "given vsock server socket string was invalid"; return -1; } int port; if (!android::base::ParseInt(fragments[1], &port)) { *error = "could not parse vsock port"; errno = EINVAL; return -1; } else if (port < 0) { *error = "vsock port was negative."; errno = EINVAL; return -1; } unique_fd serverfd(socket(AF_VSOCK, SOCK_STREAM, 0)); if (serverfd == -1) { int error_num = errno; *error = android::base::StringPrintf("could not create vsock server: '%s'", strerror(error_num)); errno = error_num; return -1; } sockaddr_vm addr{}; addr.svm_family = AF_VSOCK; addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port; addr.svm_cid = VMADDR_CID_ANY; socklen_t addr_len = sizeof(addr); if (bind(serverfd, reinterpret_cast<struct sockaddr*>(&addr), addr_len)) { return -1; } if (listen(serverfd, 4)) { return -1; } if (serverfd >= 0 && resolved_port) { if (getsockname(serverfd, reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) { *resolved_port = addr.svm_port; } else { return -1; } } return serverfd.release(); #else // ADB_LINUX *error = "vsock is only supported on linux"; return -1; #endif // ADB_LINUX } for (const auto& it : kLocalSocketTypes) { Loading adb/sockets.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -609,6 +609,14 @@ bool parse_host_service(std::string_view* out_serial, std::string_view* out_comm return false; } } if (command.starts_with("vsock:")) { // vsock serials are vsock:cid:port, which have an extra colon compared to tcp. size_t next_colon = command.find(':'); if (next_colon == std::string::npos) { return false; } consume(next_colon + 1); } bool found_address = false; if (command[0] == '[') { Loading adb/sysdeps/vm_sockets.h 0 → 100644 +49 −0 Original line number Diff line number Diff line #if __BIONIC__ #include <linux/vm_sockets.h> #else /**************************************************************************** **************************************************************************** *** *** This header was automatically generated from a Linux kernel header *** of the same name, to make information necessary for userspace to *** call into the kernel available to libc. It contains only constants, *** structures, and macros generated from the original header, and thus, *** contains no copyrightable information. *** *** Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h *** **************************************************************************** ****************************************************************************/ #ifndef _UAPI_VM_SOCKETS_H #define _UAPI_VM_SOCKETS_H #include <linux/socket.h> #define SO_VM_SOCKETS_BUFFER_SIZE 0 #define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1 #define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2 #define SO_VM_SOCKETS_PEER_HOST_VM_ID 3 #define SO_VM_SOCKETS_TRUSTED 5 #define SO_VM_SOCKETS_CONNECT_TIMEOUT 6 #define SO_VM_SOCKETS_NONBLOCK_TXRX 7 #define VMADDR_CID_ANY -1U #define VMADDR_PORT_ANY -1U #define VMADDR_CID_HYPERVISOR 0 #define VMADDR_CID_RESERVED 1 #define VMADDR_CID_HOST 2 #define VM_SOCKETS_INVALID_VERSION -1U #define VM_SOCKETS_VERSION_EPOCH(_v) (((_v)&0xFF000000) >> 24) #define VM_SOCKETS_VERSION_MAJOR(_v) (((_v)&0x00FF0000) >> 16) #define VM_SOCKETS_VERSION_MINOR(_v) (((_v)&0x0000FFFF)) struct sockaddr_vm { __kernel_sa_family_t svm_family; unsigned short svm_reserved1; unsigned int svm_port; unsigned int svm_cid; unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) - sizeof(unsigned int) - sizeof(unsigned int)]; }; #define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) #ifndef AF_VSOCK #define AF_VSOCK 40 #endif #endif #endif Loading
adb/adb.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -1134,7 +1134,9 @@ bool handle_host_request(const char* service, TransportType type, const char* se std::string host; int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; std::string error; if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) { if (address.starts_with("vsock:")) { serial = address; } else if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) { SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s", address.c_str(), error.c_str())); return true; Loading
adb/daemon/transport_qemu.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ void qemu_socket_thread(int port) { /* This could be an older version of the emulator, that doesn't * implement adb QEMUD service. Fall back to the old TCP way. */ D("adb service is not available. Falling back to TCP socket."); std::thread(server_socket_thread, port).detach(); std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach(); return; } Loading
adb/socket_spec.cpp +116 −3 Original line number Diff line number Diff line Loading @@ -46,6 +46,11 @@ using android::base::StringPrintf; #define ADB_WINDOWS 0 #endif #if ADB_LINUX #include <sys/socket.h> #include "sysdeps/vm_sockets.h" #endif // Not static because it is used in commandline.c. int gListenAll = 0; Loading Loading @@ -174,6 +179,62 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std return true; } return false; } else if (address.starts_with("vsock:")) { #if ADB_LINUX std::string spec_str(address); std::vector<std::string> fragments = android::base::Split(spec_str, ":"); unsigned int port_value = port ? *port : 0; if (fragments.size() != 2 && fragments.size() != 3) { *error = android::base::StringPrintf("expected vsock:cid or vsock:port:cid in '%s'", spec_str.c_str()); errno = EINVAL; return false; } unsigned int cid = 0; if (!android::base::ParseUint(fragments[1], &cid)) { *error = android::base::StringPrintf("could not parse vsock cid in '%s'", spec_str.c_str()); errno = EINVAL; return false; } if (fragments.size() == 3 && !android::base::ParseUint(fragments[2], &port_value)) { *error = android::base::StringPrintf("could not parse vsock port in '%s'", spec_str.c_str()); errno = EINVAL; return false; } if (port_value == 0) { *error = android::base::StringPrintf("vsock port was not provided."); errno = EINVAL; return false; } fd->reset(socket(AF_VSOCK, SOCK_STREAM, 0)); if (fd->get() == -1) { *error = "could not open vsock socket"; return false; } sockaddr_vm addr{}; addr.svm_family = AF_VSOCK; addr.svm_port = port_value; addr.svm_cid = cid; if (serial) { *serial = android::base::StringPrintf("vsock:%u:%d", cid, port_value); } if (connect(fd->get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { int error_num = errno; *error = android::base::StringPrintf("could not connect to vsock address '%s'", spec_str.c_str()); errno = error_num; return false; } if (port) { *port = port_value; } return true; #else // ADB_LINUX *error = "vsock is only supported on linux"; return false; #endif // ADB_LINUX } for (const auto& it : kLocalSocketTypes) { Loading @@ -187,6 +248,9 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace, SOCK_STREAM, error)); if (serial) { *serial = address; } return true; } } Loading @@ -196,7 +260,7 @@ bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std return false; } int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) { int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) { if (spec.starts_with("tcp:")) { std::string hostname; int port; Loading @@ -215,10 +279,59 @@ int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_ return -1; } if (result >= 0 && port == 0 && resolved_tcp_port) { *resolved_tcp_port = adb_socket_get_local_port(result); if (result >= 0 && resolved_port) { *resolved_port = adb_socket_get_local_port(result); } return result; } else if (spec.starts_with("vsock:")) { #if ADB_LINUX std::string spec_str(spec); std::vector<std::string> fragments = android::base::Split(spec_str, ":"); if (fragments.size() != 2) { *error = "given vsock server socket string was invalid"; return -1; } int port; if (!android::base::ParseInt(fragments[1], &port)) { *error = "could not parse vsock port"; errno = EINVAL; return -1; } else if (port < 0) { *error = "vsock port was negative."; errno = EINVAL; return -1; } unique_fd serverfd(socket(AF_VSOCK, SOCK_STREAM, 0)); if (serverfd == -1) { int error_num = errno; *error = android::base::StringPrintf("could not create vsock server: '%s'", strerror(error_num)); errno = error_num; return -1; } sockaddr_vm addr{}; addr.svm_family = AF_VSOCK; addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port; addr.svm_cid = VMADDR_CID_ANY; socklen_t addr_len = sizeof(addr); if (bind(serverfd, reinterpret_cast<struct sockaddr*>(&addr), addr_len)) { return -1; } if (listen(serverfd, 4)) { return -1; } if (serverfd >= 0 && resolved_port) { if (getsockname(serverfd, reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) { *resolved_port = addr.svm_port; } else { return -1; } } return serverfd.release(); #else // ADB_LINUX *error = "vsock is only supported on linux"; return -1; #endif // ADB_LINUX } for (const auto& it : kLocalSocketTypes) { Loading
adb/sockets.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -609,6 +609,14 @@ bool parse_host_service(std::string_view* out_serial, std::string_view* out_comm return false; } } if (command.starts_with("vsock:")) { // vsock serials are vsock:cid:port, which have an extra colon compared to tcp. size_t next_colon = command.find(':'); if (next_colon == std::string::npos) { return false; } consume(next_colon + 1); } bool found_address = false; if (command[0] == '[') { Loading
adb/sysdeps/vm_sockets.h 0 → 100644 +49 −0 Original line number Diff line number Diff line #if __BIONIC__ #include <linux/vm_sockets.h> #else /**************************************************************************** **************************************************************************** *** *** This header was automatically generated from a Linux kernel header *** of the same name, to make information necessary for userspace to *** call into the kernel available to libc. It contains only constants, *** structures, and macros generated from the original header, and thus, *** contains no copyrightable information. *** *** Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h *** **************************************************************************** ****************************************************************************/ #ifndef _UAPI_VM_SOCKETS_H #define _UAPI_VM_SOCKETS_H #include <linux/socket.h> #define SO_VM_SOCKETS_BUFFER_SIZE 0 #define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1 #define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2 #define SO_VM_SOCKETS_PEER_HOST_VM_ID 3 #define SO_VM_SOCKETS_TRUSTED 5 #define SO_VM_SOCKETS_CONNECT_TIMEOUT 6 #define SO_VM_SOCKETS_NONBLOCK_TXRX 7 #define VMADDR_CID_ANY -1U #define VMADDR_PORT_ANY -1U #define VMADDR_CID_HYPERVISOR 0 #define VMADDR_CID_RESERVED 1 #define VMADDR_CID_HOST 2 #define VM_SOCKETS_INVALID_VERSION -1U #define VM_SOCKETS_VERSION_EPOCH(_v) (((_v)&0xFF000000) >> 24) #define VM_SOCKETS_VERSION_MAJOR(_v) (((_v)&0x00FF0000) >> 16) #define VM_SOCKETS_VERSION_MINOR(_v) (((_v)&0x0000FFFF)) struct sockaddr_vm { __kernel_sa_family_t svm_family; unsigned short svm_reserved1; unsigned int svm_port; unsigned int svm_cid; unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) - sizeof(unsigned int) - sizeof(unsigned int)]; }; #define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) #ifndef AF_VSOCK #define AF_VSOCK 40 #endif #endif #endif