diff options
author | 2021-04-01 20:47:09 +0000 | |
---|---|---|
committer | 2021-04-01 20:47:09 +0000 | |
commit | 8911d46baf682d95a08efd678aaee7fc15c9767a (patch) | |
tree | bbe193689cd384b4345a4ab5c4edcde86b2b4793 /libs/binder/RpcConnection.cpp | |
parent | 520cc33d760c3d3385304e36a73012f2b1ec8bba (diff) | |
parent | f6ec4632823f16f214dfc92cff938485aa6c2f1e (diff) |
Merge changes I44a66c3b,Ieb3273f0
* changes:
Revert^2 "libbinder: binderRpcTest on host"
Reland libbinder: vsock support for RPC
Diffstat (limited to 'libs/binder/RpcConnection.cpp')
-rw-r--r-- | libs/binder/RpcConnection.cpp | 158 |
1 files changed, 104 insertions, 54 deletions
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp index 83a1618e9f..dab3246fc5 100644 --- a/libs/binder/RpcConnection.cpp +++ b/libs/binder/RpcConnection.cpp @@ -20,6 +20,7 @@ #include <binder/Parcel.h> #include <binder/Stability.h> +#include <utils/String8.h> #include "RpcState.h" #include "RpcWireFormat.h" @@ -29,14 +30,20 @@ #include <sys/un.h> #include <unistd.h> -#if defined(__GLIBC__) +#ifdef __GLIBC__ extern "C" pid_t gettid(); #endif +#ifdef __BIONIC__ +#include <linux/vm_sockets.h> +#endif + namespace android { using base::unique_fd; +RpcConnection::SocketAddress::~SocketAddress() {} + RpcConnection::RpcConnection() { LOG_RPC_DETAIL("RpcConnection created %p", this); @@ -50,65 +57,68 @@ sp<RpcConnection> RpcConnection::make() { return new RpcConnection; } -bool RpcConnection::setupUnixDomainServer(const char* path) { - LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Only supports one server now"); - - unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0))); - if (serverFd == -1) { - ALOGE("Could not create socket at %s: %s", path, strerror(errno)); - return false; +class UnixSocketAddress : public RpcConnection::SocketAddress { +public: + explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) { + unsigned int pathLen = strlen(path) + 1; + LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "%u %s", pathLen, path); + memcpy(mAddr.sun_path, path, pathLen); } - - struct sockaddr_un addr = { - .sun_family = AF_UNIX, - }; - - unsigned int pathLen = strlen(path) + 1; - LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen); - memcpy(addr.sun_path, path, pathLen); - - if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) { - ALOGE("Could not bind socket at %s: %s", path, strerror(errno)); - return false; + virtual ~UnixSocketAddress() {} + std::string toString() const override { + return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)), + mAddr.sun_path) + .c_str(); } + const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } + size_t addrSize() const override { return sizeof(mAddr); } - if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) { - ALOGE("Could not listen socket at %s: %s", path, strerror(errno)); - return false; - } +private: + sockaddr_un mAddr; +}; - mServer = std::move(serverFd); - return true; +bool RpcConnection::setupUnixDomainServer(const char* path) { + return addServer(UnixSocketAddress(path)); } bool RpcConnection::addUnixDomainClient(const char* path) { - LOG_RPC_DETAIL("Connecting on path: %s", path); + return addClient(UnixSocketAddress(path)); +} - unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0))); - if (serverFd == -1) { - ALOGE("Could not create socket at %s: %s", path, strerror(errno)); - return false; +#ifdef __BIONIC__ + +class VsockSocketAddress : public RpcConnection::SocketAddress { +public: + VsockSocketAddress(unsigned int cid, unsigned int port) + : mAddr({ + .svm_family = AF_VSOCK, + .svm_port = port, + .svm_cid = cid, + }) {} + virtual ~VsockSocketAddress() {} + std::string toString() const override { + return String8::format("cid %du port %du", mAddr.svm_cid, mAddr.svm_port).c_str(); } + const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } + size_t addrSize() const override { return sizeof(mAddr); } - struct sockaddr_un addr = { - .sun_family = AF_UNIX, - }; +private: + sockaddr_vm mAddr; +}; - unsigned int pathLen = strlen(path) + 1; - LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen); - memcpy(addr.sun_path, path, pathLen); +bool RpcConnection::setupVsockServer(unsigned int port) { + // realizing value w/ this type at compile time to avoid ubsan abort + constexpr unsigned int kAnyCid = VMADDR_CID_ANY; - if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) { - ALOGE("Could not connect socket at %s: %s", path, strerror(errno)); - return false; - } - - LOG_RPC_DETAIL("Unix domain client with fd %d", serverFd.get()); + return addServer(VsockSocketAddress(kAnyCid, port)); +} - addClient(std::move(serverFd)); - return true; +bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) { + return addClient(VsockSocketAddress(cid, port)); } +#endif // __BIONIC__ + sp<IBinder> RpcConnection::getRootObject() { ExclusiveSocket socket(this, SocketUse::CLIENT); return state()->getRootObject(socket.fd(), this); @@ -130,11 +140,8 @@ status_t RpcConnection::sendDecStrong(const RpcAddress& address) { void RpcConnection::join() { // establish a connection { - struct sockaddr_un clientSa; - socklen_t clientSaLen = sizeof(clientSa); - - unique_fd clientFd(TEMP_FAILURE_RETRY( - accept4(mServer.get(), (struct sockaddr*)&clientSa, &clientSaLen, SOCK_CLOEXEC))); + unique_fd clientFd( + TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC))); if (clientFd < 0) { // If this log becomes confusing, should save more state from setupUnixDomainServer // in order to output here. @@ -144,7 +151,7 @@ void RpcConnection::join() { LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get()); - addServer(std::move(clientFd)); + assignServerToThisThread(std::move(clientFd)); } // We may not use the connection we just established (two threads might @@ -170,14 +177,57 @@ wp<RpcServer> RpcConnection::server() { return mForServer; } -void RpcConnection::addClient(base::unique_fd&& fd) { +bool RpcConnection::addServer(const SocketAddress& addr) { + LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server."); + + unique_fd serverFd( + TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0))); + if (serverFd == -1) { + ALOGE("Could not create socket: %s", strerror(errno)); + return false; + } + + if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) { + int savedErrno = errno; + ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno)); + return false; + } + + if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) { + int savedErrno = errno; + ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno)); + return false; + } + + mServer = std::move(serverFd); + return true; +} + +bool RpcConnection::addClient(const SocketAddress& addr) { + unique_fd serverFd( + TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0))); + if (serverFd == -1) { + int savedErrno = errno; + ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno)); + return false; + } + + if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) { + int savedErrno = errno; + ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno)); + return false; + } + + LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get()); + std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = new ConnectionSocket(); - connection->fd = std::move(fd); + connection->fd = std::move(serverFd); mClients.push_back(connection); + return true; } -void RpcConnection::addServer(base::unique_fd&& fd) { +void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = new ConnectionSocket(); connection->fd = std::move(fd); |