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