blob: 2182e1868e1a147a8521259c5c4b2262f34dfcce [file] [log] [blame]
Yifan Hongf6b4d5c2021-06-23 19:12:32 -07001/*
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#define LOG_TAG "RpcRawTransport"
18#include <log/log.h>
19
Yifan Hong8c950422021-08-05 17:13:55 -070020#include <poll.h>
21
Yifan Hongf6b4d5c2021-06-23 19:12:32 -070022#include <binder/RpcTransportRaw.h>
23
Yifan Hong8c950422021-08-05 17:13:55 -070024#include "FdTrigger.h"
Yifan Hongf6b4d5c2021-06-23 19:12:32 -070025#include "RpcState.h"
26
27using android::base::ErrnoError;
28using android::base::Result;
29
30namespace android {
31
32namespace {
33
34// RpcTransport with TLS disabled.
35class RpcTransportRaw : public RpcTransport {
36public:
37 explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {}
Yifan Hong218c4072021-08-04 14:59:10 -070038 Result<size_t> peek(void *buf, size_t size) override {
Yifan Hongb675ffe2021-08-05 16:37:17 -070039 ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK));
Yifan Hongf6b4d5c2021-06-23 19:12:32 -070040 if (ret < 0) {
41 return ErrnoError() << "recv(MSG_PEEK)";
42 }
43 return ret;
44 }
Yifan Hong8c950422021-08-05 17:13:55 -070045
Andrei Homescua39e4ed2021-12-10 08:41:54 +000046 template <typename SendOrReceive>
47 status_t interruptableReadOrWrite(FdTrigger* fdTrigger, iovec* iovs, size_t niovs,
Steven Moreland301c3f02021-09-14 17:49:04 -070048 SendOrReceive sendOrReceiveFun, const char* funName,
Steven Moreland43921d52021-09-27 17:15:56 -070049 int16_t event, const std::function<status_t()>& altPoll) {
Yifan Hong8c950422021-08-05 17:13:55 -070050 MAYBE_WAIT_IN_FLAKE_MODE;
51
Steven Moreland301c3f02021-09-14 17:49:04 -070052 // Since we didn't poll, we need to manually check to see if it was triggered. Otherwise, we
53 // may never know we should be shutting down.
54 if (fdTrigger->isTriggered()) {
55 return DEAD_OBJECT;
56 }
57
Andrei Homescua39e4ed2021-12-10 08:41:54 +000058 // If iovs has one or more empty vectors at the end and
59 // we somehow advance past all the preceding vectors and
60 // pass some or all of the empty ones to sendmsg/recvmsg,
61 // the call will return processSize == 0. In that case
62 // we should be returning OK but instead return DEAD_OBJECT.
63 // To avoid this problem, we make sure here that the last
64 // vector at iovs[niovs - 1] has a non-zero length.
65 while (niovs > 0 && iovs[niovs - 1].iov_len == 0) {
66 niovs--;
67 }
68 if (niovs == 0) {
69 // The vectors are all empty, so we have nothing to send.
70 return OK;
71 }
72
Steven Moreland43921d52021-09-27 17:15:56 -070073 bool havePolled = false;
74 while (true) {
Andrei Homescua39e4ed2021-12-10 08:41:54 +000075 msghdr msg{
76 .msg_iov = iovs,
77 .msg_iovlen = niovs,
78 };
79 ssize_t processSize =
80 TEMP_FAILURE_RETRY(sendOrReceiveFun(mSocket.get(), &msg, MSG_NOSIGNAL));
Steven Moreland301c3f02021-09-14 17:49:04 -070081
82 if (processSize < 0) {
Steven Moreland5252e752021-09-14 14:06:03 -070083 int savedErrno = errno;
Steven Moreland301c3f02021-09-14 17:49:04 -070084
85 // Still return the error on later passes, since it would expose
86 // a problem with polling
Andrei Homescua39e4ed2021-12-10 08:41:54 +000087 if (havePolled || (savedErrno != EAGAIN && savedErrno != EWOULDBLOCK)) {
Steven Moreland301c3f02021-09-14 17:49:04 -070088 LOG_RPC_DETAIL("RpcTransport %s(): %s", funName, strerror(savedErrno));
89 return -savedErrno;
90 }
91 } else if (processSize == 0) {
92 return DEAD_OBJECT;
93 } else {
Andrei Homescua39e4ed2021-12-10 08:41:54 +000094 while (processSize > 0 && niovs > 0) {
95 auto& iov = iovs[0];
96 if (static_cast<size_t>(processSize) < iov.iov_len) {
97 // Advance the base of the current iovec
98 iov.iov_base = reinterpret_cast<char*>(iov.iov_base) + processSize;
99 iov.iov_len -= processSize;
100 break;
101 }
102
103 // The current iovec was fully written
104 processSize -= iov.iov_len;
105 iovs++;
106 niovs--;
107 }
108 if (niovs == 0) {
109 LOG_ALWAYS_FATAL_IF(processSize > 0,
110 "Reached the end of iovecs "
111 "with %zd bytes remaining",
112 processSize);
Steven Moreland301c3f02021-09-14 17:49:04 -0700113 return OK;
114 }
Yifan Hong8c950422021-08-05 17:13:55 -0700115 }
116
Steven Moreland43921d52021-09-27 17:15:56 -0700117 if (altPoll) {
118 if (status_t status = altPoll(); status != OK) return status;
119 if (fdTrigger->isTriggered()) {
120 return DEAD_OBJECT;
121 }
122 } else {
123 if (status_t status = fdTrigger->triggerablePoll(mSocket.get(), event);
124 status != OK)
125 return status;
126 if (!havePolled) havePolled = true;
127 }
128 }
Yifan Hong8c950422021-08-05 17:13:55 -0700129 }
130
Andrei Homescua39e4ed2021-12-10 08:41:54 +0000131 status_t interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, size_t niovs,
Steven Moreland43921d52021-09-27 17:15:56 -0700132 const std::function<status_t()>& altPoll) override {
Andrei Homescua39e4ed2021-12-10 08:41:54 +0000133 return interruptableReadOrWrite(fdTrigger, iovs, niovs, sendmsg, "sendmsg", POLLOUT,
134 altPoll);
Steven Moreland301c3f02021-09-14 17:49:04 -0700135 }
136
Andrei Homescua39e4ed2021-12-10 08:41:54 +0000137 status_t interruptableReadFully(FdTrigger* fdTrigger, iovec* iovs, size_t niovs,
Steven Moreland43921d52021-09-27 17:15:56 -0700138 const std::function<status_t()>& altPoll) override {
Andrei Homescua39e4ed2021-12-10 08:41:54 +0000139 return interruptableReadOrWrite(fdTrigger, iovs, niovs, recvmsg, "recvmsg", POLLIN,
140 altPoll);
Yifan Hong8c950422021-08-05 17:13:55 -0700141 }
Yifan Hongf6b4d5c2021-06-23 19:12:32 -0700142
143private:
Steven Moreland301c3f02021-09-14 17:49:04 -0700144 base::unique_fd mSocket;
Yifan Hongf6b4d5c2021-06-23 19:12:32 -0700145};
146
147// RpcTransportCtx with TLS disabled.
148class RpcTransportCtxRaw : public RpcTransportCtx {
149public:
Yifan Hongf6d42292021-08-05 23:43:05 -0700150 std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd, FdTrigger*) const {
Yifan Hongf6b4d5c2021-06-23 19:12:32 -0700151 return std::make_unique<RpcTransportRaw>(std::move(fd));
152 }
Yifan Hong9734cfc2021-09-13 16:14:09 -0700153 std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override { return {}; }
Yifan Hongf6b4d5c2021-06-23 19:12:32 -0700154};
Yifan Hong588d59c2021-08-16 17:13:58 -0700155
Yifan Hongf6b4d5c2021-06-23 19:12:32 -0700156} // namespace
157
158std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newServerCtx() const {
159 return std::make_unique<RpcTransportCtxRaw>();
160}
161
162std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newClientCtx() const {
163 return std::make_unique<RpcTransportCtxRaw>();
164}
165
166const char *RpcTransportCtxFactoryRaw::toCString() const {
167 return "raw";
168}
169
170std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryRaw::make() {
171 return std::unique_ptr<RpcTransportCtxFactoryRaw>(new RpcTransportCtxFactoryRaw());
172}
173
174} // namespace android