blob: dba47b4d150fce13a677a4b302c453c4227c4f89 [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#pragma once
17
18#include <android-base/unique_fd.h>
19#include <binder/IBinder.h>
20#include <binder/RpcAddress.h>
21#include <utils/Errors.h>
22#include <utils/RefBase.h>
23
24#include <optional>
25#include <vector>
26
27// WARNING: This is a feature which is still in development, and it is subject
28// to radical change. Any production use of this may subject your code to any
29// number of problems.
30
31namespace android {
32
33class Parcel;
34class RpcServer;
35class RpcState;
36
37/**
38 * This represents a multi-threaded/multi-socket connection between a client
39 * and a server.
40 */
41class RpcConnection final : public virtual RefBase {
42public:
43 static sp<RpcConnection> make();
44
45 /**
46 * This represents a connection for responses, e.g.:
47 *
48 * process A serves binder a
49 * process B opens a connection to process A
50 * process B makes binder b and sends it to A
51 * A uses this 'back connection' to send things back to B
52 *
53 * This should be called once, and then a call should be made to join per
54 * connection thread.
55 */
56 [[nodiscard]] bool setupUnixDomainServer(const char* path);
57
58 /**
59 * This should be called once per thread, matching 'join' in the remote
60 * process.
61 */
62 [[nodiscard]] bool addUnixDomainClient(const char* path);
63
Steven Morelandc1635952021-04-01 16:20:47 +000064#ifdef __BIONIC__
65 /**
66 * Creates an RPC server at the current port.
67 */
68 [[nodiscard]] bool setupVsockServer(unsigned int port);
69
70 /**
71 * Connects to an RPC server at the CVD & port.
72 */
73 [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port);
74#endif // __BIONIC__
75
Steven Moreland5553ac42020-11-11 02:14:45 +000076 /**
Steven Morelandd47b32c2021-04-13 02:03:08 +000077 * For debugging!
78 *
79 * Sets up an empty socket. All queries to this socket which require a
80 * response will never be satisfied. All data sent here will be
81 * unceremoniously cast down the bottomless pit, /dev/null.
82 */
83 [[nodiscard]] bool addNullDebuggingClient();
84
85 /**
Steven Moreland5553ac42020-11-11 02:14:45 +000086 * Query the other side of the connection for the root object hosted by that
87 * process's RpcServer (if one exists)
88 */
89 sp<IBinder> getRootObject();
90
91 [[nodiscard]] status_t transact(const RpcAddress& address, uint32_t code, const Parcel& data,
92 Parcel* reply, uint32_t flags);
93 [[nodiscard]] status_t sendDecStrong(const RpcAddress& address);
94
95 /**
96 * Adds a server thread accepting connections. Must be called after
97 * setup*Server.
98 */
99 void join();
100
101 ~RpcConnection();
102
103 void setForServer(const wp<RpcServer>& server);
104 wp<RpcServer> server();
105
106 // internal only
107 const std::unique_ptr<RpcState>& state() { return mState; }
108
Steven Morelandc1635952021-04-01 16:20:47 +0000109 class SocketAddress {
110 public:
111 virtual ~SocketAddress();
112 virtual std::string toString() const = 0;
113 virtual const sockaddr* addr() const = 0;
114 virtual size_t addrSize() const = 0;
115 };
116
Steven Moreland5553ac42020-11-11 02:14:45 +0000117private:
Steven Moreland1fda67b2021-04-02 18:35:50 +0000118 friend sp<RpcConnection>;
Steven Moreland5553ac42020-11-11 02:14:45 +0000119 RpcConnection();
120
Steven Morelandd47b32c2021-04-13 02:03:08 +0000121 bool setupSocketServer(const SocketAddress& address);
122 bool addSocketClient(const SocketAddress& address);
123 void addClient(base::unique_fd&& fd);
Steven Morelandc1635952021-04-01 16:20:47 +0000124 void assignServerToThisThread(base::unique_fd&& fd);
Steven Moreland5553ac42020-11-11 02:14:45 +0000125
126 struct ConnectionSocket : public RefBase {
127 base::unique_fd fd;
128
129 // whether this or another thread is currently using this fd to make
130 // or receive transactions.
131 std::optional<pid_t> exclusiveTid;
132 };
133
134 enum class SocketUse {
135 CLIENT,
136 CLIENT_ASYNC,
137 CLIENT_REFCOUNT,
138 SERVER,
139 };
140
141 // RAII object for connection socket
142 class ExclusiveSocket {
143 public:
144 explicit ExclusiveSocket(const sp<RpcConnection>& connection, SocketUse use);
145 ~ExclusiveSocket();
146 const base::unique_fd& fd() { return mSocket->fd; }
147
148 private:
149 static void findSocket(pid_t tid, sp<ConnectionSocket>* exclusive,
150 sp<ConnectionSocket>* available,
151 std::vector<sp<ConnectionSocket>>& sockets, size_t socketsIndexHint);
152
153 sp<RpcConnection> mConnection; // avoid deallocation
154 sp<ConnectionSocket> mSocket;
155
156 // whether this is being used for a nested transaction (being on the same
157 // thread guarantees we won't write in the middle of a message, the way
158 // the wire protocol is constructed guarantees this is safe).
159 bool mReentrant = false;
160 };
161
162 // On the other side of a connection, for each of mClients here, there should
163 // be one of mServers on the other side (and vice versa).
164 //
165 // For the simplest connection, a single server with one client, you would
166 // have:
167 // - the server has a single 'mServers' and a thread listening on this
168 // - the client has a single 'mClients' and makes calls to this
169 // - here, when the client makes a call, the server can call back into it
170 // (nested calls), but outside of this, the client will only ever read
171 // calls from the server when it makes a call itself.
172 //
173 // For a more complicated case, the client might itself open up a thread to
174 // serve calls to the server at all times (e.g. if it hosts a callback)
175
176 wp<RpcServer> mForServer; // maybe null, for client connections
177
178 std::unique_ptr<RpcState> mState;
179
180 base::unique_fd mServer; // socket we are accepting connections on
181
182 std::mutex mSocketMutex; // for all below
183 std::condition_variable mSocketCv; // for mWaitingThreads
184 size_t mWaitingThreads = 0;
185 size_t mClientsOffset = 0; // hint index into clients, ++ when sending an async transaction
186 std::vector<sp<ConnectionSocket>> mClients;
187 std::vector<sp<ConnectionSocket>> mServers;
188};
189
190} // namespace android