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