Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ad71b55 authored by Andrei Homescu's avatar Andrei Homescu
Browse files

libbinder: Return status_t from RpcTransport::peek()

Result<> pulls in over 100k of extra libc++ code on Trusty
so this CL replaces it with status_t as the result type of
RpcTransport::peek().

Bug: 224644083
Test: atest binderRpcTest
Change-Id: Idde111245794dc4afd421f3a723feacc8c3a346e
parent 24350bb0
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -660,8 +660,14 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con
status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
                                 const sp<RpcSession>& session, CommandType type) {
    uint8_t buf;
    while (connection->rpcTransport->peek(&buf, sizeof(buf)).value_or(0) > 0) {
        status_t status = getAndExecuteCommand(connection, session, type);
    while (true) {
        size_t num_bytes;
        status_t status = connection->rpcTransport->peek(&buf, sizeof(buf), &num_bytes);
        if (status == WOULD_BLOCK) break;
        if (status != OK) return status;
        if (!num_bytes) break;

        status = getAndExecuteCommand(connection, session, type);
        if (status != OK) return status;
    }
    return OK;
+11 −6
Original line number Diff line number Diff line
@@ -24,9 +24,6 @@
#include "FdTrigger.h"
#include "RpcState.h"

using android::base::ErrnoError;
using android::base::Result;

namespace android {

namespace {
@@ -35,12 +32,20 @@ namespace {
class RpcTransportRaw : public RpcTransport {
public:
    explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {}
    Result<size_t> peek(void *buf, size_t size) override {
    status_t peek(void* buf, size_t size, size_t* out_size) override {
        ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK));
        if (ret < 0) {
            return ErrnoError() << "recv(MSG_PEEK)";
            int savedErrno = errno;
            if (savedErrno == EAGAIN || savedErrno == EWOULDBLOCK) {
                return WOULD_BLOCK;
            }
        return ret;

            LOG_RPC_DETAIL("RpcTransport peek(): %s", strerror(savedErrno));
            return -savedErrno;
        }

        *out_size = static_cast<size_t>(ret);
        return OK;
    }

    template <typename SendOrReceive>
+24 −19
Original line number Diff line number Diff line
@@ -37,10 +37,6 @@
#define LOG_TLS_DETAIL(...) ALOGV(__VA_ARGS__) // for type checking
#endif

using android::base::ErrnoError;
using android::base::Error;
using android::base::Result;

namespace android {
namespace {

@@ -165,17 +161,8 @@ public:
        return ret;
    }

    // |sslError| should be from Ssl::getError().
    // If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
    // return error. Also return error if |fdTrigger| is triggered before or during poll().
    status_t pollForSslError(android::base::borrowed_fd fd, int sslError, FdTrigger* fdTrigger,
                             const char* fnString, int additionalEvent,
                             const std::function<status_t()>& altPoll) {
    status_t toStatus(int sslError, const char* fnString) {
        switch (sslError) {
            case SSL_ERROR_WANT_READ:
                return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_WANT_WRITE:
                return handlePoll(POLLOUT | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_SYSCALL: {
                auto queue = toString();
                LOG_TLS_DETAIL("%s(): %s. Treating as DEAD_OBJECT. Error queue: %s", fnString,
@@ -191,6 +178,22 @@ public:
        }
    }

    // |sslError| should be from Ssl::getError().
    // If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
    // return error. Also return error if |fdTrigger| is triggered before or during poll().
    status_t pollForSslError(android::base::borrowed_fd fd, int sslError, FdTrigger* fdTrigger,
                             const char* fnString, int additionalEvent,
                             const std::function<status_t()>& altPoll) {
        switch (sslError) {
            case SSL_ERROR_WANT_READ:
                return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
            case SSL_ERROR_WANT_WRITE:
                return handlePoll(POLLOUT | additionalEvent, fd, fdTrigger, fnString, altPoll);
            default:
                return toStatus(sslError, fnString);
        }
    }

private:
    bool mHandled = false;

@@ -274,7 +277,7 @@ class RpcTransportTls : public RpcTransport {
public:
    RpcTransportTls(android::base::unique_fd socket, Ssl ssl)
          : mSocket(std::move(socket)), mSsl(std::move(ssl)) {}
    Result<size_t> peek(void* buf, size_t size) override;
    status_t peek(void* buf, size_t size, size_t* out_size) override;
    status_t interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
                                     const std::function<status_t()>& altPoll) override;
    status_t interruptableReadFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
@@ -286,7 +289,7 @@ private:
};

// Error code is errno.
Result<size_t> RpcTransportTls::peek(void* buf, size_t size) {
status_t RpcTransportTls::peek(void* buf, size_t size, size_t* out_size) {
    size_t todo = std::min<size_t>(size, std::numeric_limits<int>::max());
    auto [ret, errorQueue] = mSsl.call(SSL_peek, buf, static_cast<int>(todo));
    if (ret < 0) {
@@ -294,13 +297,15 @@ Result<size_t> RpcTransportTls::peek(void* buf, size_t size) {
        if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
            // Seen EAGAIN / EWOULDBLOCK on recv(2) / send(2).
            // Like RpcTransportRaw::peek(), don't handle it here.
            return Error(EWOULDBLOCK) << "SSL_peek(): " << errorQueue.toString();
            errorQueue.clear();
            return WOULD_BLOCK;
        }
        return Error() << "SSL_peek(): " << errorQueue.toString();
        return errorQueue.toStatus(err, "SSL_peek");
    }
    errorQueue.clear();
    LOG_TLS_DETAIL("TLS: Peeked %d bytes!", ret);
    return ret;
    *out_size = static_cast<size_t>(ret);
    return OK;
}

status_t RpcTransportTls::interruptableWriteFully(FdTrigger* fdTrigger, iovec* iovs, int niovs,
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include <memory>
#include <string>

#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <utils/Errors.h>

@@ -41,7 +40,7 @@ public:
    virtual ~RpcTransport() = default;

    // replacement of ::recv(MSG_PEEK). Error code may not be set if TLS is enabled.
    [[nodiscard]] virtual android::base::Result<size_t> peek(void *buf, size_t size) = 0;
    [[nodiscard]] virtual status_t peek(void *buf, size_t size, size_t *out_size) = 0;

    /**
     * Read (or write), but allow to be interrupted by a trigger.
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <memory>
#include <mutex>
#include <vector>

#include <binder/RpcAuth.h>
#include <binder/RpcCertificateFormat.h>