1 /* 2 * Copyright (C) 2021 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 17 // Wraps the transport layer of RPC. Implementation may use plain sockets or TLS. 18 19 #pragma once 20 21 #include <functional> 22 #include <memory> 23 #include <optional> 24 #include <string> 25 #include <variant> 26 #include <vector> 27 28 #include <utils/Errors.h> 29 30 #include <binder/Common.h> 31 #include <binder/Functional.h> 32 #include <binder/RpcCertificateFormat.h> 33 #include <binder/RpcThreads.h> 34 #include <binder/unique_fd.h> 35 36 #include <sys/uio.h> 37 38 namespace android { 39 40 class FdTrigger; 41 struct RpcTransportFd; 42 43 // for 'friend' 44 class RpcTransportRaw; 45 class RpcTransportTls; 46 class RpcTransportTipcAndroid; 47 class RpcTransportTipcTrusty; 48 class RpcTransportCtxRaw; 49 class RpcTransportCtxTls; 50 class RpcTransportCtxTipcAndroid; 51 class RpcTransportCtxTipcTrusty; 52 53 // Represents a socket connection. 54 // No thread-safety is guaranteed for these APIs. 55 class LIBBINDER_EXPORTED RpcTransport { 56 public: 57 virtual ~RpcTransport() = default; 58 59 /** 60 * Poll the transport to check whether there is any data ready to read. 61 * 62 * Return: 63 * OK - There is data available on this transport 64 * WOULDBLOCK - No data is available 65 * error - any other error 66 */ 67 [[nodiscard]] virtual status_t pollRead(void) = 0; 68 69 /** 70 * Read (or write), but allow to be interrupted by a trigger. 71 * 72 * iovs - array of iovecs to perform the operation on. The elements 73 * of the array may be modified by this method. 74 * 75 * altPoll - function to be called instead of polling, when needing to wait 76 * to read/write data. If this returns an error, that error is returned from 77 * this function. 78 * 79 * ancillaryFds - FDs to be sent via UNIX domain dockets or Trusty IPC. When 80 * reading, if `ancillaryFds` is null, any received FDs will be silently 81 * dropped and closed (by the OS). Appended values will always be unique_fd, 82 * the variant type is used to avoid extra copies elsewhere. 83 * 84 * Return: 85 * OK - succeeded in completely processing 'size' 86 * error - interrupted (failure or trigger) 87 */ 88 [[nodiscard]] virtual status_t interruptableWriteFully( 89 FdTrigger* fdTrigger, iovec* iovs, int niovs, 90 const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll, 91 const std::vector<std::variant<binder::unique_fd, binder::borrowed_fd>>* 92 ancillaryFds) = 0; 93 [[nodiscard]] virtual status_t interruptableReadFully( 94 FdTrigger* fdTrigger, iovec* iovs, int niovs, 95 const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll, 96 std::vector<std::variant<binder::unique_fd, binder::borrowed_fd>>* ancillaryFds) = 0; 97 98 /** 99 * Check whether any threads are blocked while polling the transport 100 * for read operations 101 * Return: 102 * True - Specifies that there is active polling on transport. 103 * False - No active polling on transport 104 */ 105 [[nodiscard]] virtual bool isWaiting() = 0; 106 107 private: 108 // limit the classes which can implement RpcTransport. Being able to change this 109 // interface is important to allow development of RPC binder. In the past, we 110 // changed this interface to use iovec for efficiency, and we added FDs to the 111 // interface. If another transport is needed, it should be added directly here. 112 // non-socket FDs likely also need changes in RpcSession in order to get 113 // connected, and similarly to how addrinfo was type-erased from RPC binder 114 // interfaces when RpcTransportTipc* was added, other changes may be needed 115 // to add more transports. 116 117 friend class ::android::RpcTransportRaw; 118 friend class ::android::RpcTransportTls; 119 friend class ::android::RpcTransportTipcAndroid; 120 friend class ::android::RpcTransportTipcTrusty; 121 122 RpcTransport() = default; 123 }; 124 125 // Represents the context that generates the socket connection. 126 // All APIs are thread-safe. See RpcTransportCtxRaw and RpcTransportCtxTls for details. 127 class LIBBINDER_EXPORTED RpcTransportCtx { 128 public: 129 virtual ~RpcTransportCtx() = default; 130 131 // Create a new RpcTransport object. 132 // 133 // Implementation details: for TLS, this function may incur I/O. |fdTrigger| may be used 134 // to interrupt I/O. This function blocks until handshake is finished. 135 [[nodiscard]] virtual std::unique_ptr<RpcTransport> newTransport( 136 android::RpcTransportFd fd, FdTrigger *fdTrigger) const = 0; 137 138 // Return the preconfigured certificate of this context. 139 // 140 // Implementation details: 141 // - For raw sockets, this always returns empty string. 142 // - For TLS, this returns the certificate. See RpcTransportTls for details. 143 [[nodiscard]] virtual std::vector<uint8_t> getCertificate( 144 RpcCertificateFormat format) const = 0; 145 146 private: 147 // see comment on RpcTransport 148 friend class ::android::RpcTransportCtxRaw; 149 friend class ::android::RpcTransportCtxTls; 150 friend class ::android::RpcTransportCtxTipcAndroid; 151 friend class ::android::RpcTransportCtxTipcTrusty; 152 153 RpcTransportCtx() = default; 154 }; 155 156 // A factory class that generates RpcTransportCtx. 157 // All APIs are thread-safe. 158 class LIBBINDER_EXPORTED RpcTransportCtxFactory { 159 public: 160 virtual ~RpcTransportCtxFactory() = default; 161 // Creates server context. 162 [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newServerCtx() const = 0; 163 164 // Creates client context. 165 [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newClientCtx() const = 0; 166 167 // Return a short description of this transport (e.g. "raw"). For logging / debugging / testing 168 // only. 169 [[nodiscard]] virtual const char *toCString() const = 0; 170 171 protected: 172 RpcTransportCtxFactory() = default; 173 }; 174 175 struct LIBBINDER_EXPORTED RpcTransportFd final { 176 private: 177 mutable bool isPolling{false}; 178 setPollingStatefinal179 void setPollingState(bool state) const { isPolling = state; } 180 181 public: 182 binder::unique_fd fd; 183 184 RpcTransportFd() = default; RpcTransportFdfinal185 explicit RpcTransportFd(binder::unique_fd&& descriptor) 186 : isPolling(false), fd(std::move(descriptor)) {} 187 RpcTransportFdfinal188 RpcTransportFd(RpcTransportFd &&transportFd) noexcept 189 : isPolling(transportFd.isPolling), fd(std::move(transportFd.fd)) {} 190 191 RpcTransportFd &operator=(RpcTransportFd &&transportFd) noexcept { 192 fd = std::move(transportFd.fd); 193 isPolling = transportFd.isPolling; 194 return *this; 195 } 196 197 RpcTransportFd& operator=(binder::unique_fd&& descriptor) noexcept { 198 fd = std::move(descriptor); 199 isPolling = false; 200 return *this; 201 } 202 isInPollingStatefinal203 bool isInPollingState() const { return isPolling; } 204 friend class FdTrigger; 205 }; 206 207 } // namespace android 208