blob: fa228b2ab3b5774e61ca757053b1100fbaee8b86 [file] [log] [blame]
Steven Moreland5553ac42020-11-11 02:14:45 +00001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "RpcConnection"
18
19#include <binder/RpcConnection.h>
20
Yifan Hong0d2bd112021-04-13 17:38:36 -070021#include <arpa/inet.h>
Yifan Hongb00ff662021-04-26 20:01:32 -070022#include <inttypes.h>
Yifan Hong0d2bd112021-04-13 17:38:36 -070023#include <netdb.h>
24#include <netinet/in.h>
25#include <sys/socket.h>
26#include <sys/types.h>
27#include <sys/un.h>
28#include <unistd.h>
29
30#include <string_view>
31
Steven Moreland5553ac42020-11-11 02:14:45 +000032#include <binder/Parcel.h>
33#include <binder/Stability.h>
Steven Morelandc1635952021-04-01 16:20:47 +000034#include <utils/String8.h>
Steven Moreland5553ac42020-11-11 02:14:45 +000035
36#include "RpcState.h"
37#include "RpcWireFormat.h"
38
Steven Morelandc1635952021-04-01 16:20:47 +000039#ifdef __GLIBC__
Steven Moreland5553ac42020-11-11 02:14:45 +000040extern "C" pid_t gettid();
41#endif
42
Steven Morelandc1635952021-04-01 16:20:47 +000043#ifdef __BIONIC__
44#include <linux/vm_sockets.h>
45#endif
46
Steven Moreland5553ac42020-11-11 02:14:45 +000047namespace android {
48
Yifan Hongb00ff662021-04-26 20:01:32 -070049using base::borrowed_fd;
Steven Moreland5553ac42020-11-11 02:14:45 +000050using base::unique_fd;
Yifan Hong0d2bd112021-04-13 17:38:36 -070051using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;
Steven Moreland5553ac42020-11-11 02:14:45 +000052
Yifan Hongb00ff662021-04-26 20:01:32 -070053namespace {
54bool checkSockaddrSize(const char* name, size_t actual, size_t expected) {
55 if (actual >= expected) return true;
56 ALOGW("getSockaddrPort: family is %s but size is %zu < %zu", name, actual, expected);
57 return false;
58}
59
60// Get the port number of |storage| for certain families. Requires storage->sa_family to be
61// set to a known family; otherwise, return nullopt.
62std::optional<unsigned int> getSockaddrPort(const sockaddr* storage, socklen_t len) {
63 switch (storage->sa_family) {
64 case AF_INET: {
65 if (!checkSockaddrSize("INET", len, sizeof(sockaddr_in))) return std::nullopt;
66 auto inetStorage = reinterpret_cast<const sockaddr_in*>(storage);
67 return ntohs(inetStorage->sin_port);
68 }
69 default: {
70 uint16_t family = storage->sa_family;
71 ALOGW("Don't know how to infer port for family %" PRIu16, family);
72 return std::nullopt;
73 }
74 }
75}
76
77std::optional<unsigned int> getSocketPort(borrowed_fd socketfd,
78 const RpcConnection::SocketAddress& socketAddress) {
79 sockaddr_storage storage{};
80 socklen_t len = sizeof(storage);
81 auto storagePtr = reinterpret_cast<sockaddr*>(&storage);
82 if (0 != getsockname(socketfd.get(), storagePtr, &len)) {
83 int savedErrno = errno;
84 ALOGE("Could not getsockname at %s: %s", socketAddress.toString().c_str(),
85 strerror(savedErrno));
86 return std::nullopt;
87 }
88
89 // getsockname does not fill in family, but getSockaddrPort() needs it.
90 if (storage.ss_family == AF_UNSPEC) {
91 storage.ss_family = socketAddress.addr()->sa_family;
92 }
93 return getSockaddrPort(storagePtr, len);
94}
95
96} // namespace
97
Steven Morelandc1635952021-04-01 16:20:47 +000098RpcConnection::SocketAddress::~SocketAddress() {}
99
Steven Moreland5553ac42020-11-11 02:14:45 +0000100RpcConnection::RpcConnection() {
101 LOG_RPC_DETAIL("RpcConnection created %p", this);
102
103 mState = std::make_unique<RpcState>();
104}
105RpcConnection::~RpcConnection() {
106 LOG_RPC_DETAIL("RpcConnection destroyed %p", this);
Steven Morelandaf816d82021-04-19 23:11:33 +0000107
108 std::lock_guard<std::mutex> _l(mSocketMutex);
109 LOG_ALWAYS_FATAL_IF(mServers.size() != 0,
110 "Should not be able to destroy a connection with servers in use.");
Steven Moreland5553ac42020-11-11 02:14:45 +0000111}
112
113sp<RpcConnection> RpcConnection::make() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000114 return sp<RpcConnection>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000115}
116
Steven Morelandc1635952021-04-01 16:20:47 +0000117class UnixSocketAddress : public RpcConnection::SocketAddress {
118public:
119 explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
120 unsigned int pathLen = strlen(path) + 1;
Steven Morelandcda60852021-04-14 23:45:32 +0000121 LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s",
122 pathLen, path);
Steven Morelandc1635952021-04-01 16:20:47 +0000123 memcpy(mAddr.sun_path, path, pathLen);
124 }
125 virtual ~UnixSocketAddress() {}
126 std::string toString() const override {
127 return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)),
128 mAddr.sun_path)
129 .c_str();
130 }
131 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
132 size_t addrSize() const override { return sizeof(mAddr); }
133
134private:
135 sockaddr_un mAddr;
136};
137
Steven Moreland5553ac42020-11-11 02:14:45 +0000138bool RpcConnection::setupUnixDomainServer(const char* path) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000139 return setupSocketServer(UnixSocketAddress(path));
Steven Moreland5553ac42020-11-11 02:14:45 +0000140}
141
Steven Morelandf137de92021-04-24 01:54:26 +0000142bool RpcConnection::setupUnixDomainClient(const char* path) {
143 return setupSocketClient(UnixSocketAddress(path));
Steven Moreland53583542021-03-30 00:25:41 +0000144}
145
Steven Morelandc1635952021-04-01 16:20:47 +0000146#ifdef __BIONIC__
147
148class VsockSocketAddress : public RpcConnection::SocketAddress {
149public:
150 VsockSocketAddress(unsigned int cid, unsigned int port)
151 : mAddr({
152 .svm_family = AF_VSOCK,
153 .svm_port = port,
154 .svm_cid = cid,
155 }) {}
156 virtual ~VsockSocketAddress() {}
157 std::string toString() const override {
Yifan Hong4c791532021-04-14 12:38:46 -0700158 return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str();
Steven Morelandc1635952021-04-01 16:20:47 +0000159 }
160 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
161 size_t addrSize() const override { return sizeof(mAddr); }
162
163private:
164 sockaddr_vm mAddr;
165};
166
167bool RpcConnection::setupVsockServer(unsigned int port) {
168 // realizing value w/ this type at compile time to avoid ubsan abort
169 constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
170
Steven Morelandd47b32c2021-04-13 02:03:08 +0000171 return setupSocketServer(VsockSocketAddress(kAnyCid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000172}
173
Steven Morelandf137de92021-04-24 01:54:26 +0000174bool RpcConnection::setupVsockClient(unsigned int cid, unsigned int port) {
175 return setupSocketClient(VsockSocketAddress(cid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000176}
177
178#endif // __BIONIC__
179
Steven Morelandd8996df2021-04-26 22:52:50 +0000180class InetSocketAddress : public RpcConnection::SocketAddress {
Yifan Hong0d2bd112021-04-13 17:38:36 -0700181public:
Steven Morelandd8996df2021-04-26 22:52:50 +0000182 InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port)
Steven Moreland158b63d2021-04-26 22:50:06 +0000183 : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {}
Yifan Hong0d2bd112021-04-13 17:38:36 -0700184 [[nodiscard]] std::string toString() const override {
Steven Moreland158b63d2021-04-26 22:50:06 +0000185 return String8::format("%s:%u", mAddr, mPort).c_str();
Yifan Hong0d2bd112021-04-13 17:38:36 -0700186 }
Steven Moreland158b63d2021-04-26 22:50:06 +0000187 [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; }
Yifan Hong0d2bd112021-04-13 17:38:36 -0700188 [[nodiscard]] size_t addrSize() const override { return mSize; }
Yifan Hong0d2bd112021-04-13 17:38:36 -0700189
190private:
Steven Moreland158b63d2021-04-26 22:50:06 +0000191 const sockaddr* mSockAddr;
192 size_t mSize;
193 const char* mAddr;
194 unsigned int mPort;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700195};
196
197AddrInfo GetAddrInfo(const char* addr, unsigned int port) {
198 addrinfo hint{
199 .ai_flags = 0,
200 .ai_family = AF_UNSPEC,
201 .ai_socktype = SOCK_STREAM,
202 .ai_protocol = 0,
203 };
204 addrinfo* aiStart = nullptr;
205 if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) {
206 ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc));
207 return AddrInfo(nullptr, nullptr);
208 }
209 if (aiStart == nullptr) {
210 ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port);
211 return AddrInfo(nullptr, nullptr);
212 }
213 return AddrInfo(aiStart, &freeaddrinfo);
214}
215
Yifan Hongb00ff662021-04-26 20:01:32 -0700216bool RpcConnection::setupInetServer(unsigned int port, unsigned int* assignedPort) {
Steven Moreland158b63d2021-04-26 22:50:06 +0000217 const char* kAddr = "127.0.0.1";
218
Yifan Hongb00ff662021-04-26 20:01:32 -0700219 if (assignedPort != nullptr) *assignedPort = 0;
Steven Moreland158b63d2021-04-26 22:50:06 +0000220 auto aiStart = GetAddrInfo(kAddr, port);
Yifan Hong0d2bd112021-04-13 17:38:36 -0700221 if (aiStart == nullptr) return false;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700222 for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
Steven Morelandd8996df2021-04-26 22:52:50 +0000223 InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
Yifan Hongb00ff662021-04-26 20:01:32 -0700224 if (!setupSocketServer(socketAddress)) {
225 continue;
226 }
227 auto realPort = getSocketPort(mServer.get(), socketAddress);
228 LOG_ALWAYS_FATAL_IF(!realPort.has_value(), "Unable to get port number after setting up %s",
229 socketAddress.toString().c_str());
230 LOG_ALWAYS_FATAL_IF(port != 0 && *realPort != port,
231 "Requesting inet server on %s but it is set up on %u.",
232 socketAddress.toString().c_str(), *realPort);
233 if (assignedPort != nullptr) {
234 *assignedPort = *realPort;
235 }
236 return true;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700237 }
Steven Moreland158b63d2021-04-26 22:50:06 +0000238 ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
Yifan Hong0d2bd112021-04-13 17:38:36 -0700239 port);
240 return false;
241}
242
Steven Morelandf137de92021-04-24 01:54:26 +0000243bool RpcConnection::setupInetClient(const char* addr, unsigned int port) {
Yifan Hong0d2bd112021-04-13 17:38:36 -0700244 auto aiStart = GetAddrInfo(addr, port);
245 if (aiStart == nullptr) return false;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700246 for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
Steven Morelandd8996df2021-04-26 22:52:50 +0000247 InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
Steven Morelandf137de92021-04-24 01:54:26 +0000248 if (setupSocketClient(socketAddress)) return true;
Yifan Hong0d2bd112021-04-13 17:38:36 -0700249 }
250 ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
251 return false;
252}
253
Steven Morelandd47b32c2021-04-13 02:03:08 +0000254bool RpcConnection::addNullDebuggingClient() {
255 unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
256
257 if (serverFd == -1) {
258 ALOGE("Could not connect to /dev/null: %s", strerror(errno));
259 return false;
260 }
261
262 addClient(std::move(serverFd));
263 return true;
264}
265
Steven Moreland5553ac42020-11-11 02:14:45 +0000266sp<IBinder> RpcConnection::getRootObject() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000267 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
268 return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000269}
270
Steven Morelandf137de92021-04-24 01:54:26 +0000271status_t RpcConnection::getMaxThreads(size_t* maxThreads) {
272 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
273 return state()->getMaxThreads(socket.fd(), sp<RpcConnection>::fromExisting(this), maxThreads);
274}
275
Steven Moreland5553ac42020-11-11 02:14:45 +0000276status_t RpcConnection::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
277 Parcel* reply, uint32_t flags) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000278 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this),
Steven Moreland5553ac42020-11-11 02:14:45 +0000279 (flags & IBinder::FLAG_ONEWAY) ? SocketUse::CLIENT_ASYNC
280 : SocketUse::CLIENT);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000281 return state()->transact(socket.fd(), address, code, data,
282 sp<RpcConnection>::fromExisting(this), reply, flags);
Steven Moreland5553ac42020-11-11 02:14:45 +0000283}
284
285status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000286 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT_REFCOUNT);
Steven Moreland5553ac42020-11-11 02:14:45 +0000287 return state()->sendDecStrong(socket.fd(), address);
288}
289
290void RpcConnection::join() {
Steven Morelandaf816d82021-04-19 23:11:33 +0000291 // TODO(b/185167543): do this dynamically, instead of from a static number
292 // of threads
293 unique_fd clientFd(
294 TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC)));
295 if (clientFd < 0) {
296 // If this log becomes confusing, should save more state from setupUnixDomainServer
297 // in order to output here.
298 ALOGE("Could not accept4 socket: %s", strerror(errno));
299 return;
Steven Moreland5553ac42020-11-11 02:14:45 +0000300 }
301
Steven Morelandaf816d82021-04-19 23:11:33 +0000302 LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
303
304 // must be registered to allow arbitrary client code executing commands to
305 // be able to do nested calls (we can't only read from it)
306 sp<ConnectionSocket> socket = assignServerToThisThread(std::move(clientFd));
Steven Moreland5553ac42020-11-11 02:14:45 +0000307
308 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000309 status_t error =
Steven Morelandaf816d82021-04-19 23:11:33 +0000310 state()->getAndExecuteCommand(socket->fd, sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000311
312 if (error != OK) {
313 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
Steven Morelandaf816d82021-04-19 23:11:33 +0000314 break;
Steven Moreland5553ac42020-11-11 02:14:45 +0000315 }
316 }
Steven Morelandaf816d82021-04-19 23:11:33 +0000317
318 LOG_ALWAYS_FATAL_IF(!removeServerSocket(socket),
319 "bad state: socket object guaranteed to be in list");
Steven Moreland5553ac42020-11-11 02:14:45 +0000320}
321
322void RpcConnection::setForServer(const wp<RpcServer>& server) {
323 mForServer = server;
324}
325
326wp<RpcServer> RpcConnection::server() {
327 return mForServer;
328}
329
Steven Morelandd47b32c2021-04-13 02:03:08 +0000330bool RpcConnection::setupSocketServer(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000331 LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");
332
333 unique_fd serverFd(
334 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
335 if (serverFd == -1) {
336 ALOGE("Could not create socket: %s", strerror(errno));
337 return false;
338 }
339
340 if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
341 int savedErrno = errno;
342 ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
343 return false;
344 }
345
346 if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
347 int savedErrno = errno;
348 ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
349 return false;
350 }
351
352 mServer = std::move(serverFd);
353 return true;
Steven Moreland53583542021-03-30 00:25:41 +0000354}
355
Steven Morelandf137de92021-04-24 01:54:26 +0000356bool RpcConnection::setupSocketClient(const SocketAddress& addr) {
357 {
358 std::lock_guard<std::mutex> _l(mSocketMutex);
359 LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
360 "Must only setup connection once, but already has %zu clients",
361 mClients.size());
362 }
363
364 if (!setupOneSocketClient(addr)) return false;
365
366 // TODO(b/185167543): we should add additional connections dynamically
367 // instead of all at once.
368 // TODO(b/186470974): first risk of blocking
369 size_t numThreadsAvailable;
370 if (status_t status = getMaxThreads(&numThreadsAvailable); status != OK) {
371 ALOGE("Could not get max threads after initial connection to %s: %s",
372 addr.toString().c_str(), statusToString(status).c_str());
373 return false;
374 }
375
376 // we've already setup one client
377 for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
378 // TODO(b/185167543): avoid race w/ accept4 not being called on server
379 for (size_t tries = 0; tries < 5; tries++) {
380 if (setupOneSocketClient(addr)) break;
381 usleep(10000);
382 }
383 }
384
385 return true;
386}
387
388bool RpcConnection::setupOneSocketClient(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000389 unique_fd serverFd(
390 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
391 if (serverFd == -1) {
392 int savedErrno = errno;
393 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
394 return false;
395 }
396
397 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
398 int savedErrno = errno;
399 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
400 return false;
401 }
402
403 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
404
Steven Morelandd47b32c2021-04-13 02:03:08 +0000405 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000406 return true;
407}
408
Steven Morelanda4c94752021-05-01 01:34:24 +0000409void RpcConnection::addClient(unique_fd fd) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000410 std::lock_guard<std::mutex> _l(mSocketMutex);
411 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
412 connection->fd = std::move(fd);
413 mClients.push_back(connection);
414}
415
Steven Morelanda4c94752021-05-01 01:34:24 +0000416sp<RpcConnection::ConnectionSocket> RpcConnection::assignServerToThisThread(unique_fd fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000417 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000418 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000419 connection->fd = std::move(fd);
Steven Morelandaf816d82021-04-19 23:11:33 +0000420 connection->exclusiveTid = gettid();
Steven Moreland5553ac42020-11-11 02:14:45 +0000421 mServers.push_back(connection);
Steven Morelandaf816d82021-04-19 23:11:33 +0000422
423 return connection;
424}
425
426bool RpcConnection::removeServerSocket(const sp<ConnectionSocket>& socket) {
427 std::lock_guard<std::mutex> _l(mSocketMutex);
428 if (auto it = std::find(mServers.begin(), mServers.end(), socket); it != mServers.end()) {
429 mServers.erase(it);
430 return true;
431 }
432 return false;
Steven Moreland5553ac42020-11-11 02:14:45 +0000433}
434
435RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
436 : mConnection(connection) {
437 pid_t tid = gettid();
438 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
439
440 mConnection->mWaitingThreads++;
441 while (true) {
442 sp<ConnectionSocket> exclusive;
443 sp<ConnectionSocket> available;
444
445 // CHECK FOR DEDICATED CLIENT SOCKET
446 //
Steven Morelandaf816d82021-04-19 23:11:33 +0000447 // A server/looper should always use a dedicated connection if available
448 findSocket(tid, &exclusive, &available, mConnection->mClients, mConnection->mClientsOffset);
Steven Moreland5553ac42020-11-11 02:14:45 +0000449
Steven Morelandaf816d82021-04-19 23:11:33 +0000450 // WARNING: this assumes a server cannot request its client to send
451 // a transaction, as mServers is excluded below.
452 //
453 // Imagine we have more than one thread in play, and a single thread
454 // sends a synchronous, then an asynchronous command. Imagine the
455 // asynchronous command is sent on the first client socket. Then, if
456 // we naively send a synchronous command to that same socket, the
457 // thread on the far side might be busy processing the asynchronous
458 // command. So, we move to considering the second available thread
459 // for subsequent calls.
460 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
461 mConnection->mClientsOffset =
462 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
Steven Moreland5553ac42020-11-11 02:14:45 +0000463 }
464
Steven Morelandaf816d82021-04-19 23:11:33 +0000465 // USE SERVING SOCKET (for nested transaction)
Steven Moreland5553ac42020-11-11 02:14:45 +0000466 //
467 // asynchronous calls cannot be nested
468 if (use != SocketUse::CLIENT_ASYNC) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000469 // server sockets are always assigned to a thread
470 findSocket(tid, &exclusive, nullptr /*available*/, mConnection->mServers,
471 0 /* index hint */);
Steven Moreland5553ac42020-11-11 02:14:45 +0000472 }
473
474 // if our thread is already using a connection, prioritize using that
475 if (exclusive != nullptr) {
476 mSocket = exclusive;
477 mReentrant = true;
478 break;
479 } else if (available != nullptr) {
480 mSocket = available;
481 mSocket->exclusiveTid = tid;
482 break;
483 }
484
Steven Moreland5553ac42020-11-11 02:14:45 +0000485 // in regular binder, this would usually be a deadlock :)
486 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
487 "Not a client of any connection. You must create a connection to an "
488 "RPC server to make any non-nested (e.g. oneway or on another thread) "
489 "calls.");
490
491 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
492 mConnection->mClients.size(), mConnection->mServers.size());
493 mConnection->mSocketCv.wait(_l);
494 }
495 mConnection->mWaitingThreads--;
496}
497
498void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
499 sp<ConnectionSocket>* available,
500 std::vector<sp<ConnectionSocket>>& sockets,
501 size_t socketsIndexHint) {
502 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
503 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
504
505 if (*exclusive != nullptr) return; // consistent with break below
506
507 for (size_t i = 0; i < sockets.size(); i++) {
508 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
509
510 // take first available connection (intuition = caching)
511 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
512 *available = socket;
513 continue;
514 }
515
516 // though, prefer to take connection which is already inuse by this thread
517 // (nested transactions)
518 if (exclusive && socket->exclusiveTid == tid) {
519 *exclusive = socket;
520 break; // consistent with return above
521 }
522 }
523}
524
525RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
526 // reentrant use of a connection means something less deep in the call stack
527 // is using this fd, and it retains the right to it. So, we don't give up
528 // exclusive ownership, and no thread is freed.
529 if (!mReentrant) {
530 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
531 mSocket->exclusiveTid = std::nullopt;
532 if (mConnection->mWaitingThreads > 0) {
533 _l.unlock();
534 mConnection->mSocketCv.notify_one();
535 }
536 }
537}
538
539} // namespace android