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/unique_fd.h> 19 #include <binder/IBinder.h> 20 #include <binder/RpcSession.h> 21 #include <binder/RpcTransport.h> 22 #include <utils/Errors.h> 23 #include <utils/RefBase.h> 24 25 #include <mutex> 26 #include <thread> 27 28 namespace android { 29 30 class FdTrigger; 31 class RpcSocketAddress; 32 33 /** 34 * This represents a server of an interface, which may be connected to by any 35 * number of clients over sockets. 36 * 37 * Usage: 38 * auto server = RpcServer::make(); 39 * // only supports one now 40 * if (!server->setup*Server(...)) { 41 * :( 42 * } 43 * server->join(); 44 */ 45 class RpcServer final : public virtual RefBase, private RpcSession::EventListener { 46 public: 47 static sp<RpcServer> make( 48 std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory = nullptr); 49 50 /** 51 * This represents a session for responses, e.g.: 52 * 53 * process A serves binder a 54 * process B opens a session to process A 55 * process B makes binder b and sends it to A 56 * A uses this 'back session' to send things back to B 57 */ 58 [[nodiscard]] status_t setupUnixDomainServer(const char* path); 59 60 /** 61 * Creates an RPC server at the current port. 62 */ 63 [[nodiscard]] status_t setupVsockServer(unsigned int port); 64 65 /** 66 * Creates an RPC server at the current port using IPv4. 67 * 68 * TODO(b/182914638): IPv6 support 69 * 70 * Set |port| to 0 to pick an ephemeral port; see discussion of 71 * /proc/sys/net/ipv4/ip_local_port_range in ip(7). In this case, |assignedPort| 72 * will be set to the picked port number, if it is not null. 73 * 74 * Set the IPv4 address for the socket to be listening on. 75 * "127.0.0.1" allows for local connections from the same device. 76 * "0.0.0.0" allows for connections on any IP address that the device may 77 * have 78 */ 79 [[nodiscard]] status_t setupInetServer(const char* address, unsigned int port, 80 unsigned int* assignedPort = nullptr); 81 82 /** 83 * If setup*Server has been successful, return true. Otherwise return false. 84 */ 85 [[nodiscard]] bool hasServer(); 86 87 /** 88 * If hasServer(), return the server FD. Otherwise return invalid FD. 89 */ 90 [[nodiscard]] base::unique_fd releaseServer(); 91 92 /** 93 * Set up server using an external FD previously set up by releaseServer(). 94 * Return false if there's already a server. 95 */ 96 [[nodiscard]] status_t setupExternalServer(base::unique_fd serverFd); 97 98 /** 99 * This must be called before adding a client session. 100 * 101 * If this is not specified, this will be a single-threaded server. 102 * 103 * TODO(b/167966510): these are currently created per client, but these 104 * should be shared. 105 */ 106 void setMaxThreads(size_t threads); 107 size_t getMaxThreads(); 108 109 /** 110 * By default, the latest protocol version which is supported by a client is 111 * used. However, this can be used in order to prevent newer protocol 112 * versions from ever being used. This is expected to be useful for testing. 113 */ 114 void setProtocolVersion(uint32_t version); 115 116 /** 117 * The root object can be retrieved by any client, without any 118 * authentication. TODO(b/183988761) 119 * 120 * Holds a strong reference to the root object. 121 */ 122 void setRootObject(const sp<IBinder>& binder); 123 /** 124 * Holds a weak reference to the root object. 125 */ 126 void setRootObjectWeak(const wp<IBinder>& binder); 127 /** 128 * Allows a root object to be created for each session 129 */ 130 void setPerSessionRootObject(std::function<sp<IBinder>(const sockaddr*, socklen_t)>&& object); 131 sp<IBinder> getRootObject(); 132 133 /** 134 * See RpcTransportCtx::getCertificate 135 */ 136 std::vector<uint8_t> getCertificate(RpcCertificateFormat); 137 138 /** 139 * Runs join() in a background thread. Immediately returns. 140 */ 141 void start(); 142 143 /** 144 * You must have at least one client session before calling this. 145 * 146 * If a client needs to actively terminate join, call shutdown() in a separate thread. 147 * 148 * At any given point, there can only be one thread calling join(). 149 * 150 * Warning: if shutdown is called, this will return while the shutdown is 151 * still occurring. To ensure that the service is fully shutdown, you might 152 * want to call shutdown after 'join' returns. 153 */ 154 void join(); 155 156 /** 157 * Shut down any existing join(). Return true if successfully shut down, false otherwise 158 * (e.g. no join() is running). Will wait for the server to be fully 159 * shutdown. 160 * 161 * Warning: this will hang if it is called from its own thread. 162 */ 163 [[nodiscard]] bool shutdown(); 164 165 /** 166 * For debugging! 167 */ 168 std::vector<sp<RpcSession>> listSessions(); 169 size_t numUninitializedSessions(); 170 171 ~RpcServer(); 172 173 private: 174 friend sp<RpcServer>; 175 explicit RpcServer(std::unique_ptr<RpcTransportCtx> ctx); 176 177 void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override; 178 void onSessionIncomingThreadEnded() override; 179 180 static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd, 181 const sockaddr_storage addr, socklen_t addrLen); 182 [[nodiscard]] status_t setupSocketServer(const RpcSocketAddress& address); 183 184 const std::unique_ptr<RpcTransportCtx> mCtx; 185 size_t mMaxThreads = 1; 186 std::optional<uint32_t> mProtocolVersion; 187 base::unique_fd mServer; // socket we are accepting sessions on 188 189 std::mutex mLock; // for below 190 std::unique_ptr<std::thread> mJoinThread; 191 bool mJoinThreadRunning = false; 192 std::map<std::thread::id, std::thread> mConnectingThreads; 193 sp<IBinder> mRootObject; 194 wp<IBinder> mRootObjectWeak; 195 std::function<sp<IBinder>(const sockaddr*, socklen_t)> mRootObjectFactory; 196 std::map<std::vector<uint8_t>, sp<RpcSession>> mSessions; 197 std::unique_ptr<FdTrigger> mShutdownTrigger; 198 std::condition_variable mShutdownCv; 199 }; 200 201 } // namespace android 202