xref: /aosp_15_r20/frameworks/native/libs/binder/include/binder/RpcServer.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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/RpcSession.h>
21 #include <binder/RpcThreads.h>
22 #include <binder/RpcTransport.h>
23 #include <binder/unique_fd.h>
24 #include <utils/Errors.h>
25 #include <utils/RefBase.h>
26 
27 #include <bitset>
28 #include <mutex>
29 #include <thread>
30 
31 namespace android {
32 
33 class FdTrigger;
34 class RpcServerTrusty;
35 class RpcSocketAddress;
36 
37 /**
38  * This represents a server of an interface, which may be connected to by any
39  * number of clients over sockets.
40  *
41  * Usage:
42  *     auto server = RpcServer::make();
43  *     // only supports one now
44  *     if (!server->setup*Server(...)) {
45  *         :(
46  *     }
47  *     server->join();
48  */
49 class RpcServer final : public virtual RefBase, private RpcSession::EventListener {
50 public:
51     LIBBINDER_EXPORTED static sp<RpcServer> make(
52             std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory = nullptr);
53 
54     /**
55      * Creates an RPC server that bootstraps sessions using an existing
56      * Unix domain socket pair.
57      *
58      * Callers should create a pair of SOCK_STREAM Unix domain sockets, pass
59      * one to RpcServer::setupUnixDomainSocketBootstrapServer and the other
60      * to RpcSession::setupUnixDomainSocketBootstrapClient. Multiple client
61      * session can be created from the client end of the pair.
62      */
63     [[nodiscard]] LIBBINDER_EXPORTED status_t
64     setupUnixDomainSocketBootstrapServer(binder::unique_fd serverFd);
65 
66     /**
67      * This represents a session for responses, e.g.:
68      *
69      *     process A serves binder a
70      *     process B opens a session to process A
71      *     process B makes binder b and sends it to A
72      *     A uses this 'back session' to send things back to B
73      */
74     [[nodiscard]] LIBBINDER_EXPORTED status_t setupUnixDomainServer(const char* path);
75 
76     /**
77      * Sets up an RPC server with a raw socket file descriptor.
78      * The socket should be created and bound to a socket address already, e.g.
79      * the socket can be created in init.rc.
80      *
81      * This method is used in the libbinder_rpc_unstable API
82      * RunInitUnixDomainRpcServer().
83      */
84     [[nodiscard]] LIBBINDER_EXPORTED status_t setupRawSocketServer(binder::unique_fd socket_fd);
85 
86     /**
87      * Creates an RPC server binding to the given CID at the given port.
88      *
89      * Set |port| to VMADDR_PORT_ANY to pick an ephemeral port. In this case, |assignedPort|
90      * will be set to the picked port number, if it is not null.
91      */
92     [[nodiscard]] LIBBINDER_EXPORTED status_t setupVsockServer(unsigned bindCid, unsigned port,
93                                                                unsigned* assignedPort = nullptr);
94 
95     /**
96      * Creates an RPC server at the current port using IPv4.
97      *
98      * TODO(b/182914638): IPv6 support
99      *
100      * Set |port| to 0 to pick an ephemeral port; see discussion of
101      * /proc/sys/net/ipv4/ip_local_port_range in ip(7). In this case, |assignedPort|
102      * will be set to the picked port number, if it is not null.
103      *
104      * Set the IPv4 address for the socket to be listening on.
105      * "127.0.0.1" allows for local connections from the same device.
106      * "0.0.0.0" allows for connections on any IP address that the device may
107      * have
108      */
109     [[nodiscard]] LIBBINDER_EXPORTED status_t setupInetServer(const char* address,
110                                                               unsigned int port,
111                                                               unsigned int* assignedPort = nullptr);
112 
113     /**
114      * If setup*Server has been successful, return true. Otherwise return false.
115      */
116     [[nodiscard]] LIBBINDER_EXPORTED bool hasServer();
117 
118     /**
119      * If hasServer(), return the server FD. Otherwise return invalid FD.
120      */
121     [[nodiscard]] LIBBINDER_EXPORTED binder::unique_fd releaseServer();
122 
123     /**
124      * Set up server using an external FD previously set up by releaseServer().
125      * Return false if there's already a server.
126      */
127     [[nodiscard]] LIBBINDER_EXPORTED status_t setupExternalServer(binder::unique_fd serverFd);
128 
129     /**
130      * This must be called before adding a client session. This corresponds
131      * to the number of incoming connections to RpcSession objects in the
132      * server, which will correspond to the number of outgoing connections
133      * in client RpcSession objects.
134      *
135      * If this is not specified, this will be a single-threaded server.
136      *
137      * TODO(b/167966510): these are currently created per client, but these
138      * should be shared.
139      */
140     LIBBINDER_EXPORTED void setMaxThreads(size_t threads);
141     LIBBINDER_EXPORTED size_t getMaxThreads();
142 
143     /**
144      * By default, the latest protocol version which is supported by a client is
145      * used. However, this can be used in order to prevent newer protocol
146      * versions from ever being used. This is expected to be useful for testing.
147      */
148     [[nodiscard]] LIBBINDER_EXPORTED bool setProtocolVersion(uint32_t version);
149 
150     /**
151      * Set the supported transports for sending and receiving file descriptors.
152      *
153      * Clients will propose a mode when connecting. If the mode is not in the
154      * provided list, the connection will be rejected.
155      */
156     LIBBINDER_EXPORTED void setSupportedFileDescriptorTransportModes(
157             const std::vector<RpcSession::FileDescriptorTransportMode>& modes);
158 
159     /**
160      * The root object can be retrieved by any client, without any
161      * authentication. TODO(b/183988761)
162      *
163      * Holds a strong reference to the root object.
164      */
165     LIBBINDER_EXPORTED void setRootObject(const sp<IBinder>& binder);
166     /**
167      * Holds a weak reference to the root object.
168      */
169     LIBBINDER_EXPORTED void setRootObjectWeak(const wp<IBinder>& binder);
170     /**
171      * Allows a root object to be created for each session.
172      *
173      * Takes one argument: a callable that is invoked once per new session.
174      * The callable takes three arguments:
175      * - a weak pointer to the session. If you want to hold onto this in the root object, then
176      *   you should keep a weak pointer, and promote it when needed. For instance, if you refer
177      *   to this from the root object, then you could get ahold of transport-specific information.
178      * - a type-erased pointer to an OS- and transport-specific address structure, e.g.,
179      *   sockaddr_vm for vsock
180      * - an integer representing the size in bytes of that structure. The callable should
181      *   validate the size, then cast the type-erased pointer to a pointer to the actual type of the
182      *   address, e.g., const void* to const sockaddr_vm*.
183      */
184     LIBBINDER_EXPORTED void setPerSessionRootObject(
185             std::function<sp<IBinder>(wp<RpcSession> session, const void*, size_t)>&& object);
186     LIBBINDER_EXPORTED sp<IBinder> getRootObject();
187 
188     /**
189      * Set optional filter of incoming connections based on the peer's address.
190      *
191      * Takes one argument: a callable that is invoked on each accept()-ed
192      * connection and returns false if the connection should be dropped.
193      * See the description of setPerSessionRootObject() for details about
194      * the callable's arguments.
195      */
196     LIBBINDER_EXPORTED void setConnectionFilter(std::function<bool(const void*, size_t)>&& filter);
197 
198     /**
199      * Set optional modifier of each newly created server socket.
200      *
201      * The only argument is a successfully created file descriptor, not bound to an address yet.
202      */
203     LIBBINDER_EXPORTED void setServerSocketModifier(
204             std::function<void(binder::borrowed_fd)>&& modifier);
205 
206     /**
207      * See RpcTransportCtx::getCertificate
208      */
209     LIBBINDER_EXPORTED std::vector<uint8_t> getCertificate(RpcCertificateFormat);
210 
211     /**
212      * Runs join() in a background thread. Immediately returns.
213      */
214     LIBBINDER_EXPORTED void start();
215 
216     /**
217      * You must have at least one client session before calling this.
218      *
219      * If a client needs to actively terminate join, call shutdown() in a separate thread.
220      *
221      * At any given point, there can only be one thread calling join().
222      *
223      * Warning: if shutdown is called, this will return while the shutdown is
224      * still occurring. To ensure that the service is fully shutdown, you might
225      * want to call shutdown after 'join' returns.
226      */
227     LIBBINDER_EXPORTED void join();
228 
229     /**
230      * Shut down any existing join(). Return true if successfully shut down, false otherwise
231      * (e.g. no join() is running). Will wait for the server to be fully
232      * shutdown.
233      *
234      * Warning: this will hang if it is called from its own thread.
235      */
236     [[nodiscard]] LIBBINDER_EXPORTED bool shutdown();
237 
238     /**
239      * For debugging!
240      */
241     LIBBINDER_EXPORTED std::vector<sp<RpcSession>> listSessions();
242     LIBBINDER_EXPORTED size_t numUninitializedSessions();
243 
244     /**
245      * Whether any requests are currently being processed.
246      */
247     LIBBINDER_EXPORTED bool hasActiveRequests();
248 
249     LIBBINDER_EXPORTED ~RpcServer();
250 
251 private:
252     friend RpcServerTrusty;
253     friend sp<RpcServer>;
254     explicit RpcServer(std::unique_ptr<RpcTransportCtx> ctx);
255 
256     void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
257     void onSessionIncomingThreadEnded() override;
258 
259     status_t setupExternalServer(
260             binder::unique_fd serverFd,
261             std::function<status_t(const RpcServer&, RpcTransportFd*)>&& acceptFn);
262 
263     static constexpr size_t kRpcAddressSize = 128;
264     static void establishConnection(
265             sp<RpcServer>&& server, RpcTransportFd clientFd,
266             std::array<uint8_t, kRpcAddressSize> addr, size_t addrLen,
267             std::function<void(sp<RpcSession>&&, RpcSession::PreJoinSetupResult&&)>&& joinFn);
268     static status_t acceptSocketConnection(const RpcServer& server, RpcTransportFd* out);
269     static status_t recvmsgSocketConnection(const RpcServer& server, RpcTransportFd* out);
270 
271     [[nodiscard]] status_t setupSocketServer(const RpcSocketAddress& address);
272 
273     const std::unique_ptr<RpcTransportCtx> mCtx;
274     size_t mMaxThreads = 1;
275     std::optional<uint32_t> mProtocolVersion;
276     // A mode is supported if the N'th bit is on, where N is the mode enum's value.
277     std::bitset<8> mSupportedFileDescriptorTransportModes = std::bitset<8>().set(
278             static_cast<size_t>(RpcSession::FileDescriptorTransportMode::NONE));
279     RpcTransportFd mServer; // socket we are accepting sessions on
280 
281     RpcMutex mLock; // for below
282     std::unique_ptr<RpcMaybeThread> mJoinThread;
283     bool mJoinThreadRunning = false;
284     std::map<RpcMaybeThread::id, RpcMaybeThread> mConnectingThreads;
285 
286     sp<IBinder> mRootObject;
287     wp<IBinder> mRootObjectWeak;
288     std::function<sp<IBinder>(wp<RpcSession>, const void*, size_t)> mRootObjectFactory;
289     std::function<bool(const void*, size_t)> mConnectionFilter;
290     std::function<void(binder::borrowed_fd)> mServerSocketModifier;
291     std::map<std::vector<uint8_t>, sp<RpcSession>> mSessions;
292     std::unique_ptr<FdTrigger> mShutdownTrigger;
293     RpcConditionVariable mShutdownCv;
294     std::function<status_t(const RpcServer& server, RpcTransportFd* out)> mAcceptFn;
295 };
296 
297 } // namespace android
298