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