diff options
Diffstat (limited to 'libs/binder/RpcConnection.cpp')
| -rw-r--r-- | libs/binder/RpcConnection.cpp | 158 |
1 files changed, 54 insertions, 104 deletions
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp index dab3246fc5..83a1618e9f 100644 --- a/libs/binder/RpcConnection.cpp +++ b/libs/binder/RpcConnection.cpp @@ -20,7 +20,6 @@ #include <binder/Parcel.h> #include <binder/Stability.h> -#include <utils/String8.h> #include "RpcState.h" #include "RpcWireFormat.h" @@ -30,20 +29,14 @@ #include <sys/un.h> #include <unistd.h> -#ifdef __GLIBC__ +#if defined(__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); @@ -57,67 +50,64 @@ sp<RpcConnection> RpcConnection::make() { return new RpcConnection; } -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); +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; } - virtual ~UnixSocketAddress() {} - std::string toString() const override { - return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)), - mAddr.sun_path) - .c_str(); + + 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; } - const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } - size_t addrSize() const override { return sizeof(mAddr); } -private: - sockaddr_un mAddr; -}; + if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) { + ALOGE("Could not listen socket at %s: %s", path, strerror(errno)); + return false; + } -bool RpcConnection::setupUnixDomainServer(const char* path) { - return addServer(UnixSocketAddress(path)); + mServer = std::move(serverFd); + return true; } bool RpcConnection::addUnixDomainClient(const char* path) { - return addClient(UnixSocketAddress(path)); -} + LOG_RPC_DETAIL("Connecting on path: %s", path); -#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(); + 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; } - const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } - size_t addrSize() const override { return sizeof(mAddr); } -private: - sockaddr_vm mAddr; -}; + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + }; -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; + unsigned int pathLen = strlen(path) + 1; + LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen); + memcpy(addr.sun_path, path, pathLen); - return addServer(VsockSocketAddress(kAnyCid, port)); -} + 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; + } -bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) { - return addClient(VsockSocketAddress(cid, port)); -} + LOG_RPC_DETAIL("Unix domain client with fd %d", serverFd.get()); -#endif // __BIONIC__ + addClient(std::move(serverFd)); + return true; +} sp<IBinder> RpcConnection::getRootObject() { ExclusiveSocket socket(this, SocketUse::CLIENT); @@ -140,8 +130,11 @@ status_t RpcConnection::sendDecStrong(const RpcAddress& address) { void RpcConnection::join() { // establish a connection { - unique_fd clientFd( - TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC))); + struct sockaddr_un clientSa; + socklen_t clientSaLen = sizeof(clientSa); + + unique_fd clientFd(TEMP_FAILURE_RETRY( + accept4(mServer.get(), (struct sockaddr*)&clientSa, &clientSaLen, SOCK_CLOEXEC))); if (clientFd < 0) { // If this log becomes confusing, should save more state from setupUnixDomainServer // in order to output here. @@ -151,7 +144,7 @@ void RpcConnection::join() { LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get()); - assignServerToThisThread(std::move(clientFd)); + addServer(std::move(clientFd)); } // We may not use the connection we just established (two threads might @@ -177,57 +170,14 @@ wp<RpcServer> RpcConnection::server() { return mForServer; } -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()); - +void RpcConnection::addClient(base::unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = new ConnectionSocket(); - connection->fd = std::move(serverFd); + connection->fd = std::move(fd); mClients.push_back(connection); - return true; } -void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) { +void RpcConnection::addServer(base::unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = new ConnectionSocket(); connection->fd = std::move(fd); |