diff options
author | 2022-09-23 12:25:18 +0100 | |
---|---|---|
committer | 2022-10-07 11:24:45 +0100 | |
commit | 21c887c5a09040bf41d272a9e729119956e48a3f (patch) | |
tree | 3eb1e98a6aacd9b8134172f5decc9520d456d2b9 /libs/binder/RpcSession.cpp | |
parent | cd8e35be036417c14c270a2ebc94e968d930c478 (diff) |
RpcBinder: Add AF_UNIX socketpair transport
Add support for running RpcBinder over unnamed Unix domain sockets
created by socketpair(). This is useful e.g. between parent/child
processes.
The implementation uses the initial socket pair only to create more
socket pairs for individual connections. This creates a natural mapping
to syscalls used on sockets bound to an address:
socket() socketpair()
bind() n/a (preconnected)
connect() sendmsg()
listen() recvmsg()
Bug: 250685929
Test: atest binderRpcTest
Change-Id: Id4ff3946ddcfefe3592eb1149c61582f7369aa29
Diffstat (limited to 'libs/binder/RpcSession.cpp')
-rw-r--r-- | libs/binder/RpcSession.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index 49843e5953..ff50c16102 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -41,6 +41,7 @@ #include "OS.h" #include "RpcSocketAddress.h" #include "RpcState.h" +#include "RpcTransportUtils.h" #include "RpcWireFormat.h" #include "Utils.h" @@ -147,6 +148,34 @@ status_t RpcSession::setupUnixDomainClient(const char* path) { return setupSocketClient(UnixSocketAddress(path)); } +status_t RpcSession::setupUnixDomainSocketBootstrapClient(unique_fd bootstrapFd) { + mBootstrapTransport = + mCtx->newTransport(RpcTransportFd(std::move(bootstrapFd)), mShutdownTrigger.get()); + return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) { + int socks[2]; + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, socks) < 0) { + int savedErrno = errno; + ALOGE("Failed socketpair: %s", strerror(savedErrno)); + return -savedErrno; + } + unique_fd clientFd(socks[0]), serverFd(socks[1]); + + int zero = 0; + iovec iov{&zero, sizeof(zero)}; + std::vector<std::variant<base::unique_fd, base::borrowed_fd>> fds; + fds.push_back(std::move(serverFd)); + + status_t status = mBootstrapTransport->interruptableWriteFully(mShutdownTrigger.get(), &iov, + 1, std::nullopt, &fds); + if (status != OK) { + ALOGE("Failed to send fd over bootstrap transport: %s", strerror(-status)); + return status; + } + + return initAndAddConnection(RpcTransportFd(std::move(clientFd)), sessionId, incoming); + }); +} + status_t RpcSession::setupVsockClient(unsigned int cid, unsigned int port) { return setupSocketClient(VsockSocketAddress(cid, port)); } |