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 <android-base/function_ref.h> 29 #include <android-base/unique_fd.h> 30 #include <utils/Errors.h> 31 32 #include <binder/RpcCertificateFormat.h> 33 #include <binder/RpcThreads.h> 34 35 #include <sys/uio.h> 36 37 namespace android { 38 39 class FdTrigger; 40 struct RpcTransportFd; 41 42 // Represents a socket connection. 43 // No thread-safety is guaranteed for these APIs. 44 class RpcTransport { 45 public: 46 virtual ~RpcTransport() = default; 47 48 /** 49 * Poll the transport to check whether there is any data ready to read. 50 * 51 * Return: 52 * OK - There is data available on this transport 53 * WOULDBLOCK - No data is available 54 * error - any other error 55 */ 56 [[nodiscard]] virtual status_t pollRead(void) = 0; 57 58 /** 59 * Read (or write), but allow to be interrupted by a trigger. 60 * 61 * iovs - array of iovecs to perform the operation on. The elements 62 * of the array may be modified by this method. 63 * 64 * altPoll - function to be called instead of polling, when needing to wait 65 * to read/write data. If this returns an error, that error is returned from 66 * this function. 67 * 68 * ancillaryFds - FDs to be sent via UNIX domain dockets or Trusty IPC. When 69 * reading, if `ancillaryFds` is null, any received FDs will be silently 70 * dropped and closed (by the OS). Appended values will always be unique_fd, 71 * the variant type is used to avoid extra copies elsewhere. 72 * 73 * Return: 74 * OK - succeeded in completely processing 'size' 75 * error - interrupted (failure or trigger) 76 */ 77 [[nodiscard]] virtual status_t interruptableWriteFully( 78 FdTrigger *fdTrigger, iovec *iovs, int niovs, 79 const std::optional<android::base::function_ref<status_t()>> &altPoll, 80 const std::vector<std::variant<base::unique_fd, base::borrowed_fd>> *ancillaryFds) = 0; 81 [[nodiscard]] virtual status_t interruptableReadFully( 82 FdTrigger *fdTrigger, iovec *iovs, int niovs, 83 const std::optional<android::base::function_ref<status_t()>> &altPoll, 84 std::vector<std::variant<base::unique_fd, base::borrowed_fd>> *ancillaryFds) = 0; 85 86 /** 87 * Check whether any threads are blocked while polling the transport 88 * for read operations 89 * Return: 90 * True - Specifies that there is active polling on transport. 91 * False - No active polling on transport 92 */ 93 [[nodiscard]] virtual bool isWaiting() = 0; 94 95 protected: 96 RpcTransport() = default; 97 }; 98 99 // Represents the context that generates the socket connection. 100 // All APIs are thread-safe. See RpcTransportCtxRaw and RpcTransportCtxTls for details. 101 class RpcTransportCtx { 102 public: 103 virtual ~RpcTransportCtx() = default; 104 105 // Create a new RpcTransport object. 106 // 107 // Implementation details: for TLS, this function may incur I/O. |fdTrigger| may be used 108 // to interrupt I/O. This function blocks until handshake is finished. 109 [[nodiscard]] virtual std::unique_ptr<RpcTransport> newTransport( 110 android::RpcTransportFd fd, FdTrigger *fdTrigger) const = 0; 111 112 // Return the preconfigured certificate of this context. 113 // 114 // Implementation details: 115 // - For raw sockets, this always returns empty string. 116 // - For TLS, this returns the certificate. See RpcTransportTls for details. 117 [[nodiscard]] virtual std::vector<uint8_t> getCertificate( 118 RpcCertificateFormat format) const = 0; 119 120 protected: 121 RpcTransportCtx() = default; 122 }; 123 124 // A factory class that generates RpcTransportCtx. 125 // All APIs are thread-safe. 126 class RpcTransportCtxFactory { 127 public: 128 virtual ~RpcTransportCtxFactory() = default; 129 // Creates server context. 130 [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newServerCtx() const = 0; 131 132 // Creates client context. 133 [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newClientCtx() const = 0; 134 135 // Return a short description of this transport (e.g. "raw"). For logging / debugging / testing 136 // only. 137 [[nodiscard]] virtual const char *toCString() const = 0; 138 139 protected: 140 RpcTransportCtxFactory() = default; 141 }; 142 143 struct RpcTransportFd { 144 private: 145 mutable bool isPolling{false}; 146 setPollingStateRpcTransportFd147 void setPollingState(bool state) const { isPolling = state; } 148 149 public: 150 base::unique_fd fd; 151 152 RpcTransportFd() = default; RpcTransportFdRpcTransportFd153 explicit RpcTransportFd(base::unique_fd &&descriptor) 154 : isPolling(false), fd(std::move(descriptor)) {} 155 RpcTransportFdRpcTransportFd156 RpcTransportFd(RpcTransportFd &&transportFd) noexcept 157 : isPolling(transportFd.isPolling), fd(std::move(transportFd.fd)) {} 158 159 RpcTransportFd &operator=(RpcTransportFd &&transportFd) noexcept { 160 fd = std::move(transportFd.fd); 161 isPolling = transportFd.isPolling; 162 return *this; 163 } 164 165 RpcTransportFd &operator=(base::unique_fd &&descriptor) noexcept { 166 fd = std::move(descriptor); 167 isPolling = false; 168 return *this; 169 } 170 isInPollingStateRpcTransportFd171 bool isInPollingState() const { return isPolling; } 172 friend class FdTrigger; 173 }; 174 175 } // namespace android 176