xref: /aosp_15_r20/frameworks/native/libs/binder/RpcTransportRaw.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "RpcRawTransport"
18*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <poll.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <stddef.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <sys/socket.h>
23*38e8c45fSAndroid Build Coastguard Worker 
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransportRaw.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #include "FdTrigger.h"
27*38e8c45fSAndroid Build Coastguard Worker #include "OS.h"
28*38e8c45fSAndroid Build Coastguard Worker #include "RpcState.h"
29*38e8c45fSAndroid Build Coastguard Worker #include "RpcTransportUtils.h"
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker namespace android {
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker using namespace android::binder::impl;
34*38e8c45fSAndroid Build Coastguard Worker using android::binder::borrowed_fd;
35*38e8c45fSAndroid Build Coastguard Worker using android::binder::unique_fd;
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker // RpcTransport with TLS disabled.
38*38e8c45fSAndroid Build Coastguard Worker class RpcTransportRaw : public RpcTransport {
39*38e8c45fSAndroid Build Coastguard Worker public:
RpcTransportRaw(android::RpcTransportFd socket)40*38e8c45fSAndroid Build Coastguard Worker     explicit RpcTransportRaw(android::RpcTransportFd socket) : mSocket(std::move(socket)) {}
pollRead(void)41*38e8c45fSAndroid Build Coastguard Worker     status_t pollRead(void) override {
42*38e8c45fSAndroid Build Coastguard Worker         uint8_t buf;
43*38e8c45fSAndroid Build Coastguard Worker         ssize_t ret = TEMP_FAILURE_RETRY(
44*38e8c45fSAndroid Build Coastguard Worker                 ::recv(mSocket.fd.get(), &buf, sizeof(buf), MSG_PEEK | MSG_DONTWAIT));
45*38e8c45fSAndroid Build Coastguard Worker         if (ret < 0) {
46*38e8c45fSAndroid Build Coastguard Worker             int savedErrno = errno;
47*38e8c45fSAndroid Build Coastguard Worker             if (savedErrno == EAGAIN || savedErrno == EWOULDBLOCK) {
48*38e8c45fSAndroid Build Coastguard Worker                 return WOULD_BLOCK;
49*38e8c45fSAndroid Build Coastguard Worker             }
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker             LOG_RPC_DETAIL("RpcTransport poll(): %s", strerror(savedErrno));
52*38e8c45fSAndroid Build Coastguard Worker             return -savedErrno;
53*38e8c45fSAndroid Build Coastguard Worker         } else if (ret == 0) {
54*38e8c45fSAndroid Build Coastguard Worker             return DEAD_OBJECT;
55*38e8c45fSAndroid Build Coastguard Worker         }
56*38e8c45fSAndroid Build Coastguard Worker 
57*38e8c45fSAndroid Build Coastguard Worker         return OK;
58*38e8c45fSAndroid Build Coastguard Worker     }
59*38e8c45fSAndroid Build Coastguard Worker 
interruptableWriteFully(FdTrigger * fdTrigger,iovec * iovs,int niovs,const std::optional<SmallFunction<status_t ()>> & altPoll,const std::vector<std::variant<unique_fd,borrowed_fd>> * ancillaryFds)60*38e8c45fSAndroid Build Coastguard Worker     status_t interruptableWriteFully(
61*38e8c45fSAndroid Build Coastguard Worker             FdTrigger* fdTrigger, iovec* iovs, int niovs,
62*38e8c45fSAndroid Build Coastguard Worker             const std::optional<SmallFunction<status_t()>>& altPoll,
63*38e8c45fSAndroid Build Coastguard Worker             const std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override {
64*38e8c45fSAndroid Build Coastguard Worker         bool sentFds = false;
65*38e8c45fSAndroid Build Coastguard Worker         auto send = [&](iovec* iovs, int niovs) -> ssize_t {
66*38e8c45fSAndroid Build Coastguard Worker             ssize_t ret = binder::os::sendMessageOnSocket(mSocket, iovs, niovs,
67*38e8c45fSAndroid Build Coastguard Worker                                                           sentFds ? nullptr : ancillaryFds);
68*38e8c45fSAndroid Build Coastguard Worker             sentFds |= ret > 0;
69*38e8c45fSAndroid Build Coastguard Worker             return ret;
70*38e8c45fSAndroid Build Coastguard Worker         };
71*38e8c45fSAndroid Build Coastguard Worker         return interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, send, "sendmsg", POLLOUT,
72*38e8c45fSAndroid Build Coastguard Worker                                         altPoll);
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker 
interruptableReadFully(FdTrigger * fdTrigger,iovec * iovs,int niovs,const std::optional<SmallFunction<status_t ()>> & altPoll,std::vector<std::variant<unique_fd,borrowed_fd>> * ancillaryFds)75*38e8c45fSAndroid Build Coastguard Worker     status_t interruptableReadFully(
76*38e8c45fSAndroid Build Coastguard Worker             FdTrigger* fdTrigger, iovec* iovs, int niovs,
77*38e8c45fSAndroid Build Coastguard Worker             const std::optional<SmallFunction<status_t()>>& altPoll,
78*38e8c45fSAndroid Build Coastguard Worker             std::vector<std::variant<unique_fd, borrowed_fd>>* ancillaryFds) override {
79*38e8c45fSAndroid Build Coastguard Worker         auto recv = [&](iovec* iovs, int niovs) -> ssize_t {
80*38e8c45fSAndroid Build Coastguard Worker             return binder::os::receiveMessageFromSocket(mSocket, iovs, niovs, ancillaryFds);
81*38e8c45fSAndroid Build Coastguard Worker         };
82*38e8c45fSAndroid Build Coastguard Worker         return interruptableReadOrWrite(mSocket, fdTrigger, iovs, niovs, recv, "recvmsg", POLLIN,
83*38e8c45fSAndroid Build Coastguard Worker                                         altPoll);
84*38e8c45fSAndroid Build Coastguard Worker     }
85*38e8c45fSAndroid Build Coastguard Worker 
isWaiting()86*38e8c45fSAndroid Build Coastguard Worker     bool isWaiting() override { return mSocket.isInPollingState(); }
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker private:
89*38e8c45fSAndroid Build Coastguard Worker     android::RpcTransportFd mSocket;
90*38e8c45fSAndroid Build Coastguard Worker };
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker // RpcTransportCtx with TLS disabled.
93*38e8c45fSAndroid Build Coastguard Worker class RpcTransportCtxRaw : public RpcTransportCtx {
94*38e8c45fSAndroid Build Coastguard Worker public:
newTransport(android::RpcTransportFd socket,FdTrigger *) const95*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<RpcTransport> newTransport(android::RpcTransportFd socket,
96*38e8c45fSAndroid Build Coastguard Worker                                                FdTrigger*) const override {
97*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<RpcTransportRaw>(std::move(socket));
98*38e8c45fSAndroid Build Coastguard Worker     }
getCertificate(RpcCertificateFormat) const99*38e8c45fSAndroid Build Coastguard Worker     std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override { return {}; }
100*38e8c45fSAndroid Build Coastguard Worker };
101*38e8c45fSAndroid Build Coastguard Worker 
newServerCtx() const102*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newServerCtx() const {
103*38e8c45fSAndroid Build Coastguard Worker     return std::make_unique<RpcTransportCtxRaw>();
104*38e8c45fSAndroid Build Coastguard Worker }
105*38e8c45fSAndroid Build Coastguard Worker 
newClientCtx() const106*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newClientCtx() const {
107*38e8c45fSAndroid Build Coastguard Worker     return std::make_unique<RpcTransportCtxRaw>();
108*38e8c45fSAndroid Build Coastguard Worker }
109*38e8c45fSAndroid Build Coastguard Worker 
toCString() const110*38e8c45fSAndroid Build Coastguard Worker const char *RpcTransportCtxFactoryRaw::toCString() const {
111*38e8c45fSAndroid Build Coastguard Worker     return "raw";
112*38e8c45fSAndroid Build Coastguard Worker }
113*38e8c45fSAndroid Build Coastguard Worker 
make()114*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryRaw::make() {
115*38e8c45fSAndroid Build Coastguard Worker     return std::unique_ptr<RpcTransportCtxFactoryRaw>(new RpcTransportCtxFactoryRaw());
116*38e8c45fSAndroid Build Coastguard Worker }
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker } // namespace android
119