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