summaryrefslogtreecommitdiff
path: root/libs/binder/RpcConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/RpcConnection.cpp')
-rw-r--r--libs/binder/RpcConnection.cpp189
1 files changed, 6 insertions, 183 deletions
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index 3e1964673a..930bcbde62 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -18,13 +18,7 @@
#include <binder/RpcConnection.h>
-#include <arpa/inet.h>
#include <inttypes.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
#include <unistd.h>
#include <string_view>
@@ -33,6 +27,7 @@
#include <binder/Stability.h>
#include <utils/String8.h>
+#include "RpcSocketAddress.h"
#include "RpcState.h"
#include "RpcWireFormat.h"
@@ -40,16 +35,9 @@
extern "C" pid_t gettid();
#endif
-#ifdef __BIONIC__
-#include <linux/vm_sockets.h>
-#endif
-
namespace android {
using base::unique_fd;
-using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;
-
-RpcConnection::SocketAddress::~SocketAddress() {}
RpcConnection::RpcConnection() {
LOG_RPC_DETAIL("RpcConnection created %p", this);
@@ -68,146 +56,20 @@ sp<RpcConnection> RpcConnection::make() {
return sp<RpcConnection>::make();
}
-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), "Socket path is too long: %u %s",
- pathLen, path);
- memcpy(mAddr.sun_path, path, pathLen);
- }
- 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); }
-
-private:
- sockaddr_un mAddr;
-};
-
-bool RpcConnection::setupUnixDomainServer(const char* path) {
- return setupSocketServer(UnixSocketAddress(path));
-}
-
bool RpcConnection::setupUnixDomainClient(const char* path) {
return setupSocketClient(UnixSocketAddress(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 %u port %u", 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); }
-
-private:
- sockaddr_vm mAddr;
-};
-
-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;
-
- return setupSocketServer(VsockSocketAddress(kAnyCid, port));
-}
-
bool RpcConnection::setupVsockClient(unsigned int cid, unsigned int port) {
return setupSocketClient(VsockSocketAddress(cid, port));
}
#endif // __BIONIC__
-class InetSocketAddress : public RpcConnection::SocketAddress {
-public:
- InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port)
- : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {}
- [[nodiscard]] std::string toString() const override {
- return String8::format("%s:%u", mAddr, mPort).c_str();
- }
- [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; }
- [[nodiscard]] size_t addrSize() const override { return mSize; }
-
-private:
- const sockaddr* mSockAddr;
- size_t mSize;
- const char* mAddr;
- unsigned int mPort;
-};
-
-AddrInfo GetAddrInfo(const char* addr, unsigned int port) {
- addrinfo hint{
- .ai_flags = 0,
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_STREAM,
- .ai_protocol = 0,
- };
- addrinfo* aiStart = nullptr;
- if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) {
- ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc));
- return AddrInfo(nullptr, nullptr);
- }
- if (aiStart == nullptr) {
- ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port);
- return AddrInfo(nullptr, nullptr);
- }
- return AddrInfo(aiStart, &freeaddrinfo);
-}
-
-bool RpcConnection::setupInetServer(unsigned int port, unsigned int* assignedPort) {
- const char* kAddr = "127.0.0.1";
-
- if (assignedPort != nullptr) *assignedPort = 0;
- auto aiStart = GetAddrInfo(kAddr, port);
- if (aiStart == nullptr) return false;
- for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
- InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
- if (!setupSocketServer(socketAddress)) {
- continue;
- }
-
- LOG_ALWAYS_FATAL_IF(socketAddress.addr()->sa_family != AF_INET, "expecting inet");
- sockaddr_in addr{};
- socklen_t len = sizeof(addr);
- if (0 != getsockname(mServer.get(), reinterpret_cast<sockaddr*>(&addr), &len)) {
- int savedErrno = errno;
- ALOGE("Could not getsockname at %s: %s", socketAddress.toString().c_str(),
- strerror(savedErrno));
- return false;
- }
- LOG_ALWAYS_FATAL_IF(len != sizeof(addr), "Wrong socket type: len %zu vs len %zu",
- static_cast<size_t>(len), sizeof(addr));
- unsigned int realPort = ntohs(addr.sin_port);
- LOG_ALWAYS_FATAL_IF(port != 0 && realPort != port,
- "Requesting inet server on %s but it is set up on %u.",
- socketAddress.toString().c_str(), realPort);
-
- if (assignedPort != nullptr) {
- *assignedPort = realPort;
- }
-
- return true;
- }
- ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
- port);
- return false;
-}
-
bool RpcConnection::setupInetClient(const char* addr, unsigned int port) {
- auto aiStart = GetAddrInfo(addr, port);
+ auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
if (aiStart == nullptr) return false;
for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
@@ -253,23 +115,10 @@ status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
return state()->sendDecStrong(socket.fd(), address);
}
-void RpcConnection::join() {
- // TODO(b/185167543): do this dynamically, instead of from a static number
- // of threads
- 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.
- ALOGE("Could not accept4 socket: %s", strerror(errno));
- return;
- }
-
- LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
-
+void RpcConnection::join(unique_fd client) {
// must be registered to allow arbitrary client code executing commands to
// be able to do nested calls (we can't only read from it)
- sp<ConnectionSocket> socket = assignServerToThisThread(std::move(clientFd));
+ sp<ConnectionSocket> socket = assignServerToThisThread(std::move(client));
while (true) {
status_t error =
@@ -293,33 +142,7 @@ wp<RpcServer> RpcConnection::server() {
return mForServer;
}
-bool RpcConnection::setupSocketServer(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::setupSocketClient(const SocketAddress& addr) {
+bool RpcConnection::setupSocketClient(const RpcSocketAddress& addr) {
{
std::lock_guard<std::mutex> _l(mSocketMutex);
LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
@@ -351,7 +174,7 @@ bool RpcConnection::setupSocketClient(const SocketAddress& addr) {
return true;
}
-bool RpcConnection::setupOneSocketClient(const SocketAddress& addr) {
+bool RpcConnection::setupOneSocketClient(const RpcSocketAddress& addr) {
unique_fd serverFd(
TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
if (serverFd == -1) {