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 <android-base/threads.h> 19 #include <android-base/unique_fd.h> 20 #include <binder/IBinder.h> 21 #include <binder/RpcThreads.h> 22 #include <binder/RpcTransport.h> 23 #include <utils/Errors.h> 24 #include <utils/RefBase.h> 25 26 #include <map> 27 #include <optional> 28 #include <vector> 29 30 namespace android { 31 32 class Parcel; 33 class RpcServer; 34 class RpcServerTrusty; 35 class RpcSocketAddress; 36 class RpcState; 37 class RpcTransport; 38 class FdTrigger; 39 40 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 2; 41 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL = 0xF0000000; 42 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = 1; 43 44 // Starting with this version: 45 // 46 // * RpcWireReply is larger (4 bytes -> 20). 47 // * RpcWireTransaction and RpcWireReplyV1 include the parcel data size. 48 constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE = 1; 49 50 /** 51 * This represents a session (group of connections) between a client 52 * and a server. Multiple connections are needed for multiple parallel "binder" 53 * calls which may also have nested calls. 54 * 55 * Once a binder exists in the session, if all references to all binders are dropped, 56 * the session shuts down. 57 */ 58 class RpcSession final : public virtual RefBase { 59 public: 60 // Create an RpcSession with default configuration (raw sockets). 61 static sp<RpcSession> make(); 62 63 // Create an RpcSession with the given configuration. |serverRpcCertificateFormat| and 64 // |serverCertificate| must have values or be nullopt simultaneously. If they have values, set 65 // server certificate. 66 static sp<RpcSession> make(std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory); 67 68 /** 69 * Set the maximum number of incoming threads allowed to be made (for things like callbacks). 70 * By default, this is 0. This must be called before setting up this connection as a client. 71 * Server sessions will inherits this value from RpcServer. Each thread will serve a 72 * connection to the remote RpcSession. 73 * 74 * If this is called, 'shutdown' on this session must also be called. 75 * Otherwise, a threadpool will leak. 76 * 77 * TODO(b/189955605): start these lazily - currently all are started 78 */ 79 void setMaxIncomingThreads(size_t threads); 80 size_t getMaxIncomingThreads(); 81 82 /** 83 * Set the maximum number of outgoing connections allowed to be made. 84 * By default, this is |kDefaultMaxOutgoingConnections|. This must be called before setting up 85 * this connection as a client. 86 * 87 * For an RpcSession client, if you are connecting to a server which starts N threads, 88 * then this must be set to >= N. If you set the maximum number of outgoing connections 89 * to 1, but the server requests 10, then it would be considered an error. If you set a 90 * maximum number of connections to 10, and the server requests 1, then only 1 will be 91 * created. This API is used to limit the amount of resources a server can request you 92 * create. 93 */ 94 void setMaxOutgoingConnections(size_t connections); 95 size_t getMaxOutgoingThreads(); 96 97 /** 98 * By default, the minimum of the supported versions of the client and the 99 * server will be used. Usually, this API should only be used for debugging. 100 */ 101 [[nodiscard]] bool setProtocolVersion(uint32_t version); 102 std::optional<uint32_t> getProtocolVersion(); 103 104 enum class FileDescriptorTransportMode : uint8_t { 105 NONE = 0, 106 // Send file descriptors via unix domain socket ancillary data. 107 UNIX = 1, 108 // Send file descriptors as Trusty IPC handles. 109 TRUSTY = 2, 110 }; 111 112 /** 113 * Set the transport for sending and receiving file descriptors. 114 */ 115 void setFileDescriptorTransportMode(FileDescriptorTransportMode mode); 116 FileDescriptorTransportMode getFileDescriptorTransportMode(); 117 118 /** 119 * This should be called once per thread, matching 'join' in the remote 120 * process. 121 */ 122 [[nodiscard]] status_t setupUnixDomainClient(const char* path); 123 124 /** 125 * Connects to an RPC server over a nameless Unix domain socket pair. 126 */ 127 [[nodiscard]] status_t setupUnixDomainSocketBootstrapClient(base::unique_fd bootstrap); 128 129 /** 130 * Connects to an RPC server at the CVD & port. 131 */ 132 [[nodiscard]] status_t setupVsockClient(unsigned int cvd, unsigned int port); 133 134 /** 135 * Connects to an RPC server at the given address and port. 136 */ 137 [[nodiscard]] status_t setupInetClient(const char* addr, unsigned int port); 138 139 /** 140 * Starts talking to an RPC server which has already been connected to. This 141 * is expected to be used when another process has permission to connect to 142 * a binder RPC service, but this process only has permission to talk to 143 * that service. 144 * 145 * For convenience, if 'fd' is -1, 'request' will be called. 146 * 147 * For future compatibility, 'request' should not reference any stack data. 148 */ 149 [[nodiscard]] status_t setupPreconnectedClient(base::unique_fd fd, 150 std::function<base::unique_fd()>&& request); 151 152 /** 153 * For debugging! 154 * 155 * Sets up an empty connection. All queries to this connection which require a 156 * response will never be satisfied. All data sent here will be 157 * unceremoniously cast down the bottomless pit, /dev/null. 158 */ 159 [[nodiscard]] status_t addNullDebuggingClient(); 160 161 /** 162 * Query the other side of the session for the root object hosted by that 163 * process's RpcServer (if one exists) 164 */ 165 sp<IBinder> getRootObject(); 166 167 /** 168 * Query the other side of the session for the maximum number of threads 169 * it supports (maximum number of concurrent non-nested synchronous transactions) 170 */ 171 [[nodiscard]] status_t getRemoteMaxThreads(size_t* maxThreads); 172 173 /** 174 * See RpcTransportCtx::getCertificate 175 */ 176 std::vector<uint8_t> getCertificate(RpcCertificateFormat); 177 178 /** 179 * Shuts down the service. 180 * 181 * For client sessions, wait can be true or false. For server sessions, 182 * waiting is not currently supported (will abort). 183 * 184 * Warning: this is currently not active/nice (the server isn't told we're 185 * shutting down). Being nicer to the server could potentially make it 186 * reclaim resources faster. 187 * 188 * If this is called w/ 'wait' true, then this will wait for shutdown to 189 * complete before returning. This will hang if it is called from the 190 * session threadpool (when processing received calls). 191 */ 192 [[nodiscard]] bool shutdownAndWait(bool wait); 193 194 [[nodiscard]] status_t transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data, 195 Parcel* reply, uint32_t flags); 196 197 /** 198 * Generally, you should not call this, unless you are testing error 199 * conditions, as this is called automatically by BpBinders when they are 200 * deleted (this is also why a raw pointer is used here) 201 */ 202 [[nodiscard]] status_t sendDecStrong(const BpBinder* binder); 203 204 /** 205 * Whether any requests are currently being processed. 206 */ 207 bool hasActiveRequests(); 208 209 ~RpcSession(); 210 211 /** 212 * Server if this session is created as part of a server (symmetrical to 213 * client servers). Otherwise, nullptr. 214 */ 215 sp<RpcServer> server(); 216 217 // internal only state()218 const std::unique_ptr<RpcState>& state() { return mRpcBinderState; } 219 220 private: 221 friend sp<RpcSession>; 222 friend RpcServer; 223 friend RpcServerTrusty; 224 friend RpcState; 225 explicit RpcSession(std::unique_ptr<RpcTransportCtx> ctx); 226 227 static constexpr size_t kDefaultMaxOutgoingConnections = 10; 228 229 // internal version of setProtocolVersion that 230 // optionally skips the mStartedSetup check 231 [[nodiscard]] bool setProtocolVersionInternal(uint32_t version, bool checkStarted); 232 233 // for 'target', see RpcState::sendDecStrongToTarget 234 [[nodiscard]] status_t sendDecStrongToTarget(uint64_t address, size_t target); 235 236 class EventListener : public virtual RefBase { 237 public: 238 virtual void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0; 239 virtual void onSessionIncomingThreadEnded() = 0; 240 }; 241 242 class WaitForShutdownListener : public EventListener { 243 public: 244 void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override; 245 void onSessionIncomingThreadEnded() override; 246 void waitForShutdown(RpcMutexUniqueLock& lock, const sp<RpcSession>& session); 247 248 private: 249 RpcConditionVariable mCv; 250 std::atomic<size_t> mShutdownCount = 0; 251 }; 252 friend WaitForShutdownListener; 253 254 struct RpcConnection : public RefBase { 255 std::unique_ptr<RpcTransport> rpcTransport; 256 257 // whether this or another thread is currently using this fd to make 258 // or receive transactions. 259 std::optional<uint64_t> exclusiveTid; 260 261 bool allowNested = false; 262 }; 263 264 [[nodiscard]] status_t readId(); 265 266 // A thread joining a server must always call these functions in order, and 267 // cleanup is only programmed once into join. These are in separate 268 // functions in order to allow for different locks to be taken during 269 // different parts of setup. 270 // 271 // transfer ownership of thread (usually done while a lock is taken on the 272 // structure which originally owns the thread) 273 void preJoinThreadOwnership(RpcMaybeThread thread); 274 // pass FD to thread and read initial connection information 275 struct PreJoinSetupResult { 276 // Server connection object associated with this 277 sp<RpcConnection> connection; 278 // Status of setup 279 status_t status; 280 }; 281 PreJoinSetupResult preJoinSetup(std::unique_ptr<RpcTransport> rpcTransport); 282 // join on thread passed to preJoinThreadOwnership 283 static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result); 284 285 [[nodiscard]] status_t setupClient( 286 const std::function<status_t(const std::vector<uint8_t>& sessionId, bool incoming)>& 287 connectAndInit); 288 [[nodiscard]] status_t setupSocketClient(const RpcSocketAddress& address); 289 [[nodiscard]] status_t setupOneSocketConnection(const RpcSocketAddress& address, 290 const std::vector<uint8_t>& sessionId, 291 bool incoming); 292 [[nodiscard]] status_t initAndAddConnection(RpcTransportFd fd, 293 const std::vector<uint8_t>& sessionId, 294 bool incoming); 295 [[nodiscard]] status_t addIncomingConnection(std::unique_ptr<RpcTransport> rpcTransport); 296 [[nodiscard]] status_t addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTransport, 297 bool init); 298 [[nodiscard]] bool setForServer(const wp<RpcServer>& server, 299 const wp<RpcSession::EventListener>& eventListener, 300 const std::vector<uint8_t>& sessionId, 301 const sp<IBinder>& sessionSpecificRoot); 302 sp<RpcConnection> assignIncomingConnectionToThisThread( 303 std::unique_ptr<RpcTransport> rpcTransport); 304 [[nodiscard]] bool removeIncomingConnection(const sp<RpcConnection>& connection); 305 void clearConnectionTid(const sp<RpcConnection>& connection); 306 307 [[nodiscard]] status_t initShutdownTrigger(); 308 309 /** 310 * Checks whether any connection is active (Not polling on fd) 311 */ 312 bool hasActiveConnection(const std::vector<sp<RpcConnection>>& connections); 313 314 enum class ConnectionUse { 315 CLIENT, 316 CLIENT_ASYNC, 317 CLIENT_REFCOUNT, 318 }; 319 320 // Object representing exclusive access to a connection. 321 class ExclusiveConnection { 322 public: 323 [[nodiscard]] static status_t find(const sp<RpcSession>& session, ConnectionUse use, 324 ExclusiveConnection* connection); 325 326 ~ExclusiveConnection(); get()327 const sp<RpcConnection>& get() { return mConnection; } 328 329 private: 330 static void findConnection(uint64_t tid, sp<RpcConnection>* exclusive, 331 sp<RpcConnection>* available, 332 std::vector<sp<RpcConnection>>& sockets, 333 size_t socketsIndexHint); 334 335 sp<RpcSession> mSession; // avoid deallocation 336 sp<RpcConnection> mConnection; 337 338 // whether this is being used for a nested transaction (being on the same 339 // thread guarantees we won't write in the middle of a message, the way 340 // the wire protocol is constructed guarantees this is safe). 341 bool mReentrant = false; 342 }; 343 344 const std::unique_ptr<RpcTransportCtx> mCtx; 345 346 // On the other side of a session, for each of mOutgoing here, there should 347 // be one of mIncoming on the other side (and vice versa). 348 // 349 // For the simplest session, a single server with one client, you would 350 // have: 351 // - the server has a single 'mIncoming' and a thread listening on this 352 // - the client has a single 'mOutgoing' and makes calls to this 353 // - here, when the client makes a call, the server can call back into it 354 // (nested calls), but outside of this, the client will only ever read 355 // calls from the server when it makes a call itself. 356 // 357 // For a more complicated case, the client might itself open up a thread to 358 // serve calls to the server at all times (e.g. if it hosts a callback) 359 360 wp<RpcServer> mForServer; // maybe null, for client sessions 361 sp<WaitForShutdownListener> mShutdownListener; // used for client sessions 362 wp<EventListener> mEventListener; // mForServer if server, mShutdownListener if client 363 364 // session-specific root object (if a different root is used for each 365 // session) 366 sp<IBinder> mSessionSpecificRootObject; 367 368 std::vector<uint8_t> mId; 369 370 std::unique_ptr<FdTrigger> mShutdownTrigger; 371 372 std::unique_ptr<RpcState> mRpcBinderState; 373 374 RpcMutex mMutex; // for all below 375 376 bool mStartedSetup = false; 377 size_t mMaxIncomingThreads = 0; 378 size_t mMaxOutgoingConnections = kDefaultMaxOutgoingConnections; 379 std::optional<uint32_t> mProtocolVersion; 380 FileDescriptorTransportMode mFileDescriptorTransportMode = FileDescriptorTransportMode::NONE; 381 382 RpcConditionVariable mAvailableConnectionCv; // for mWaitingThreads 383 384 std::unique_ptr<RpcTransport> mBootstrapTransport; 385 386 struct ThreadState { 387 size_t mWaitingThreads = 0; 388 // hint index into clients, ++ when sending an async transaction 389 size_t mOutgoingOffset = 0; 390 std::vector<sp<RpcConnection>> mOutgoing; 391 // max size of mIncoming. Once any thread starts down, no more can be started. 392 size_t mMaxIncoming = 0; 393 std::vector<sp<RpcConnection>> mIncoming; 394 std::map<RpcMaybeThread::id, RpcMaybeThread> mThreads; 395 } mConnections; 396 }; 397 398 } // namespace android 399