blob: 930bcbde62f575c8fc362131beee4c29a8f0d23f [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 Moreland611d15f2021-05-01 01:28:27 +0000118void RpcConnection::join(unique_fd client) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000119 // must be registered to allow arbitrary client code executing commands to
120 // be able to do nested calls (we can't only read from it)
Steven Moreland611d15f2021-05-01 01:28:27 +0000121 sp<ConnectionSocket> socket = assignServerToThisThread(std::move(client));
Steven Moreland5553ac42020-11-11 02:14:45 +0000122
123 while (true) {
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000124 status_t error =
Steven Morelandaf816d82021-04-19 23:11:33 +0000125 state()->getAndExecuteCommand(socket->fd, sp<RpcConnection>::fromExisting(this));
Steven Moreland5553ac42020-11-11 02:14:45 +0000126
127 if (error != OK) {
128 ALOGI("Binder socket thread closing w/ status %s", statusToString(error).c_str());
Steven Morelandaf816d82021-04-19 23:11:33 +0000129 break;
Steven Moreland5553ac42020-11-11 02:14:45 +0000130 }
131 }
Steven Morelandaf816d82021-04-19 23:11:33 +0000132
133 LOG_ALWAYS_FATAL_IF(!removeServerSocket(socket),
134 "bad state: socket object guaranteed to be in list");
Steven Moreland5553ac42020-11-11 02:14:45 +0000135}
136
137void RpcConnection::setForServer(const wp<RpcServer>& server) {
138 mForServer = server;
139}
140
141wp<RpcServer> RpcConnection::server() {
142 return mForServer;
143}
144
Steven Moreland611d15f2021-05-01 01:28:27 +0000145bool RpcConnection::setupSocketClient(const RpcSocketAddress& addr) {
Steven Morelandf137de92021-04-24 01:54:26 +0000146 {
147 std::lock_guard<std::mutex> _l(mSocketMutex);
148 LOG_ALWAYS_FATAL_IF(mClients.size() != 0,
149 "Must only setup connection once, but already has %zu clients",
150 mClients.size());
151 }
152
153 if (!setupOneSocketClient(addr)) return false;
154
155 // TODO(b/185167543): we should add additional connections dynamically
156 // instead of all at once.
157 // TODO(b/186470974): first risk of blocking
158 size_t numThreadsAvailable;
159 if (status_t status = getMaxThreads(&numThreadsAvailable); status != OK) {
160 ALOGE("Could not get max threads after initial connection to %s: %s",
161 addr.toString().c_str(), statusToString(status).c_str());
162 return false;
163 }
164
165 // we've already setup one client
166 for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
167 // TODO(b/185167543): avoid race w/ accept4 not being called on server
168 for (size_t tries = 0; tries < 5; tries++) {
169 if (setupOneSocketClient(addr)) break;
170 usleep(10000);
171 }
172 }
173
174 return true;
175}
176
Steven Moreland611d15f2021-05-01 01:28:27 +0000177bool RpcConnection::setupOneSocketClient(const RpcSocketAddress& addr) {
Steven Morelandc1635952021-04-01 16:20:47 +0000178 unique_fd serverFd(
179 TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
180 if (serverFd == -1) {
181 int savedErrno = errno;
182 ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
183 return false;
184 }
185
186 if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
187 int savedErrno = errno;
188 ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
189 return false;
190 }
191
192 LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
193
Steven Morelandd47b32c2021-04-13 02:03:08 +0000194 addClient(std::move(serverFd));
Steven Morelandc1635952021-04-01 16:20:47 +0000195 return true;
196}
197
Steven Morelanda4c94752021-05-01 01:34:24 +0000198void RpcConnection::addClient(unique_fd fd) {
Steven Morelandd47b32c2021-04-13 02:03:08 +0000199 std::lock_guard<std::mutex> _l(mSocketMutex);
200 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
201 connection->fd = std::move(fd);
202 mClients.push_back(connection);
203}
204
Steven Morelanda4c94752021-05-01 01:34:24 +0000205sp<RpcConnection::ConnectionSocket> RpcConnection::assignServerToThisThread(unique_fd fd) {
Steven Moreland5553ac42020-11-11 02:14:45 +0000206 std::lock_guard<std::mutex> _l(mSocketMutex);
Steven Moreland1a3a8ef2021-04-02 02:52:46 +0000207 sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
Steven Moreland5553ac42020-11-11 02:14:45 +0000208 connection->fd = std::move(fd);
Steven Morelandaf816d82021-04-19 23:11:33 +0000209 connection->exclusiveTid = gettid();
Steven Moreland5553ac42020-11-11 02:14:45 +0000210 mServers.push_back(connection);
Steven Morelandaf816d82021-04-19 23:11:33 +0000211
212 return connection;
213}
214
215bool RpcConnection::removeServerSocket(const sp<ConnectionSocket>& socket) {
216 std::lock_guard<std::mutex> _l(mSocketMutex);
217 if (auto it = std::find(mServers.begin(), mServers.end(), socket); it != mServers.end()) {
218 mServers.erase(it);
219 return true;
220 }
221 return false;
Steven Moreland5553ac42020-11-11 02:14:45 +0000222}
223
224RpcConnection::ExclusiveSocket::ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use)
225 : mConnection(connection) {
226 pid_t tid = gettid();
227 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
228
229 mConnection->mWaitingThreads++;
230 while (true) {
231 sp<ConnectionSocket> exclusive;
232 sp<ConnectionSocket> available;
233
234 // CHECK FOR DEDICATED CLIENT SOCKET
235 //
Steven Morelandaf816d82021-04-19 23:11:33 +0000236 // A server/looper should always use a dedicated connection if available
237 findSocket(tid, &exclusive, &available, mConnection->mClients, mConnection->mClientsOffset);
Steven Moreland5553ac42020-11-11 02:14:45 +0000238
Steven Morelandaf816d82021-04-19 23:11:33 +0000239 // WARNING: this assumes a server cannot request its client to send
240 // a transaction, as mServers is excluded below.
241 //
242 // Imagine we have more than one thread in play, and a single thread
243 // sends a synchronous, then an asynchronous command. Imagine the
244 // asynchronous command is sent on the first client socket. Then, if
245 // we naively send a synchronous command to that same socket, the
246 // thread on the far side might be busy processing the asynchronous
247 // command. So, we move to considering the second available thread
248 // for subsequent calls.
249 if (use == SocketUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
250 mConnection->mClientsOffset =
251 (mConnection->mClientsOffset + 1) % mConnection->mClients.size();
Steven Moreland5553ac42020-11-11 02:14:45 +0000252 }
253
Steven Morelandaf816d82021-04-19 23:11:33 +0000254 // USE SERVING SOCKET (for nested transaction)
Steven Moreland5553ac42020-11-11 02:14:45 +0000255 //
256 // asynchronous calls cannot be nested
257 if (use != SocketUse::CLIENT_ASYNC) {
Steven Morelandaf816d82021-04-19 23:11:33 +0000258 // server sockets are always assigned to a thread
259 findSocket(tid, &exclusive, nullptr /*available*/, mConnection->mServers,
260 0 /* index hint */);
Steven Moreland5553ac42020-11-11 02:14:45 +0000261 }
262
263 // if our thread is already using a connection, prioritize using that
264 if (exclusive != nullptr) {
265 mSocket = exclusive;
266 mReentrant = true;
267 break;
268 } else if (available != nullptr) {
269 mSocket = available;
270 mSocket->exclusiveTid = tid;
271 break;
272 }
273
Steven Moreland5553ac42020-11-11 02:14:45 +0000274 // in regular binder, this would usually be a deadlock :)
275 LOG_ALWAYS_FATAL_IF(mConnection->mClients.size() == 0,
276 "Not a client of any connection. You must create a connection to an "
277 "RPC server to make any non-nested (e.g. oneway or on another thread) "
278 "calls.");
279
280 LOG_RPC_DETAIL("No available connection (have %zu clients and %zu servers). Waiting...",
281 mConnection->mClients.size(), mConnection->mServers.size());
282 mConnection->mSocketCv.wait(_l);
283 }
284 mConnection->mWaitingThreads--;
285}
286
287void RpcConnection::ExclusiveSocket::findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
288 sp<ConnectionSocket>* available,
289 std::vector<sp<ConnectionSocket>>& sockets,
290 size_t socketsIndexHint) {
291 LOG_ALWAYS_FATAL_IF(sockets.size() > 0 && socketsIndexHint >= sockets.size(),
292 "Bad index %zu >= %zu", socketsIndexHint, sockets.size());
293
294 if (*exclusive != nullptr) return; // consistent with break below
295
296 for (size_t i = 0; i < sockets.size(); i++) {
297 sp<ConnectionSocket>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
298
299 // take first available connection (intuition = caching)
300 if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
301 *available = socket;
302 continue;
303 }
304
305 // though, prefer to take connection which is already inuse by this thread
306 // (nested transactions)
307 if (exclusive && socket->exclusiveTid == tid) {
308 *exclusive = socket;
309 break; // consistent with return above
310 }
311 }
312}
313
314RpcConnection::ExclusiveSocket::~ExclusiveSocket() {
315 // reentrant use of a connection means something less deep in the call stack
316 // is using this fd, and it retains the right to it. So, we don't give up
317 // exclusive ownership, and no thread is freed.
318 if (!mReentrant) {
319 std::unique_lock<std::mutex> _l(mConnection->mSocketMutex);
320 mSocket->exclusiveTid = std::nullopt;
321 if (mConnection->mWaitingThreads > 0) {
322 _l.unlock();
323 mConnection->mSocketCv.notify_one();
324 }
325 }
326}
327
328} // namespace android