• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <binder/Common.h>
19 #include <binder/IBinder.h>
20 #include <binder/RpcThreads.h>
21 #include <binder/RpcTransport.h>
22 #include <binder/unique_fd.h>
23 #include <utils/Errors.h>
24 #include <utils/RefBase.h>
25 
26 #include <map>
27 #include <optional>
28 #include <vector>
29 
30 namespace android {
31 
32 class Parcel;
33 class RpcServer;
34 class RpcServerTrusty;
35 class RpcSocketAddress;
36 class RpcState;
37 class RpcTransport;
38 class FdTrigger;
39 
40 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 2;
41 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL = 0xF0000000;
42 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = 1;
43 
44 // Starting with this version:
45 //
46 // * RpcWireReply is larger (4 bytes -> 20).
47 // * RpcWireTransaction and RpcWireReplyV1 include the parcel data size.
48 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE = 1;
49 
50 /**
51  * This represents a session (group of connections) between a client
52  * and a server. Multiple connections are needed for multiple parallel "binder"
53  * calls which may also have nested calls.
54  *
55  * Once a binder exists in the session, if all references to all binders are dropped,
56  * the session shuts down.
57  */
58 class RpcSession final : public virtual RefBase {
59 public:
60     // Create an RpcSession with default configuration (raw sockets).
61     LIBBINDER_EXPORTED static sp<RpcSession> make();
62 
63     // Create an RpcSession with the given configuration. |serverRpcCertificateFormat| and
64     // |serverCertificate| must have values or be nullopt simultaneously. If they have values, set
65     // server certificate.
66     LIBBINDER_EXPORTED static sp<RpcSession> make(
67             std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory);
68 
69     /**
70      * Set the maximum number of incoming threads allowed to be made (for things like callbacks).
71      * By default, this is 0. This must be called before setting up this connection as a client.
72      * Server sessions will inherits this value from RpcServer. Each thread will serve a
73      * connection to the remote RpcSession.
74      *
75      * If this is called, 'shutdown' on this session must also be called.
76      * Otherwise, a threadpool will leak.
77      *
78      * TODO(b/189955605): start these lazily - currently all are started
79      */
80     LIBBINDER_EXPORTED void setMaxIncomingThreads(size_t threads);
81     LIBBINDER_EXPORTED size_t getMaxIncomingThreads();
82 
83     /**
84      * Set the maximum number of outgoing connections allowed to be made.
85      * By default, this is |kDefaultMaxOutgoingConnections|. This must be called before setting up
86      * this connection as a client.
87      *
88      * For an RpcSession client, if you are connecting to a server which starts N threads,
89      * then this must be set to >= N. If you set the maximum number of outgoing connections
90      * to 1, but the server requests 10, then it would be considered an error. If you set a
91      * maximum number of connections to 10, and the server requests 1, then only 1 will be
92      * created. This API is used to limit the amount of resources a server can request you
93      * create.
94      */
95     LIBBINDER_EXPORTED void setMaxOutgoingConnections(size_t connections);
96     LIBBINDER_EXPORTED size_t getMaxOutgoingThreads();
97 
98     /**
99      * By default, the minimum of the supported versions of the client and the
100      * server will be used. Usually, this API should only be used for debugging.
101      */
102     [[nodiscard]] LIBBINDER_EXPORTED bool setProtocolVersion(uint32_t version);
103     LIBBINDER_EXPORTED std::optional<uint32_t> getProtocolVersion();
104 
105     enum class FileDescriptorTransportMode : uint8_t {
106         NONE = 0,
107         // Send file descriptors via unix domain socket ancillary data.
108         UNIX = 1,
109         // Send file descriptors as Trusty IPC handles.
110         TRUSTY = 2,
111     };
112 
113     /**
114      * Set the transport for sending and receiving file descriptors.
115      */
116     LIBBINDER_EXPORTED void setFileDescriptorTransportMode(FileDescriptorTransportMode mode);
117     LIBBINDER_EXPORTED FileDescriptorTransportMode getFileDescriptorTransportMode();
118 
119     /**
120      * This should be called once per thread, matching 'join' in the remote
121      * process.
122      */
123     [[nodiscard]] LIBBINDER_EXPORTED status_t setupUnixDomainClient(const char* path);
124 
125     /**
126      * Connects to an RPC server over a nameless Unix domain socket pair.
127      */
128     [[nodiscard]] LIBBINDER_EXPORTED status_t
129     setupUnixDomainSocketBootstrapClient(binder::unique_fd bootstrap);
130 
131     /**
132      * Connects to an RPC server at the CID & port.
133      */
134     [[nodiscard]] LIBBINDER_EXPORTED status_t setupVsockClient(unsigned int cid, unsigned int port);
135 
136     /**
137      * Connects to an RPC server at the given address and port.
138      */
139     [[nodiscard]] LIBBINDER_EXPORTED status_t setupInetClient(const char* addr, unsigned int port);
140 
141     /**
142      * Starts talking to an RPC server which has already been connected to. This
143      * is expected to be used when another process has permission to connect to
144      * a binder RPC service, but this process only has permission to talk to
145      * that service.
146      *
147      * For convenience, if 'fd' is -1, 'request' will be called.
148      *
149      * For future compatibility, 'request' should not reference any stack data.
150      */
151     [[nodiscard]] LIBBINDER_EXPORTED status_t
152     setupPreconnectedClient(binder::unique_fd fd, std::function<binder::unique_fd()>&& request);
153 
154     /**
155      * For debugging!
156      *
157      * Sets up an empty connection. All queries to this connection which require a
158      * response will never be satisfied. All data sent here will be
159      * unceremoniously cast down the bottomless pit, /dev/null.
160      */
161     [[nodiscard]] LIBBINDER_EXPORTED status_t addNullDebuggingClient();
162 
163     /**
164      * Query the other side of the session for the root object hosted by that
165      * process's RpcServer (if one exists)
166      */
167     LIBBINDER_EXPORTED sp<IBinder> getRootObject();
168 
169     /**
170      * Query the other side of the session for the maximum number of threads
171      * it supports (maximum number of concurrent non-nested synchronous transactions)
172      */
173     [[nodiscard]] LIBBINDER_EXPORTED status_t getRemoteMaxThreads(size_t* maxThreads);
174 
175     /**
176      * See RpcTransportCtx::getCertificate
177      */
178     LIBBINDER_EXPORTED std::vector<uint8_t> getCertificate(RpcCertificateFormat);
179 
180     /**
181      * Shuts down the service.
182      *
183      * For client sessions, wait can be true or false. For server sessions,
184      * waiting is not currently supported (will abort).
185      *
186      * Warning: this is currently not active/nice (the server isn't told we're
187      * shutting down). Being nicer to the server could potentially make it
188      * reclaim resources faster.
189      *
190      * If this is called w/ 'wait' true, then this will wait for shutdown to
191      * complete before returning. This will hang if it is called from the
192      * session threadpool (when processing received calls).
193      */
194     [[nodiscard]] LIBBINDER_EXPORTED bool shutdownAndWait(bool wait);
195 
196     [[nodiscard]] LIBBINDER_EXPORTED status_t transact(const sp<IBinder>& binder, uint32_t code,
197                                                        const Parcel& data, Parcel* reply,
198                                                        uint32_t flags);
199 
200     /**
201      * Generally, you should not call this, unless you are testing error
202      * conditions, as this is called automatically by BpBinders when they are
203      * deleted (this is also why a raw pointer is used here)
204      */
205     [[nodiscard]] LIBBINDER_EXPORTED status_t sendDecStrong(const BpBinder* binder);
206 
207     /**
208      * Whether any requests are currently being processed.
209      */
210     LIBBINDER_EXPORTED bool hasActiveRequests();
211 
212     LIBBINDER_EXPORTED ~RpcSession();
213 
214     /**
215      * Server if this session is created as part of a server (symmetrical to
216      * client servers). Otherwise, nullptr.
217      */
218     LIBBINDER_EXPORTED sp<RpcServer> server();
219 
220     // internal only
state()221     LIBBINDER_EXPORTED const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
222 
223 private:
224     friend sp<RpcSession>;
225     friend RpcServer;
226     friend RpcServerTrusty;
227     friend RpcState;
228     explicit RpcSession(std::unique_ptr<RpcTransportCtx> ctx);
229 
230     static constexpr size_t kDefaultMaxOutgoingConnections = 10;
231 
232     // internal version of setProtocolVersion that
233     // optionally skips the mStartedSetup check
234     [[nodiscard]] bool setProtocolVersionInternal(uint32_t version, bool checkStarted);
235 
236     // for 'target', see RpcState::sendDecStrongToTarget
237     [[nodiscard]] status_t sendDecStrongToTarget(uint64_t address, size_t target);
238 
239     class EventListener : public virtual RefBase {
240     public:
241         virtual void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0;
242         virtual void onSessionIncomingThreadEnded() = 0;
243     };
244 
245     class WaitForShutdownListener : public EventListener {
246     public:
247         void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
248         void onSessionIncomingThreadEnded() override;
249         void waitForShutdown(RpcMutexUniqueLock& lock, const sp<RpcSession>& session);
250 
251     private:
252         RpcConditionVariable mCv;
253         std::atomic<size_t> mShutdownCount = 0;
254     };
255     friend WaitForShutdownListener;
256 
257     struct RpcConnection : public RefBase {
258         std::unique_ptr<RpcTransport> rpcTransport;
259 
260         // whether this or another thread is currently using this fd to make
261         // or receive transactions.
262         std::optional<uint64_t> exclusiveTid;
263 
264         bool allowNested = false;
265     };
266 
267     [[nodiscard]] status_t readId();
268 
269     // A thread joining a server must always call these functions in order, and
270     // cleanup is only programmed once into join. These are in separate
271     // functions in order to allow for different locks to be taken during
272     // different parts of setup.
273     //
274     // transfer ownership of thread (usually done while a lock is taken on the
275     // structure which originally owns the thread)
276     void preJoinThreadOwnership(RpcMaybeThread thread);
277     // pass FD to thread and read initial connection information
278     struct PreJoinSetupResult {
279         // Server connection object associated with this
280         sp<RpcConnection> connection;
281         // Status of setup
282         status_t status;
283     };
284     PreJoinSetupResult preJoinSetup(std::unique_ptr<RpcTransport> rpcTransport);
285     // join on thread passed to preJoinThreadOwnership
286     static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result);
287 
288     [[nodiscard]] status_t setupClient(
289             const std::function<status_t(const std::vector<uint8_t>& sessionId, bool incoming)>&
290                     connectAndInit);
291     [[nodiscard]] status_t setupSocketClient(const RpcSocketAddress& address);
292     [[nodiscard]] status_t setupOneSocketConnection(const RpcSocketAddress& address,
293                                                     const std::vector<uint8_t>& sessionId,
294                                                     bool incoming);
295     [[nodiscard]] status_t initAndAddConnection(RpcTransportFd fd,
296                                                 const std::vector<uint8_t>& sessionId,
297                                                 bool incoming);
298     [[nodiscard]] status_t addIncomingConnection(std::unique_ptr<RpcTransport> rpcTransport);
299     [[nodiscard]] status_t addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTransport,
300                                                  bool init);
301     [[nodiscard]] bool setForServer(const wp<RpcServer>& server,
302                                     const wp<RpcSession::EventListener>& eventListener,
303                                     const std::vector<uint8_t>& sessionId,
304                                     const sp<IBinder>& sessionSpecificRoot);
305     sp<RpcConnection> assignIncomingConnectionToThisThread(
306             std::unique_ptr<RpcTransport> rpcTransport);
307     [[nodiscard]] bool removeIncomingConnection(const sp<RpcConnection>& connection);
308     void clearConnectionTid(const sp<RpcConnection>& connection);
309 
310     [[nodiscard]] status_t initShutdownTrigger();
311 
312     /**
313      * Checks whether any connection is active (Not polling on fd)
314      */
315     bool hasActiveConnection(const std::vector<sp<RpcConnection>>& connections);
316 
317     enum class ConnectionUse {
318         CLIENT,
319         CLIENT_ASYNC,
320         CLIENT_REFCOUNT,
321     };
322 
323     // Object representing exclusive access to a connection.
324     class ExclusiveConnection {
325     public:
326         [[nodiscard]] static status_t find(const sp<RpcSession>& session, ConnectionUse use,
327                                            ExclusiveConnection* connection);
328 
329         ~ExclusiveConnection();
get()330         const sp<RpcConnection>& get() { return mConnection; }
331 
332     private:
333         static void findConnection(uint64_t tid, sp<RpcConnection>* exclusive,
334                                    sp<RpcConnection>* available,
335                                    std::vector<sp<RpcConnection>>& sockets,
336                                    size_t socketsIndexHint);
337 
338         sp<RpcSession> mSession; // avoid deallocation
339         sp<RpcConnection> mConnection;
340 
341         // whether this is being used for a nested transaction (being on the same
342         // thread guarantees we won't write in the middle of a message, the way
343         // the wire protocol is constructed guarantees this is safe).
344         bool mReentrant = false;
345     };
346 
347     const std::unique_ptr<RpcTransportCtx> mCtx;
348 
349     // On the other side of a session, for each of mOutgoing here, there should
350     // be one of mIncoming on the other side (and vice versa).
351     //
352     // For the simplest session, a single server with one client, you would
353     // have:
354     //  - the server has a single 'mIncoming' and a thread listening on this
355     //  - the client has a single 'mOutgoing' and makes calls to this
356     //  - here, when the client makes a call, the server can call back into it
357     //    (nested calls), but outside of this, the client will only ever read
358     //    calls from the server when it makes a call itself.
359     //
360     // For a more complicated case, the client might itself open up a thread to
361     // serve calls to the server at all times (e.g. if it hosts a callback)
362 
363     wp<RpcServer> mForServer;                      // maybe null, for client sessions
364     sp<WaitForShutdownListener> mShutdownListener; // used for client sessions
365     wp<EventListener> mEventListener; // mForServer if server, mShutdownListener if client
366 
367     // session-specific root object (if a different root is used for each
368     // session)
369     sp<IBinder> mSessionSpecificRootObject;
370 
371     std::vector<uint8_t> mId;
372 
373     std::unique_ptr<FdTrigger> mShutdownTrigger;
374 
375     std::unique_ptr<RpcState> mRpcBinderState;
376 
377     RpcMutex mMutex; // for all below
378 
379     bool mStartedSetup = false;
380     size_t mMaxIncomingThreads = 0;
381     size_t mMaxOutgoingConnections = kDefaultMaxOutgoingConnections;
382     std::optional<uint32_t> mProtocolVersion;
383     FileDescriptorTransportMode mFileDescriptorTransportMode = FileDescriptorTransportMode::NONE;
384 
385     RpcConditionVariable mAvailableConnectionCv; // for mWaitingThreads
386 
387     std::unique_ptr<RpcTransport> mBootstrapTransport;
388 
389     struct ThreadState {
390         size_t mWaitingThreads = 0;
391         // hint index into clients, ++ when sending an async transaction
392         size_t mOutgoingOffset = 0;
393         std::vector<sp<RpcConnection>> mOutgoing;
394         // max size of mIncoming. Once any thread starts down, no more can be started.
395         size_t mMaxIncoming = 0;
396         std::vector<sp<RpcConnection>> mIncoming;
397         std::map<RpcMaybeThread::id, RpcMaybeThread> mThreads;
398     } mConnections;
399 };
400 
401 } // namespace android
402