blob: 4b3a53ffe94a4d734b3ee1d69d4e008cbb51a8ae [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 Hongb00ff662021-04-26 20:01:32 -070021#include <inttypes.h>
Yifan Hong0d2bd112021-04-13 17:38:36 -070022#include <unistd.h>
23
24#include <string_view>
25
Steven Moreland5553ac42020-11-11 02:14:45 +000026#include <binder/Parcel.h>
27#include <binder/Stability.h>
Steven Morelandc1635952021-04-01 16:20:47 +000028#include <utils/String8.h>
Steven Moreland5553ac42020-11-11 02:14:45 +000029
Steven Moreland611d15f2021-05-01 01:28:27 +000030#include "RpcSocketAddress.h"
Steven Moreland5553ac42020-11-11 02:14:45 +000031#include "RpcState.h"
32#include "RpcWireFormat.h"
33
Steven Morelandc1635952021-04-01 16:20:47 +000034#ifdef __GLIBC__
Steven Moreland5553ac42020-11-11 02:14:45 +000035extern "C" pid_t gettid();
36#endif
37
38namespace android {
39
40using base::unique_fd;
Steven Morelandc1635952021-04-01 16:20:47 +000041
Steven Moreland5553ac42020-11-11 02:14:45 +000042RpcConnection::RpcConnection() {
43 LOG_RPC_DETAIL("RpcConnection created %p", this);
44
45 mState = std::make_unique<RpcState>();
46}
47RpcConnection::~RpcConnection() {
48 LOG_RPC_DETAIL("RpcConnection destroyed %p", this);
Steven Morelandaf816d82021-04-19 23:11:33 +000049
50 std::lock_guard<std::mutex> _l(mSocketMutex);
51 LOG_ALWAYS_FATAL_IF(mServers.size() != 0,
52 "Should not be able to destroy a connection with servers in use.");
Steven Moreland5553ac42020-11-11 02:14:45 +000053}
54
55sp<RpcConnection> RpcConnection::make() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +000056 return sp<RpcConnection>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +000057}
58
Steven Morelandf137de92021-04-24 01:54:26 +000059bool RpcConnection::setupUnixDomainClient(const char* path) {
60 return setupSocketClient(UnixSocketAddress(path));
Steven Moreland53583542021-03-30 00:25:41 +000061}
62
Steven Morelandc1635952021-04-01 16:20:47 +000063#ifdef __BIONIC__
64
Steven Morelandf137de92021-04-24 01:54:26 +000065bool RpcConnection::setupVsockClient(unsigned int cid, unsigned int port) {
66 return setupSocketClient(VsockSocketAddress(cid, port));
Steven Morelandc1635952021-04-01 16:20:47 +000067}
68
69#endif // __BIONIC__
70
Steven Morelandf137de92021-04-24 01:54:26 +000071bool RpcConnection::setupInetClient(const char* addr, unsigned int port) {
Steven Moreland611d15f2021-05-01 01:28:27 +000072 auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
Yifan Hong0d2bd112021-04-13 17:38:36 -070073 if (aiStart == nullptr) return false;
Yifan Hong0d2bd112021-04-13 17:38:36 -070074 for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
Steven Morelandd8996df2021-04-26 22:52:50 +000075 InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
Steven Morelandf137de92021-04-24 01:54:26 +000076 if (setupSocketClient(socketAddress)) return true;
Yifan Hong0d2bd112021-04-13 17:38:36 -070077 }
78 ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
79 return false;
80}
81
Steven Morelandd47b32c2021-04-13 02:03:08 +000082bool RpcConnection::addNullDebuggingClient() {
83 unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
84
85 if (serverFd == -1) {
86 ALOGE("Could not connect to /dev/null: %s", strerror(errno));
87 return false;
88 }
89
90 addClient(std::move(serverFd));
91 return true;
92}
93
Steven Moreland5553ac42020-11-11 02:14:45 +000094sp<IBinder> RpcConnection::getRootObject() {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +000095 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
96 return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +000097}
98
Steven Morelandf137de92021-04-24 01:54:26 +000099status_t RpcConnection::getMaxThreads(size_t* maxThreads) {
100 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
101 return state()->getMaxThreads(socket.fd(), sp<RpcConnection>::fromExisting(this), maxThreads);
102}
103
Steven Moreland5553ac42020-11-11 02:14:45 +0000104status_t RpcConnection::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
105 Parcel* reply, uint32_t flags) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000106 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this),
Steven Moreland5553ac42020-11-11 02:14:45 +0000107 (flags & IBinder::FLAG_ONEWAY) ? SocketUse::CLIENT_ASYNC
108 : SocketUse::CLIENT);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000109 return state()->transact(socket.fd(), address, code, data,
110 sp<RpcConnection>::fromExisting(this), reply, flags);
Steven Moreland5553ac42020-11-11 02:14:45 +0000111}
112
113status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000114 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT_REFCOUNT);
Steven Moreland5553ac42020-11-11 02:14:45 +0000115 return state()->sendDecStrong(socket.fd(), address);
116}
117
Steven Moreland7c5e6c22021-05-01 02:55:20 +0000118status_t RpcConnection::readId() {
119 {
120 std::lock_guard<std::mutex> _l(mSocketMutex);
121 LOG_ALWAYS_FATAL_IF(mForServer != nullptr, "Can only update ID for client.");
122 }
123
124 int32_t id;
125
126 ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
127 status_t status =
128 state()->getConnectionId(socket.fd(), sp<RpcConnection>::fromExisting(this), &id);
129 if (status != OK) return status;
130
131 LOG_RPC_DETAIL("RpcConnection %p has id %d", this, id);
132 mId = id;
133 return OK;
134}
135
Steven Moreland736664b2021-05-01 04:27:25 +0000136void RpcConnection::startThread(unique_fd client) {
137 std::lock_guard<std::mutex> _l(mSocketMutex);
138 sp<RpcConnection> holdThis = sp<RpcConnection>::fromExisting(this);
139 int fd = client.release();
140 auto thread = std::thread([=] {
141 holdThis->join(unique_fd(fd));
142 {
143 std::lock_guard<std::mutex> _l(holdThis->mSocketMutex);
144 size_t erased = mThreads.erase(std::this_thread::get_id());
145 LOG_ALWAYS_FATAL_IF(erased != 0, "Could not erase thread.");
146 }
147 });
148 mThreads[thread.get_id()] = std::move(thread);
149}
150
Steven Moreland611d15f2021-05-01 01:28:27 +0000151void RpcConnection::join(unique_fd client) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000152 // must be registered to allow arbitrary client code executing commands to
153 // be able to do nested calls (we can't only read from it)
Steven Moreland611d15f2021-05-01 01:28:27 +0000154 sp<ConnectionSocket> socket = assignServerToThisThread(std::move(client));
Steven Moreland5553ac42020-11-11 02:14:45 +0000155
156 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000157 status_t error =
Steven Morelandaf816d82021-04-19 23:11:33 +0000158 state()->getAndExecuteCommand(socket->fd, sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000159
160 if (error != OK) {
161 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
Steven Morelandaf816d82021-04-19 23:11:33 +0000162 break;
Steven Moreland5553ac42020-11-11 02:14:45 +0000163 }
164 }
Steven Morelandaf816d82021-04-19 23:11:33 +0000165
166 LOG_ALWAYS_FATAL_IF(!removeServerSocket(socket),
167 "bad state: socket object guaranteed to be in list");
Steven Moreland5553ac42020-11-11 02:14:45 +0000168}
169
Steven Moreland5553ac42020-11-11 02:14:45 +0000170wp<RpcServer> RpcConnection::server() {
171 return mForServer;
172}
173
Steven Moreland611d15f2021-05-01 01:28:27 +0000174bool RpcConnection::setupSocketClient(const RpcSocketAddress& addr) {
Steven Morelandf137de92021-04-24 01:54:26 +0000175 {
176 std::lock_guard<std::mutex> _l(mSocketMutex);
177 LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
178 "Must only setup connection once, but already has %zu clients",
179 mClients.size());
180 }
181
Steven Moreland736664b2021-05-01 04:27:25 +0000182 if (!setupOneSocketClient(addr, RPC_CONNECTION_ID_NEW)) return false;
Steven Morelandf137de92021-04-24 01:54:26 +0000183
184 // TODO(b/185167543): we should add additional connections dynamically
185 // instead of all at once.
186 // TODO(b/186470974): first risk of blocking
187 size_t numThreadsAvailable;
188 if (status_t status = getMaxThreads(&numThreadsAvailable); status != OK) {
189 ALOGE("Could not get max threads after initial connection to %s: %s",
190 addr.toString().c_str(), statusToString(status).c_str());
191 return false;
192 }
193
Steven Moreland7c5e6c22021-05-01 02:55:20 +0000194 if (status_t status = readId(); status != OK) {
195 ALOGE("Could not get connection id after initial connection to %s; %s",
196 addr.toString().c_str(), statusToString(status).c_str());
197 return false;
198 }
199
Steven Morelandf137de92021-04-24 01:54:26 +0000200 // we've already setup one client
201 for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
202 // TODO(b/185167543): avoid race w/ accept4 not being called on server
203 for (size_t tries = 0; tries < 5; tries++) {
Steven Moreland736664b2021-05-01 04:27:25 +0000204 if (setupOneSocketClient(addr, mId.value())) break;
Steven Morelandf137de92021-04-24 01:54:26 +0000205 usleep(10000);
206 }
207 }
208
209 return true;
210}
211
Steven Moreland736664b2021-05-01 04:27:25 +0000212bool RpcConnection::setupOneSocketClient(const RpcSocketAddress& addr, int32_t id) {
Steven Morelandc1635952021-04-01 16:20:47 +0000213 unique_fd serverFd(
214 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
215 if (serverFd == -1) {
216 int savedErrno = errno;
217 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
218 return false;
219 }
220
221 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
222 int savedErrno = errno;
223 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
224 return false;
225 }
226
Steven Moreland736664b2021-05-01 04:27:25 +0000227 if (sizeof(id) != TEMP_FAILURE_RETRY(write(serverFd.get(), &id, sizeof(id)))) {
228 int savedErrno = errno;
229 ALOGE("Could not write id to socket at %s: %s", addr.toString().c_str(),
230 strerror(savedErrno));
231 return false;
232 }
233
Steven Morelandc1635952021-04-01 16:20:47 +0000234 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
235
Steven Morelandd47b32c2021-04-13 02:03:08 +0000236 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000237 return true;
238}
239
Steven Morelanda4c94752021-05-01 01:34:24 +0000240void RpcConnection::addClient(unique_fd fd) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000241 std::lock_guard<std::mutex> _l(mSocketMutex);
242 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
243 connection->fd = std::move(fd);
244 mClients.push_back(connection);
245}
246
Steven Moreland7c5e6c22021-05-01 02:55:20 +0000247void RpcConnection::setForServer(const wp<RpcServer>& server, int32_t connectionId) {
248 mId = connectionId;
249 mForServer = server;
250}
251
Steven Morelanda4c94752021-05-01 01:34:24 +0000252sp<RpcConnection::ConnectionSocket> RpcConnection::assignServerToThisThread(unique_fd fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000253 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000254 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000255 connection->fd = std::move(fd);
Steven Morelandaf816d82021-04-19 23:11:33 +0000256 connection->exclusiveTid = gettid();
Steven Moreland5553ac42020-11-11 02:14:45 +0000257 mServers.push_back(connection);
Steven Morelandaf816d82021-04-19 23:11:33 +0000258
259 return connection;
260}
261
262bool RpcConnection::removeServerSocket(const sp<ConnectionSocket>& socket) {
263 std::lock_guard<std::mutex> _l(mSocketMutex);
264 if (auto it = std::find(mServers.begin(), mServers.end(), socket); it != mServers.end()) {
265 mServers.erase(it);
266 return true;
267 }
268 return false;
Steven Moreland5553ac42020-11-11 02:14:45 +0000269}
270
271RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
272 : mConnection(connection) {
273 pid_t tid = gettid();
274 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
275
276 mConnection->mWaitingThreads++;
277 while (true) {
278 sp<ConnectionSocket> exclusive;
279 sp<ConnectionSocket> available;
280
281 // CHECK FOR DEDICATED CLIENT SOCKET
282 //
Steven Morelandaf816d82021-04-19 23:11:33 +0000283 // A server/looper should always use a dedicated connection if available
284 findSocket(tid, &exclusive, &available, mConnection->mClients, mConnection->mClientsOffset);
Steven Moreland5553ac42020-11-11 02:14:45 +0000285
Steven Morelandaf816d82021-04-19 23:11:33 +0000286 // WARNING: this assumes a server cannot request its client to send
287 // a transaction, as mServers is excluded below.
288 //
289 // Imagine we have more than one thread in play, and a single thread
290 // sends a synchronous, then an asynchronous command. Imagine the
291 // asynchronous command is sent on the first client socket. Then, if
292 // we naively send a synchronous command to that same socket, the
293 // thread on the far side might be busy processing the asynchronous
294 // command. So, we move to considering the second available thread
295 // for subsequent calls.
296 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
297 mConnection->mClientsOffset =
298 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
Steven Moreland5553ac42020-11-11 02:14:45 +0000299 }
300
Steven Morelandaf816d82021-04-19 23:11:33 +0000301 // USE SERVING SOCKET (for nested transaction)
Steven Moreland5553ac42020-11-11 02:14:45 +0000302 //
303 // asynchronous calls cannot be nested
304 if (use != SocketUse::CLIENT_ASYNC) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000305 // server sockets are always assigned to a thread
306 findSocket(tid, &exclusive, nullptr /*available*/, mConnection->mServers,
307 0 /* index hint */);
Steven Moreland5553ac42020-11-11 02:14:45 +0000308 }
309
310 // if our thread is already using a connection, prioritize using that
311 if (exclusive != nullptr) {
312 mSocket = exclusive;
313 mReentrant = true;
314 break;
315 } else if (available != nullptr) {
316 mSocket = available;
317 mSocket->exclusiveTid = tid;
318 break;
319 }
320
Steven Moreland5553ac42020-11-11 02:14:45 +0000321 // in regular binder, this would usually be a deadlock :)
322 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
323 "Not a client of any connection. You must create a connection to an "
324 "RPC server to make any non-nested (e.g. oneway or on another thread) "
325 "calls.");
326
327 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
328 mConnection->mClients.size(), mConnection->mServers.size());
329 mConnection->mSocketCv.wait(_l);
330 }
331 mConnection->mWaitingThreads--;
332}
333
334void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
335 sp<ConnectionSocket>* available,
336 std::vector<sp<ConnectionSocket>>& sockets,
337 size_t socketsIndexHint) {
338 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
339 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
340
341 if (*exclusive != nullptr) return; // consistent with break below
342
343 for (size_t i = 0; i < sockets.size(); i++) {
344 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
345
346 // take first available connection (intuition = caching)
347 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
348 *available = socket;
349 continue;
350 }
351
352 // though, prefer to take connection which is already inuse by this thread
353 // (nested transactions)
354 if (exclusive && socket->exclusiveTid == tid) {
355 *exclusive = socket;
356 break; // consistent with return above
357 }
358 }
359}
360
361RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
362 // reentrant use of a connection means something less deep in the call stack
363 // is using this fd, and it retains the right to it. So, we don't give up
364 // exclusive ownership, and no thread is freed.
365 if (!mReentrant) {
366 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
367 mSocket->exclusiveTid = std::nullopt;
368 if (mConnection->mWaitingThreads > 0) {
369 _l.unlock();
370 mConnection->mSocketCv.notify_one();
371 }
372 }
373}
374
375} // namespace android