• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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