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