blob: 4aff92b58a56885e1ec92ce847dbae2d9681d9b4 [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
21#include <binder/Parcel.h>
22#include <binder/Stability.h>
Steven Morelandc1635952021-04-01 16:20:47 +000023#include <utils/String8.h>
Steven Moreland5553ac42020-11-11 02:14:45 +000024
25#include "RpcState.h"
26#include "RpcWireFormat.h"
27
28#include <sys/socket.h>
29#include <sys/types.h>
30#include <sys/un.h>
31#include <unistd.h>
32
Steven Morelandc1635952021-04-01 16:20:47 +000033#ifdef __GLIBC__
Steven Moreland5553ac42020-11-11 02:14:45 +000034extern "C" pid_t gettid();
35#endif
36
Steven Morelandc1635952021-04-01 16:20:47 +000037#ifdef __BIONIC__
38#include <linux/vm_sockets.h>
39#endif
40
Steven Moreland5553ac42020-11-11 02:14:45 +000041namespace android {
42
43using base::unique_fd;
44
Steven Morelandc1635952021-04-01 16:20:47 +000045RpcConnection::SocketAddress::~SocketAddress() {}
46
Steven Moreland5553ac42020-11-11 02:14:45 +000047RpcConnection::RpcConnection() {
48 LOG_RPC_DETAIL("RpcConnection created %p", this);
49
50 mState = std::make_unique<RpcState>();
51}
52RpcConnection::~RpcConnection() {
53 LOG_RPC_DETAIL("RpcConnection destroyed %p", this);
54}
55
56sp<RpcConnection> RpcConnection::make() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +000057 return sp<RpcConnection>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +000058}
59
Steven Morelandc1635952021-04-01 16:20:47 +000060class UnixSocketAddress : public RpcConnection::SocketAddress {
61public:
62 explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
63 unsigned int pathLen = strlen(path) + 1;
Steven Morelandcda60852021-04-14 23:45:32 +000064 LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s",
65 pathLen, path);
Steven Morelandc1635952021-04-01 16:20:47 +000066 memcpy(mAddr.sun_path, path, pathLen);
67 }
68 virtual ~UnixSocketAddress() {}
69 std::string toString() const override {
70 return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)),
71 mAddr.sun_path)
72 .c_str();
73 }
74 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
75 size_t addrSize() const override { return sizeof(mAddr); }
76
77private:
78 sockaddr_un mAddr;
79};
80
Steven Moreland5553ac42020-11-11 02:14:45 +000081bool RpcConnection::setupUnixDomainServer(const char* path) {
Steven Morelandd47b32c2021-04-13 02:03:08 +000082 return setupSocketServer(UnixSocketAddress(path));
Steven Moreland5553ac42020-11-11 02:14:45 +000083}
84
85bool RpcConnection::addUnixDomainClient(const char* path) {
Steven Morelandd47b32c2021-04-13 02:03:08 +000086 return addSocketClient(UnixSocketAddress(path));
Steven Moreland53583542021-03-30 00:25:41 +000087}
88
Steven Morelandc1635952021-04-01 16:20:47 +000089#ifdef __BIONIC__
90
91class VsockSocketAddress : public RpcConnection::SocketAddress {
92public:
93 VsockSocketAddress(unsigned int cid, unsigned int port)
94 : mAddr({
95 .svm_family = AF_VSOCK,
96 .svm_port = port,
97 .svm_cid = cid,
98 }) {}
99 virtual ~VsockSocketAddress() {}
100 std::string toString() const override {
Yifan Hong4c791532021-04-14 12:38:46 -0700101 return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str();
Steven Morelandc1635952021-04-01 16:20:47 +0000102 }
103 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
104 size_t addrSize() const override { return sizeof(mAddr); }
105
106private:
107 sockaddr_vm mAddr;
108};
109
110bool RpcConnection::setupVsockServer(unsigned int port) {
111 // realizing value w/ this type at compile time to avoid ubsan abort
112 constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
113
Steven Morelandd47b32c2021-04-13 02:03:08 +0000114 return setupSocketServer(VsockSocketAddress(kAnyCid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000115}
116
117bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000118 return addSocketClient(VsockSocketAddress(cid, port));
Steven Morelandc1635952021-04-01 16:20:47 +0000119}
120
121#endif // __BIONIC__
122
Steven Morelandd47b32c2021-04-13 02:03:08 +0000123bool RpcConnection::addNullDebuggingClient() {
124 unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
125
126 if (serverFd == -1) {
127 ALOGE("Could not connect to /dev/null: %s", strerror(errno));
128 return false;
129 }
130
131 addClient(std::move(serverFd));
132 return true;
133}
134
Steven Moreland5553ac42020-11-11 02:14:45 +0000135sp<IBinder> RpcConnection::getRootObject() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000136 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
137 return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000138}
139
140status_t RpcConnection::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
141 Parcel* reply, uint32_t flags) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000142 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this),
Steven Moreland5553ac42020-11-11 02:14:45 +0000143 (flags & IBinder::FLAG_ONEWAY) ? SocketUse::CLIENT_ASYNC
144 : SocketUse::CLIENT);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000145 return state()->transact(socket.fd(), address, code, data,
146 sp<RpcConnection>::fromExisting(this), reply, flags);
Steven Moreland5553ac42020-11-11 02:14:45 +0000147}
148
149status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000150 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT_REFCOUNT);
Steven Moreland5553ac42020-11-11 02:14:45 +0000151 return state()->sendDecStrong(socket.fd(), address);
152}
153
154void RpcConnection::join() {
155 // establish a connection
156 {
Steven Morelandc1635952021-04-01 16:20:47 +0000157 unique_fd clientFd(
158 TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC)));
Steven Moreland5553ac42020-11-11 02:14:45 +0000159 if (clientFd < 0) {
160 // If this log becomes confusing, should save more state from setupUnixDomainServer
161 // in order to output here.
162 ALOGE("Could not accept4 socket: %s", strerror(errno));
163 return;
164 }
165
166 LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
167
Steven Morelandc1635952021-04-01 16:20:47 +0000168 assignServerToThisThread(std::move(clientFd));
Steven Moreland5553ac42020-11-11 02:14:45 +0000169 }
170
171 // We may not use the connection we just established (two threads might
172 // establish connections for each other), but for now, just use one
173 // server/socket connection.
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000174 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::SERVER);
Steven Moreland5553ac42020-11-11 02:14:45 +0000175
176 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000177 status_t error =
178 state()->getAndExecuteCommand(socket.fd(), sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000179
180 if (error != OK) {
181 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
182 return;
183 }
184 }
185}
186
187void RpcConnection::setForServer(const wp<RpcServer>& server) {
188 mForServer = server;
189}
190
191wp<RpcServer> RpcConnection::server() {
192 return mForServer;
193}
194
Steven Morelandd47b32c2021-04-13 02:03:08 +0000195bool RpcConnection::setupSocketServer(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000196 LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");
197
198 unique_fd serverFd(
199 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
200 if (serverFd == -1) {
201 ALOGE("Could not create socket: %s", strerror(errno));
202 return false;
203 }
204
205 if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
206 int savedErrno = errno;
207 ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
208 return false;
209 }
210
211 if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
212 int savedErrno = errno;
213 ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
214 return false;
215 }
216
217 mServer = std::move(serverFd);
218 return true;
Steven Moreland53583542021-03-30 00:25:41 +0000219}
220
Steven Morelandd47b32c2021-04-13 02:03:08 +0000221bool RpcConnection::addSocketClient(const SocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000222 unique_fd serverFd(
223 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
224 if (serverFd == -1) {
225 int savedErrno = errno;
226 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
227 return false;
228 }
229
230 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
231 int savedErrno = errno;
232 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
233 return false;
234 }
235
236 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
237
Steven Morelandd47b32c2021-04-13 02:03:08 +0000238 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000239 return true;
240}
241
Steven Morelandd47b32c2021-04-13 02:03:08 +0000242void RpcConnection::addClient(unique_fd&& fd) {
243 std::lock_guard<std::mutex> _l(mSocketMutex);
244 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
245 connection->fd = std::move(fd);
246 mClients.push_back(connection);
247}
248
249void RpcConnection::assignServerToThisThread(unique_fd&& fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000250 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000251 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000252 connection->fd = std::move(fd);
253 mServers.push_back(connection);
254}
255
256RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
257 : mConnection(connection) {
258 pid_t tid = gettid();
259 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
260
261 mConnection->mWaitingThreads++;
262 while (true) {
263 sp<ConnectionSocket> exclusive;
264 sp<ConnectionSocket> available;
265
266 // CHECK FOR DEDICATED CLIENT SOCKET
267 //
268 // A server/looper should always use a dedicated connection.
269 if (use != SocketUse::SERVER) {
270 findSocket(tid, &exclusive, &available, mConnection->mClients,
271 mConnection->mClientsOffset);
272
273 // WARNING: this assumes a server cannot request its client to send
274 // a transaction, as mServers is excluded below.
275 //
276 // Imagine we have more than one thread in play, and a single thread
277 // sends a synchronous, then an asynchronous command. Imagine the
278 // asynchronous command is sent on the first client socket. Then, if
279 // we naively send a synchronous command to that same socket, the
280 // thread on the far side might be busy processing the asynchronous
281 // command. So, we move to considering the second available thread
282 // for subsequent calls.
283 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
284 mConnection->mClientsOffset =
285 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
286 }
287 }
288
289 // USE SERVING SOCKET (to start serving or for nested transaction)
290 //
291 // asynchronous calls cannot be nested
292 if (use != SocketUse::CLIENT_ASYNC) {
293 // servers should start serving on an available thread only
294 // otherwise, this should only be a nested call
295 bool useAvailable = use == SocketUse::SERVER;
296
297 findSocket(tid, &exclusive, (useAvailable ? &available : nullptr),
298 mConnection->mServers, 0 /* index hint */);
299 }
300
301 // if our thread is already using a connection, prioritize using that
302 if (exclusive != nullptr) {
303 mSocket = exclusive;
304 mReentrant = true;
305 break;
306 } else if (available != nullptr) {
307 mSocket = available;
308 mSocket->exclusiveTid = tid;
309 break;
310 }
311
312 LOG_ALWAYS_FATAL_IF(use == SocketUse::SERVER, "Must create connection to join one.");
313
314 // in regular binder, this would usually be a deadlock :)
315 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
316 "Not a client of any connection. You must create a connection to an "
317 "RPC server to make any non-nested (e.g. oneway or on another thread) "
318 "calls.");
319
320 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
321 mConnection->mClients.size(), mConnection->mServers.size());
322 mConnection->mSocketCv.wait(_l);
323 }
324 mConnection->mWaitingThreads--;
325}
326
327void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
328 sp<ConnectionSocket>* available,
329 std::vector<sp<ConnectionSocket>>& sockets,
330 size_t socketsIndexHint) {
331 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
332 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
333
334 if (*exclusive != nullptr) return; // consistent with break below
335
336 for (size_t i = 0; i < sockets.size(); i++) {
337 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
338
339 // take first available connection (intuition = caching)
340 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
341 *available = socket;
342 continue;
343 }
344
345 // though, prefer to take connection which is already inuse by this thread
346 // (nested transactions)
347 if (exclusive && socket->exclusiveTid == tid) {
348 *exclusive = socket;
349 break; // consistent with return above
350 }
351 }
352}
353
354RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
355 // reentrant use of a connection means something less deep in the call stack
356 // is using this fd, and it retains the right to it. So, we don't give up
357 // exclusive ownership, and no thread is freed.
358 if (!mReentrant) {
359 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
360 mSocket->exclusiveTid = std::nullopt;
361 if (mConnection->mWaitingThreads > 0) {
362 _l.unlock();
363 mConnection->mSocketCv.notify_one();
364 }
365 }
366}
367
368} // namespace android