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

Commit aecdd17c authored by Yifan Hong's avatar Yifan Hong
Browse files

binder: Add TLS to benchmark

Test: run benchmark
Fixes: 199747871
Change-Id: Ifce173017ac82dfd67de2b6315987494532d3424
parent aa677d97
Loading
Loading
Loading
Loading
+8 −1
Original line number Original line Diff line number Diff line
@@ -175,7 +175,10 @@ cc_test {


cc_benchmark {
cc_benchmark {
    name: "binderRpcBenchmark",
    name: "binderRpcBenchmark",
    defaults: ["binder_test_defaults"],
    defaults: [
        "binder_test_defaults",
        "libbinder_tls_shared_deps",
    ],
    host_supported: true,
    host_supported: true,
    target: {
    target: {
        darwin: {
        darwin: {
@@ -185,6 +188,7 @@ cc_benchmark {
    srcs: [
    srcs: [
        "binderRpcBenchmark.cpp",
        "binderRpcBenchmark.cpp",
        "IBinderRpcBenchmark.aidl",
        "IBinderRpcBenchmark.aidl",
        "RpcAuthTesting.cpp",
    ],
    ],
    shared_libs: [
    shared_libs: [
        "libbase",
        "libbase",
@@ -192,6 +196,9 @@ cc_benchmark {
        "liblog",
        "liblog",
        "libutils",
        "libutils",
    ],
    ],
    static_libs: [
        "libbinder_tls_static",
    ],
}
}


cc_test {
cc_test {
+72 −21
Original line number Original line Diff line number Diff line
@@ -21,8 +21,14 @@
#include <binder/IPCThreadState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/ProcessState.h>
#include <binder/RpcCertificateFormat.h>
#include <binder/RpcCertificateVerifier.h>
#include <binder/RpcServer.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
#include <binder/RpcSession.h>
#include <binder/RpcTlsUtils.h>
#include <binder/RpcTransportRaw.h>
#include <binder/RpcTransportTls.h>
#include <openssl/ssl.h>


#include <thread>
#include <thread>


@@ -31,6 +37,8 @@
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>


#include "RpcAuthTesting.h"

using android::BBinder;
using android::BBinder;
using android::defaultServiceManager;
using android::defaultServiceManager;
using android::IBinder;
using android::IBinder;
@@ -39,8 +47,14 @@ using android::IPCThreadState;
using android::IServiceManager;
using android::IServiceManager;
using android::OK;
using android::OK;
using android::ProcessState;
using android::ProcessState;
using android::RpcAuthPreSigned;
using android::RpcCertificateFormat;
using android::RpcCertificateVerifier;
using android::RpcServer;
using android::RpcServer;
using android::RpcSession;
using android::RpcSession;
using android::RpcTransportCtxFactory;
using android::RpcTransportCtxFactoryRaw;
using android::RpcTransportCtxFactoryTls;
using android::sp;
using android::sp;
using android::status_t;
using android::status_t;
using android::statusToString;
using android::statusToString;
@@ -65,15 +79,37 @@ class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
enum Transport {
enum Transport {
    KERNEL,
    KERNEL,
    RPC,
    RPC,
    RPC_TLS,
};
};


static const std::initializer_list<int64_t> kTransportList = {
static const std::initializer_list<int64_t> kTransportList = {
#ifdef __BIONIC__
#ifdef __BIONIC__
        Transport::KERNEL,
        Transport::KERNEL,
#endif
#endif
        Transport::RPC};
        Transport::RPC,
        Transport::RPC_TLS,
};

// Certificate validation happens during handshake and does not affect the result of benchmarks.
// Skip certificate validation to simplify the setup process.
class RpcCertificateVerifierNoOp : public RpcCertificateVerifier {
public:
    status_t verify(const SSL*, uint8_t*) override { return OK; }
};

std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() {
    auto pkey = android::makeKeyPairForSelfSignedCert();
    CHECK_NE(pkey.get(), nullptr);
    auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds);
    CHECK_NE(cert.get(), nullptr);

    auto verifier = std::make_shared<RpcCertificateVerifierNoOp>();
    auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert));
    return RpcTransportCtxFactoryTls::make(verifier, std::move(auth));
}


static sp<RpcSession> gSession = RpcSession::make();
static sp<RpcSession> gSession = RpcSession::make();
static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
#ifdef __BIONIC__
#ifdef __BIONIC__
static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
static sp<IBinder> gKernelBinder;
static sp<IBinder> gKernelBinder;
@@ -88,6 +124,8 @@ static sp<IBinder> getBinderForOptions(benchmark::State& state) {
#endif
#endif
        case RPC:
        case RPC:
            return gSession->getRootObject();
            return gSession->getRootObject();
        case RPC_TLS:
            return gSessionTls->getRootObject();
        default:
        default:
            LOG(FATAL) << "Unknown transport value: " << transport;
            LOG(FATAL) << "Unknown transport value: " << transport;
            return nullptr;
            return nullptr;
@@ -169,26 +207,35 @@ void BM_repeatBinder(benchmark::State& state) {
}
}
BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});
BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});


int main(int argc, char** argv) {
void forkRpcServer(const char* addr, const sp<RpcServer>& server) {
    ::benchmark::Initialize(&argc, argv);
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;

    std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
    (void)unlink(addr.c_str());

    std::cerr << "Tests suffixes:" << std::endl;
    std::cerr << "\t.../" << Transport::KERNEL << " is KERNEL" << std::endl;
    std::cerr << "\t.../" << Transport::RPC << " is RPC" << std::endl;

    if (0 == fork()) {
    if (0 == fork()) {
        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
        sp<RpcServer> server = RpcServer::make();
        server->setRootObject(sp<MyBinderRpcBenchmark>::make());
        server->setRootObject(sp<MyBinderRpcBenchmark>::make());
        server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
        server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
        CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
        CHECK_EQ(OK, server->setupUnixDomainServer(addr));
        server->join();
        server->join();
        exit(1);
        exit(1);
    }
    }
}

void setupClient(const sp<RpcSession>& session, const char* addr) {
    status_t status;
    for (size_t tries = 0; tries < 5; tries++) {
        usleep(10000);
        status = session->setupUnixDomainClient(addr);
        if (status == OK) break;
    }
    CHECK_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
}

int main(int argc, char** argv) {
    ::benchmark::Initialize(&argc, argv);
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;

    std::cerr << "Tests suffixes:" << std::endl;
    std::cerr << "\t.../" << Transport::KERNEL << " is KERNEL" << std::endl;
    std::cerr << "\t.../" << Transport::RPC << " is RPC" << std::endl;
    std::cerr << "\t.../" << Transport::RPC_TLS << " is RPC with TLS" << std::endl;


#ifdef __BIONIC__
#ifdef __BIONIC__
    if (0 == fork()) {
    if (0 == fork()) {
@@ -207,13 +254,17 @@ int main(int argc, char** argv) {
    CHECK_NE(nullptr, gKernelBinder.get());
    CHECK_NE(nullptr, gKernelBinder.get());
#endif
#endif


    status_t status;
    std::string tmp = getenv("TMPDIR") ?: "/tmp";
    for (size_t tries = 0; tries < 5; tries++) {

        usleep(10000);
    std::string addr = tmp + "/binderRpcBenchmark";
        status = gSession->setupUnixDomainClient(addr.c_str());
    (void)unlink(addr.c_str());
        if (status == OK) break;
    forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
    }
    setupClient(gSession, addr.c_str());
    CHECK_EQ(status, OK) << "Could not connect: " << statusToString(status).c_str();

    std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
    (void)unlink(tlsAddr.c_str());
    forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
    setupClient(gSessionTls, tlsAddr.c_str());


    ::benchmark::RunSpecifiedBenchmarks();
    ::benchmark::RunSpecifiedBenchmarks();
    return 0;
    return 0;