blob: 95eba87b68b7fd06193112535c175c1f6551f212 [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 Moreland611d15f2021-05-01 01:28:27 +0000136void RpcConnection::join(unique_fd client) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000137 // must be registered to allow arbitrary client code executing commands to
138 // be able to do nested calls (we can't only read from it)
Steven Moreland611d15f2021-05-01 01:28:27 +0000139 sp<ConnectionSocket> socket = assignServerToThisThread(std::move(client));
Steven Moreland5553ac42020-11-11 02:14:45 +0000140
141 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000142 status_t error =
Steven Morelandaf816d82021-04-19 23:11:33 +0000143 state()->getAndExecuteCommand(socket->fd, sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000144
145 if (error != OK) {
146 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
Steven Morelandaf816d82021-04-19 23:11:33 +0000147 break;
Steven Moreland5553ac42020-11-11 02:14:45 +0000148 }
149 }
Steven Morelandaf816d82021-04-19 23:11:33 +0000150
151 LOG_ALWAYS_FATAL_IF(!removeServerSocket(socket),
152 "bad state: socket object guaranteed to be in list");
Steven Moreland5553ac42020-11-11 02:14:45 +0000153}
154
Steven Moreland5553ac42020-11-11 02:14:45 +0000155wp<RpcServer> RpcConnection::server() {
156 return mForServer;
157}
158
Steven Moreland611d15f2021-05-01 01:28:27 +0000159bool RpcConnection::setupSocketClient(const RpcSocketAddress& addr) {
Steven Morelandf137de92021-04-24 01:54:26 +0000160 {
161 std::lock_guard<std::mutex> _l(mSocketMutex);
162 LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
163 "Must only setup connection once, but already has %zu clients",
164 mClients.size());
165 }
166
167 if (!setupOneSocketClient(addr)) return false;
168
169 // TODO(b/185167543): we should add additional connections dynamically
170 // instead of all at once.
171 // TODO(b/186470974): first risk of blocking
172 size_t numThreadsAvailable;
173 if (status_t status = getMaxThreads(&numThreadsAvailable); status != OK) {
174 ALOGE("Could not get max threads after initial connection to %s: %s",
175 addr.toString().c_str(), statusToString(status).c_str());
176 return false;
177 }
178
Steven Moreland7c5e6c22021-05-01 02:55:20 +0000179 if (status_t status = readId(); status != OK) {
180 ALOGE("Could not get connection id after initial connection to %s; %s",
181 addr.toString().c_str(), statusToString(status).c_str());
182 return false;
183 }
184
Steven Morelandf137de92021-04-24 01:54:26 +0000185 // we've already setup one client
186 for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
187 // TODO(b/185167543): avoid race w/ accept4 not being called on server
188 for (size_t tries = 0; tries < 5; tries++) {
189 if (setupOneSocketClient(addr)) break;
190 usleep(10000);
191 }
192 }
193
194 return true;
195}
196
Steven Moreland611d15f2021-05-01 01:28:27 +0000197bool RpcConnection::setupOneSocketClient(const RpcSocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000198 unique_fd serverFd(
199 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
200 if (serverFd == -1) {
201 int savedErrno = errno;
202 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
203 return false;
204 }
205
206 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
207 int savedErrno = errno;
208 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
209 return false;
210 }
211
212 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
213
Steven Morelandd47b32c2021-04-13 02:03:08 +0000214 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000215 return true;
216}
217
Steven Morelanda4c94752021-05-01 01:34:24 +0000218void RpcConnection::addClient(unique_fd fd) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000219 std::lock_guard<std::mutex> _l(mSocketMutex);
220 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
221 connection->fd = std::move(fd);
222 mClients.push_back(connection);
223}
224
Steven Moreland7c5e6c22021-05-01 02:55:20 +0000225void RpcConnection::setForServer(const wp<RpcServer>& server, int32_t connectionId) {
226 mId = connectionId;
227 mForServer = server;
228}
229
Steven Morelanda4c94752021-05-01 01:34:24 +0000230sp<RpcConnection::ConnectionSocket> RpcConnection::assignServerToThisThread(unique_fd fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000231 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000232 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000233 connection->fd = std::move(fd);
Steven Morelandaf816d82021-04-19 23:11:33 +0000234 connection->exclusiveTid = gettid();
Steven Moreland5553ac42020-11-11 02:14:45 +0000235 mServers.push_back(connection);
Steven Morelandaf816d82021-04-19 23:11:33 +0000236
237 return connection;
238}
239
240bool RpcConnection::removeServerSocket(const sp<ConnectionSocket>& socket) {
241 std::lock_guard<std::mutex> _l(mSocketMutex);
242 if (auto it = std::find(mServers.begin(), mServers.end(), socket); it != mServers.end()) {
243 mServers.erase(it);
244 return true;
245 }
246 return false;
Steven Moreland5553ac42020-11-11 02:14:45 +0000247}
248
249RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
250 : mConnection(connection) {
251 pid_t tid = gettid();
252 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
253
254 mConnection->mWaitingThreads++;
255 while (true) {
256 sp<ConnectionSocket> exclusive;
257 sp<ConnectionSocket> available;
258
259 // CHECK FOR DEDICATED CLIENT SOCKET
260 //
Steven Morelandaf816d82021-04-19 23:11:33 +0000261 // A server/looper should always use a dedicated connection if available
262 findSocket(tid, &exclusive, &available, mConnection->mClients, mConnection->mClientsOffset);
Steven Moreland5553ac42020-11-11 02:14:45 +0000263
Steven Morelandaf816d82021-04-19 23:11:33 +0000264 // WARNING: this assumes a server cannot request its client to send
265 // a transaction, as mServers is excluded below.
266 //
267 // Imagine we have more than one thread in play, and a single thread
268 // sends a synchronous, then an asynchronous command. Imagine the
269 // asynchronous command is sent on the first client socket. Then, if
270 // we naively send a synchronous command to that same socket, the
271 // thread on the far side might be busy processing the asynchronous
272 // command. So, we move to considering the second available thread
273 // for subsequent calls.
274 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
275 mConnection->mClientsOffset =
276 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
Steven Moreland5553ac42020-11-11 02:14:45 +0000277 }
278
Steven Morelandaf816d82021-04-19 23:11:33 +0000279 // USE SERVING SOCKET (for nested transaction)
Steven Moreland5553ac42020-11-11 02:14:45 +0000280 //
281 // asynchronous calls cannot be nested
282 if (use != SocketUse::CLIENT_ASYNC) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000283 // server sockets are always assigned to a thread
284 findSocket(tid, &exclusive, nullptr /*available*/, mConnection->mServers,
285 0 /* index hint */);
Steven Moreland5553ac42020-11-11 02:14:45 +0000286 }
287
288 // if our thread is already using a connection, prioritize using that
289 if (exclusive != nullptr) {
290 mSocket = exclusive;
291 mReentrant = true;
292 break;
293 } else if (available != nullptr) {
294 mSocket = available;
295 mSocket->exclusiveTid = tid;
296 break;
297 }
298
Steven Moreland5553ac42020-11-11 02:14:45 +0000299 // in regular binder, this would usually be a deadlock :)
300 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
301 "Not a client of any connection. You must create a connection to an "
302 "RPC server to make any non-nested (e.g. oneway or on another thread) "
303 "calls.");
304
305 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
306 mConnection->mClients.size(), mConnection->mServers.size());
307 mConnection->mSocketCv.wait(_l);
308 }
309 mConnection->mWaitingThreads--;
310}
311
312void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
313 sp<ConnectionSocket>* available,
314 std::vector<sp<ConnectionSocket>>& sockets,
315 size_t socketsIndexHint) {
316 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
317 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
318
319 if (*exclusive != nullptr) return; // consistent with break below
320
321 for (size_t i = 0; i < sockets.size(); i++) {
322 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
323
324 // take first available connection (intuition = caching)
325 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
326 *available = socket;
327 continue;
328 }
329
330 // though, prefer to take connection which is already inuse by this thread
331 // (nested transactions)
332 if (exclusive && socket->exclusiveTid == tid) {
333 *exclusive = socket;
334 break; // consistent with return above
335 }
336 }
337}
338
339RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
340 // reentrant use of a connection means something less deep in the call stack
341 // is using this fd, and it retains the right to it. So, we don't give up
342 // exclusive ownership, and no thread is freed.
343 if (!mReentrant) {
344 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
345 mSocket->exclusiveTid = std::nullopt;
346 if (mConnection->mWaitingThreads > 0) {
347 _l.unlock();
348 mConnection->mSocketCv.notify_one();
349 }
350 }
351}
352
353} // namespace android