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