diff options
| author | 2021-09-13 19:06:12 +0000 | |
|---|---|---|
| committer | 2021-09-13 19:06:12 +0000 | |
| commit | fa64e8b448f83db62cd1298978b286f16fef08fa (patch) | |
| tree | 3ffebf91cf4771a4af3fa6753a5c8625c30d8f9e | |
| parent | eeb7ba4a6aa6ee05777e5877e0be4f3452700576 (diff) | |
| parent | 8b245c803049691f5703bed05946b67135e8dfac (diff) | |
Merge changes If27bffb5,I945e650b am: 21fcad29cd am: bd0fef633f am: bd9607b9f1 am: 8b245c8030
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1824010
Change-Id: I961144c07d69f5fc13dcc957bd687c148834a105
| -rw-r--r-- | libs/binder/Android.bp | 1 | ||||
| -rw-r--r-- | libs/binder/BpBinder.cpp | 4 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 14 | ||||
| -rw-r--r-- | libs/binder/RpcAddress.cpp | 112 | ||||
| -rw-r--r-- | libs/binder/RpcServer.cpp | 50 | ||||
| -rw-r--r-- | libs/binder/RpcSession.cpp | 57 | ||||
| -rw-r--r-- | libs/binder/RpcState.cpp | 160 | ||||
| -rw-r--r-- | libs/binder/RpcState.h | 21 | ||||
| -rw-r--r-- | libs/binder/RpcWireFormat.h | 32 | ||||
| -rw-r--r-- | libs/binder/include/binder/BpBinder.h | 9 | ||||
| -rw-r--r-- | libs/binder/include/binder/RpcAddress.h | 80 | ||||
| -rw-r--r-- | libs/binder/include/binder/RpcServer.h | 3 | ||||
| -rw-r--r-- | libs/binder/include/binder/RpcSession.h | 15 |
13 files changed, 212 insertions, 346 deletions
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index 97c252a9f0..3da1905f45 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -117,7 +117,6 @@ cc_library { "ParcelFileDescriptor.cpp", "PersistableBundle.cpp", "ProcessState.cpp", - "RpcAddress.cpp", "RpcSession.cpp", "RpcServer.cpp", "RpcState.cpp", diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index 1100d72a0c..687ee257fd 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -156,7 +156,7 @@ sp<BpBinder> BpBinder::create(int32_t handle) { return sp<BpBinder>::make(BinderHandle{handle}, trackedUid); } -sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, const RpcAddress& address) { +sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, uint64_t address) { LOG_ALWAYS_FATAL_IF(session == nullptr, "BpBinder::create null session"); // These are not currently tracked, since there is no UID or other @@ -193,7 +193,7 @@ bool BpBinder::isRpcBinder() const { return std::holds_alternative<RpcHandle>(mHandle); } -const RpcAddress& BpBinder::rpcAddress() const { +uint64_t BpBinder::rpcAddress() const { return std::get<RpcHandle>(mHandle).address; } diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 99b6be8d4e..dce6f3bf70 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -205,11 +205,11 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) { if (binder) { status_t status = writeInt32(1); // non-null if (status != OK) return status; - RpcAddress address = RpcAddress::zero(); + uint64_t address; // TODO(b/167966510): need to undo this if the Parcel is not sent status = mSession->state()->onBinderLeaving(mSession, binder, &address); if (status != OK) return status; - status = address.writeToParcel(this); + status = writeUint64(address); if (status != OK) return status; } else { status_t status = writeInt32(0); // null @@ -279,15 +279,15 @@ status_t Parcel::unflattenBinder(sp<IBinder>* out) const if (isForRpc()) { LOG_ALWAYS_FATAL_IF(mSession == nullptr, "RpcSession required to read from remote parcel"); - int32_t isNull; - status_t status = readInt32(&isNull); + int32_t isPresent; + status_t status = readInt32(&isPresent); if (status != OK) return status; sp<IBinder> binder; - if (isNull & 1) { - auto addr = RpcAddress::zero(); - if (status_t status = addr.readFromParcel(*this); status != OK) return status; + if (isPresent & 1) { + uint64_t addr; + if (status_t status = readUint64(&addr); status != OK) return status; if (status_t status = mSession->state()->onBinderEntering(mSession, addr, &binder); status != OK) return status; diff --git a/libs/binder/RpcAddress.cpp b/libs/binder/RpcAddress.cpp deleted file mode 100644 index ffc94b94b3..0000000000 --- a/libs/binder/RpcAddress.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <binder/RpcAddress.h> - -#include <android-base/hex.h> -#include <binder/Parcel.h> - -#include "Debug.h" -#include "RpcState.h" -#include "RpcWireFormat.h" - -namespace android { - -RpcAddress RpcAddress::zero() { - return RpcAddress(); -} - -bool RpcAddress::isZero() const { - RpcWireAddress ZERO{.options = 0}; - return memcmp(mRawAddr.get(), &ZERO, sizeof(RpcWireAddress)) == 0; -} - -static void ReadRandomBytes(uint8_t* buf, size_t len) { - int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); - if (fd == -1) { - ALOGE("%s: cannot read /dev/urandom", __func__); - return; - } - - size_t n; - while ((n = TEMP_FAILURE_RETRY(read(fd, buf, len))) > 0) { - len -= n; - buf += n; - } - if (len > 0) { - ALOGW("%s: there are %d bytes skipped", __func__, (int)len); - } - close(fd); -} - -RpcAddress RpcAddress::random(bool forServer) { - // The remainder of this header acts as reserved space for different kinds - // of binder objects. - uint64_t options = RPC_WIRE_ADDRESS_OPTION_CREATED; - - // servers and clients allocate addresses independently, so this bit can - // tell you where an address originates - if (forServer) options |= RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; - - RpcAddress ret; - RpcWireAddress* raw = ret.mRawAddr.get(); - - raw->options = options; - ReadRandomBytes(raw->address, sizeof(raw->address)); - - LOG_RPC_DETAIL("Creating new address: %s", ret.toString().c_str()); - return ret; -} - -bool RpcAddress::isForServer() const { - return mRawAddr.get()->options & RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; -} - -bool RpcAddress::isRecognizedType() const { - uint64_t allKnownOptions = RPC_WIRE_ADDRESS_OPTION_CREATED | RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; - return (mRawAddr.get()->options & ~allKnownOptions) == 0; -} - -RpcAddress RpcAddress::fromRawEmbedded(const RpcWireAddress* raw) { - RpcAddress addr; - memcpy(addr.mRawAddr.get(), raw, sizeof(RpcWireAddress)); - return addr; -} - -const RpcWireAddress& RpcAddress::viewRawEmbedded() const { - return *mRawAddr.get(); -} - -bool RpcAddress::operator<(const RpcAddress& rhs) const { - return std::memcmp(mRawAddr.get(), rhs.mRawAddr.get(), sizeof(RpcWireAddress)) < 0; -} - -std::string RpcAddress::toString() const { - return base::HexString(mRawAddr.get(), sizeof(RpcWireAddress)); -} - -status_t RpcAddress::writeToParcel(Parcel* parcel) const { - return parcel->write(mRawAddr.get(), sizeof(RpcWireAddress)); -} - -status_t RpcAddress::readFromParcel(const Parcel& parcel) { - return parcel.read(mRawAddr.get(), sizeof(RpcWireAddress)); -} - -RpcAddress::~RpcAddress() {} -RpcAddress::RpcAddress() : mRawAddr(std::make_shared<RpcWireAddress>()) {} - -} // namespace android diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp index ba723e6ef3..7fa2f5764f 100644 --- a/libs/binder/RpcServer.cpp +++ b/libs/binder/RpcServer.cpp @@ -23,6 +23,8 @@ #include <thread> #include <vector> +#include <android-base/file.h> +#include <android-base/hex.h> #include <android-base/scopeguard.h> #include <binder/Parcel.h> #include <binder/RpcServer.h> @@ -281,17 +283,29 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie } } + std::vector<uint8_t> sessionId; + if (status == OK) { + if (header.sessionIdSize > 0) { + sessionId.resize(header.sessionIdSize); + status = client->interruptableReadFully(server->mShutdownTrigger.get(), + sessionId.data(), sessionId.size()); + if (status != OK) { + ALOGE("Failed to read session ID for client connecting to RPC server: %s", + statusToString(status).c_str()); + // still need to cleanup before we can return + } + } + } + bool incoming = false; uint32_t protocolVersion = 0; - RpcAddress sessionId = RpcAddress::zero(); bool requestingNewSession = false; if (status == OK) { incoming = header.options & RPC_CONNECTION_OPTION_INCOMING; protocolVersion = std::min(header.version, server->mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION)); - sessionId = RpcAddress::fromRawEmbedded(&header.sessionId); - requestingNewSession = sessionId.isZero(); + requestingNewSession = sessionId.empty(); if (requestingNewSession) { RpcNewSessionResponse response{ @@ -333,15 +347,26 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie return; } + // Uniquely identify session at the application layer. Even if a + // client/server use the same certificates, if they create multiple + // sessions, we still want to distinguish between them. + constexpr size_t kSessionIdSize = 32; + sessionId.resize(kSessionIdSize); size_t tries = 0; do { // don't block if there is some entropy issue if (tries++ > 5) { - ALOGE("Cannot find new address: %s", sessionId.toString().c_str()); + ALOGE("Cannot find new address: %s", + base::HexString(sessionId.data(), sessionId.size()).c_str()); return; } - sessionId = RpcAddress::random(true /*forServer*/); + base::unique_fd fd(TEMP_FAILURE_RETRY( + open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW))); + if (!base::ReadFully(fd, sessionId.data(), sessionId.size())) { + ALOGE("Could not read from /dev/urandom to create session ID"); + return; + } } while (server->mSessions.end() != server->mSessions.find(sessionId)); session = RpcSession::make(); @@ -361,7 +386,7 @@ void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clie auto it = server->mSessions.find(sessionId); if (it == server->mSessions.end()) { ALOGE("Cannot add thread, no record of session with ID %s", - sessionId.toString().c_str()); + base::HexString(sessionId.data(), sessionId.size()).c_str()); return; } session = it->second; @@ -423,16 +448,17 @@ status_t RpcServer::setupSocketServer(const RpcSocketAddress& addr) { } void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) { - auto id = session->mId; - LOG_ALWAYS_FATAL_IF(id == std::nullopt, "Server sessions must be initialized with ID"); - LOG_RPC_DETAIL("Dropping session with address %s", id->toString().c_str()); + const std::vector<uint8_t>& id = session->mId; + LOG_ALWAYS_FATAL_IF(id.empty(), "Server sessions must be initialized with ID"); + LOG_RPC_DETAIL("Dropping session with address %s", + base::HexString(id.data(), id.size()).c_str()); std::lock_guard<std::mutex> _l(mLock); - auto it = mSessions.find(*id); + auto it = mSessions.find(id); LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %s", - id->toString().c_str()); + base::HexString(id.data(), id.size()).c_str()); LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %s", - id->toString().c_str()); + base::HexString(id.data(), id.size()).c_str()); (void)mSessions.erase(it); } diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index 8da3fa3c3f..c5a8dd1ddf 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -26,6 +26,7 @@ #include <string_view> +#include <android-base/hex.h> #include <android-base/macros.h> #include <android_runtime/vm.h> #include <binder/Parcel.h> @@ -132,7 +133,7 @@ status_t RpcSession::setupInetClient(const char* addr, unsigned int port) { } status_t RpcSession::setupPreconnectedClient(unique_fd fd, std::function<unique_fd()>&& request) { - return setupClient([&](const RpcAddress& sessionId, bool incoming) -> status_t { + return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) -> status_t { // std::move'd from fd becomes -1 (!ok()) if (!fd.ok()) { fd = request(); @@ -214,7 +215,7 @@ status_t RpcSession::transact(const sp<IBinder>& binder, uint32_t code, const Pa sp<RpcSession>::fromExisting(this), reply, flags); } -status_t RpcSession::sendDecStrong(const RpcAddress& address) { +status_t RpcSession::sendDecStrong(uint64_t address) { ExclusiveConnection connection; status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT_REFCOUNT, &connection); @@ -233,12 +234,11 @@ status_t RpcSession::readId() { ConnectionUse::CLIENT, &connection); if (status != OK) return status; - mId = RpcAddress::zero(); - status = state()->getSessionId(connection.get(), sp<RpcSession>::fromExisting(this), - &mId.value()); + status = state()->getSessionId(connection.get(), sp<RpcSession>::fromExisting(this), &mId); if (status != OK) return status; - LOG_RPC_DETAIL("RpcSession %p has id %s", this, mId->toString().c_str()); + LOG_RPC_DETAIL("RpcSession %p has id %s", this, + base::HexString(mId.data(), mId.size()).c_str()); return OK; } @@ -397,8 +397,8 @@ sp<RpcServer> RpcSession::server() { return server; } -status_t RpcSession::setupClient( - const std::function<status_t(const RpcAddress& sessionId, bool incoming)>& connectAndInit) { +status_t RpcSession::setupClient(const std::function<status_t(const std::vector<uint8_t>& sessionId, + bool incoming)>& connectAndInit) { { std::lock_guard<std::mutex> _l(mMutex); LOG_ALWAYS_FATAL_IF(mOutgoingConnections.size() != 0, @@ -407,8 +407,7 @@ status_t RpcSession::setupClient( } if (auto status = initShutdownTrigger(); status != OK) return status; - if (status_t status = connectAndInit(RpcAddress::zero(), false /*incoming*/); status != OK) - return status; + if (status_t status = connectAndInit({}, false /*incoming*/); status != OK) return status; { ExclusiveConnection connection; @@ -449,26 +448,25 @@ status_t RpcSession::setupClient( // we've already setup one client for (size_t i = 0; i + 1 < numThreadsAvailable; i++) { - if (status_t status = connectAndInit(mId.value(), false /*incoming*/); status != OK) - return status; + if (status_t status = connectAndInit(mId, false /*incoming*/); status != OK) return status; } for (size_t i = 0; i < mMaxThreads; i++) { - if (status_t status = connectAndInit(mId.value(), true /*incoming*/); status != OK) - return status; + if (status_t status = connectAndInit(mId, true /*incoming*/); status != OK) return status; } return OK; } status_t RpcSession::setupSocketClient(const RpcSocketAddress& addr) { - return setupClient([&](const RpcAddress& sessionId, bool incoming) { + return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) { return setupOneSocketConnection(addr, sessionId, incoming); }); } status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, - const RpcAddress& sessionId, bool incoming) { + const std::vector<uint8_t>& sessionId, + bool incoming) { for (size_t tries = 0; tries < 5; tries++) { if (tries > 0) usleep(10000); @@ -526,7 +524,7 @@ status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr, return UNKNOWN_ERROR; } -status_t RpcSession::initAndAddConnection(unique_fd fd, const RpcAddress& sessionId, +status_t RpcSession::initAndAddConnection(unique_fd fd, const std::vector<uint8_t>& sessionId, bool incoming) { LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr); auto server = mCtx->newTransport(std::move(fd), mShutdownTrigger.get()); @@ -537,13 +535,20 @@ status_t RpcSession::initAndAddConnection(unique_fd fd, const RpcAddress& sessio LOG_RPC_DETAIL("Socket at client with RpcTransport %p", server.get()); + if (sessionId.size() > std::numeric_limits<uint16_t>::max()) { + ALOGE("Session ID too big %zu", sessionId.size()); + return BAD_VALUE; + } + RpcConnectionHeader header{ .version = mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION), .options = 0, + .sessionIdSize = static_cast<uint16_t>(sessionId.size()), }; - memcpy(&header.sessionId, &sessionId.viewRawEmbedded(), sizeof(RpcWireAddress)); - if (incoming) header.options |= RPC_CONNECTION_OPTION_INCOMING; + if (incoming) { + header.options |= RPC_CONNECTION_OPTION_INCOMING; + } auto sendHeaderStatus = server->interruptableWriteFully(mShutdownTrigger.get(), &header, sizeof(header)); @@ -553,6 +558,18 @@ status_t RpcSession::initAndAddConnection(unique_fd fd, const RpcAddress& sessio return sendHeaderStatus; } + if (sessionId.size() > 0) { + auto sendSessionIdStatus = + server->interruptableWriteFully(mShutdownTrigger.get(), sessionId.data(), + sessionId.size()); + if (sendSessionIdStatus != OK) { + ALOGE("Could not write session ID ('%s') to socket: %s", + base::HexString(sessionId.data(), sessionId.size()).c_str(), + statusToString(sendSessionIdStatus).c_str()); + return sendSessionIdStatus; + } + } + LOG_RPC_DETAIL("Socket at client: header sent"); if (incoming) { @@ -625,7 +642,7 @@ status_t RpcSession::addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTran } bool RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListener>& eventListener, - const RpcAddress& sessionId) { + const std::vector<uint8_t>& sessionId) { LOG_ALWAYS_FATAL_IF(mForServer != nullptr); LOG_ALWAYS_FATAL_IF(server == nullptr); LOG_ALWAYS_FATAL_IF(mEventListener != nullptr); diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index b58f1b38ff..59643ba4ee 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -52,7 +52,7 @@ RpcState::RpcState() {} RpcState::~RpcState() {} status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBinder>& binder, - RpcAddress* outAddress) { + uint64_t* outAddress) { bool isRemote = binder->remoteBinder(); bool isRpc = isRemote && binder->remoteBinder()->isRpcBinder(); @@ -84,12 +84,11 @@ status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBind for (auto& [addr, node] : mNodeForAddress) { if (binder == node.binder) { if (isRpc) { - const RpcAddress& actualAddr = + // check integrity of data structure + uint64_t actualAddr = binder->remoteBinder()->getPrivateAccessorForId().rpcAddress(); - // TODO(b/182939933): this is only checking integrity of data structure - // a different data structure doesn't need this - LOG_ALWAYS_FATAL_IF(addr < actualAddr, "Address mismatch"); - LOG_ALWAYS_FATAL_IF(actualAddr < addr, "Address mismatch"); + LOG_ALWAYS_FATAL_IF(addr != actualAddr, "Address mismatch %" PRIu64 " vs %" PRIu64, + addr, actualAddr); } node.timesSent++; node.sentRef = binder; // might already be set @@ -101,8 +100,29 @@ status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBind bool forServer = session->server() != nullptr; - for (size_t tries = 0; tries < 5; tries++) { - auto&& [it, inserted] = mNodeForAddress.insert({RpcAddress::random(forServer), + // arbitrary limit for maximum number of nodes in a process (otherwise we + // might run out of addresses) + if (mNodeForAddress.size() > 100000) { + return NO_MEMORY; + } + + while (true) { + RpcWireAddress address{ + .options = RPC_WIRE_ADDRESS_OPTION_CREATED, + .address = mNextId, + }; + if (forServer) { + address.options |= RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; + } + + // avoid ubsan abort + if (mNextId >= std::numeric_limits<uint32_t>::max()) { + mNextId = 0; + } else { + mNextId++; + } + + auto&& [it, inserted] = mNodeForAddress.insert({RpcWireAddress::toRaw(address), BinderNode{ .binder = binder, .timesSent = 1, @@ -112,18 +132,10 @@ status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBind *outAddress = it->first; return OK; } - - // well, we don't have visibility into the header here, but still - static_assert(sizeof(RpcWireAddress) == 40, "this log needs updating"); - ALOGW("2**256 is 1e77. If you see this log, you probably have some entropy issue, or maybe " - "you witness something incredible!"); } - - ALOGE("Unable to create an address in order to send out %p", binder.get()); - return WOULD_BLOCK; } -status_t RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address, +status_t RpcState::onBinderEntering(const sp<RpcSession>& session, uint64_t address, sp<IBinder>* out) { // ensure that: if we want to use addresses for something else in the future (for // instance, allowing transitive binder sends), that we don't accidentally @@ -133,8 +145,11 @@ status_t RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddr // if we communicate with a binder, it could always be proxying // information. However, we want to make sure that isn't done on accident // by a client. - if (!address.isRecognizedType()) { - ALOGE("Address is of an unknown type, rejecting: %s", address.toString().c_str()); + RpcWireAddress addr = RpcWireAddress::fromRaw(address); + constexpr uint32_t kKnownOptions = + RPC_WIRE_ADDRESS_OPTION_CREATED | RPC_WIRE_ADDRESS_OPTION_FOR_SERVER; + if (addr.options & ~kKnownOptions) { + ALOGE("Address is of an unknown type, rejecting: %" PRIu64, address); return BAD_VALUE; } @@ -159,9 +174,9 @@ status_t RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddr // we don't know about this binder, so the other side of the connection // should have created it. - if (address.isForServer() == !!session->server()) { - ALOGE("Server received unrecognized address which we should own the creation of %s.", - address.toString().c_str()); + if ((addr.options & RPC_WIRE_ADDRESS_OPTION_FOR_SERVER) == !!session->server()) { + ALOGE("Server received unrecognized address which we should own the creation of %" PRIu64, + address); return BAD_VALUE; } @@ -241,9 +256,8 @@ void RpcState::dumpLocked() { desc = "(null)"; } - ALOGE("- BINDER NODE: %p times sent:%zu times recd: %zu a:%s type:%s", - node.binder.unsafe_get(), node.timesSent, node.timesRecd, address.toString().c_str(), - desc); + ALOGE("- BINDER NODE: %p times sent:%zu times recd: %zu a: %" PRIu64 " type: %s", + node.binder.unsafe_get(), node.timesSent, node.timesRecd, address, desc); } ALOGE("END DUMP OF RpcState"); } @@ -360,8 +374,8 @@ sp<IBinder> RpcState::getRootObject(const sp<RpcSession::RpcConnection>& connect data.markForRpc(session); Parcel reply; - status_t status = transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_ROOT, - data, session, &reply, 0); + status_t status = + transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_ROOT, data, session, &reply, 0); if (status != OK) { ALOGE("Error getting root object: %s", statusToString(status).c_str()); return nullptr; @@ -376,9 +390,8 @@ status_t RpcState::getMaxThreads(const sp<RpcSession::RpcConnection>& connection data.markForRpc(session); Parcel reply; - status_t status = - transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_MAX_THREADS, - data, session, &reply, 0); + status_t status = transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_MAX_THREADS, data, + session, &reply, 0); if (status != OK) { ALOGE("Error getting max threads: %s", statusToString(status).c_str()); return status; @@ -397,20 +410,19 @@ status_t RpcState::getMaxThreads(const sp<RpcSession::RpcConnection>& connection } status_t RpcState::getSessionId(const sp<RpcSession::RpcConnection>& connection, - const sp<RpcSession>& session, RpcAddress* sessionIdOut) { + const sp<RpcSession>& session, std::vector<uint8_t>* sessionIdOut) { Parcel data; data.markForRpc(session); Parcel reply; - status_t status = - transactAddress(connection, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_SESSION_ID, - data, session, &reply, 0); + status_t status = transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_SESSION_ID, data, + session, &reply, 0); if (status != OK) { ALOGE("Error getting session ID: %s", statusToString(status).c_str()); return status; } - return sessionIdOut->readFromParcel(reply); + return reply.readByteVector(sessionIdOut); } status_t RpcState::transact(const sp<RpcSession::RpcConnection>& connection, @@ -426,26 +438,26 @@ status_t RpcState::transact(const sp<RpcSession::RpcConnection>& connection, return BAD_TYPE; } - RpcAddress address = RpcAddress::zero(); + uint64_t address; if (status_t status = onBinderLeaving(session, binder, &address); status != OK) return status; return transactAddress(connection, address, code, data, session, reply, flags); } status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connection, - const RpcAddress& address, uint32_t code, const Parcel& data, + uint64_t address, uint32_t code, const Parcel& data, const sp<RpcSession>& session, Parcel* reply, uint32_t flags) { LOG_ALWAYS_FATAL_IF(!data.isForRpc()); LOG_ALWAYS_FATAL_IF(data.objectsCount() != 0); uint64_t asyncNumber = 0; - if (!address.isZero()) { + if (address != 0) { std::unique_lock<std::mutex> _l(mNodeMutex); if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races auto it = mNodeForAddress.find(address); - LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s", - address.toString().c_str()); + LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), + "Sending transact on unknown address %" PRIu64, address); if (flags & IBinder::FLAG_ONEWAY) { asyncNumber = it->second.asyncNumber; @@ -466,8 +478,9 @@ status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connecti .command = RPC_COMMAND_TRANSACT, .bodySize = static_cast<uint32_t>(sizeof(RpcWireTransaction) + data.dataSize()), }; + RpcWireTransaction transaction{ - .address = address.viewRawEmbedded(), + .address = RpcWireAddress::fromRaw(address), .code = code, .flags = flags, .asyncNumber = asyncNumber, @@ -557,15 +570,14 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection, } status_t RpcState::sendDecStrong(const sp<RpcSession::RpcConnection>& connection, - const sp<RpcSession>& session, const RpcAddress& addr) { + const sp<RpcSession>& session, uint64_t addr) { { std::lock_guard<std::mutex> _l(mNodeMutex); if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races auto it = mNodeForAddress.find(addr); - LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending dec strong on unknown address %s", - addr.toString().c_str()); - LOG_ALWAYS_FATAL_IF(it->second.timesRecd <= 0, "Bad dec strong %s", - addr.toString().c_str()); + LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), + "Sending dec strong on unknown address %" PRIu64, addr); + LOG_ALWAYS_FATAL_IF(it->second.timesRecd <= 0, "Bad dec strong %" PRIu64, addr); it->second.timesRecd--; LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it), @@ -579,8 +591,7 @@ status_t RpcState::sendDecStrong(const sp<RpcSession::RpcConnection>& connection if (status_t status = rpcSend(connection, session, "dec ref header", &cmd, sizeof(cmd)); status != OK) return status; - if (status_t status = rpcSend(connection, session, "dec ref body", &addr.viewRawEmbedded(), - sizeof(RpcWireAddress)); + if (status_t status = rpcSend(connection, session, "dec ref body", &addr, sizeof(addr)); status != OK) return status; return OK; @@ -685,14 +696,12 @@ processTransactInternalTailCall: } RpcWireTransaction* transaction = reinterpret_cast<RpcWireTransaction*>(transactionData.data()); - // TODO(b/182939933): heap allocation just for lookup in mNodeForAddress, - // maybe add an RpcAddress 'view' if the type remains 'heavy' - auto addr = RpcAddress::fromRawEmbedded(&transaction->address); + uint64_t addr = RpcWireAddress::toRaw(transaction->address); bool oneway = transaction->flags & IBinder::FLAG_ONEWAY; status_t replyStatus = OK; sp<IBinder> target; - if (!addr.isZero()) { + if (addr != 0) { if (!targetRef) { replyStatus = onBinderEntering(session, addr, &target); } else { @@ -708,21 +717,21 @@ processTransactInternalTailCall: // (any binder which is being transacted on should be holding a // strong ref count), so in either case, terminating the // session. - ALOGE("While transacting, binder has been deleted at address %s. Terminating!", - addr.toString().c_str()); + ALOGE("While transacting, binder has been deleted at address %" PRIu64 ". Terminating!", + addr); (void)session->shutdownAndWait(false); replyStatus = BAD_VALUE; } else if (target->localBinder() == nullptr) { - ALOGE("Unknown binder address or non-local binder, not address %s. Terminating!", - addr.toString().c_str()); + ALOGE("Unknown binder address or non-local binder, not address %" PRIu64 + ". Terminating!", + addr); (void)session->shutdownAndWait(false); replyStatus = BAD_VALUE; } else if (oneway) { std::unique_lock<std::mutex> _l(mNodeMutex); auto it = mNodeForAddress.find(addr); if (it->second.binder.promote() != target) { - ALOGE("Binder became invalid during transaction. Bad client? %s", - addr.toString().c_str()); + ALOGE("Binder became invalid during transaction. Bad client? %" PRIu64, addr); replyStatus = BAD_VALUE; } else if (transaction->asyncNumber != it->second.asyncNumber) { // we need to process some other asynchronous transaction @@ -734,8 +743,8 @@ processTransactInternalTailCall: }); size_t numPending = it->second.asyncTodo.size(); - LOG_RPC_DETAIL("Enqueuing %" PRId64 " on %s (%zu pending)", - transaction->asyncNumber, addr.toString().c_str(), numPending); + LOG_RPC_DETAIL("Enqueuing %" PRIu64 " on %" PRIu64 " (%zu pending)", + transaction->asyncNumber, addr, numPending); constexpr size_t kArbitraryOnewayCallTerminateLevel = 10000; constexpr size_t kArbitraryOnewayCallWarnLevel = 1000; @@ -792,7 +801,7 @@ processTransactInternalTailCall: // for client connections, this should always report the value // originally returned from the server, so this is asserting // that it exists - replyStatus = session->mId.value().writeToParcel(&reply); + replyStatus = reply.writeByteVector(session->mId); break; } default: { @@ -820,8 +829,8 @@ processTransactInternalTailCall: ALOGW("Oneway call failed with error: %d", replyStatus); } - LOG_RPC_DETAIL("Processed async transaction %" PRId64 " on %s", transaction->asyncNumber, - addr.toString().c_str()); + LOG_RPC_DETAIL("Processed async transaction %" PRIu64 " on %" PRIu64, + transaction->asyncNumber, addr); // Check to see if there is another asynchronous transaction to process. // This behavior differs from binder behavior, since in the binder @@ -847,8 +856,8 @@ processTransactInternalTailCall: if (it->second.asyncTodo.size() == 0) return OK; if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) { - LOG_RPC_DETAIL("Found next async transaction %" PRId64 " on %s", - it->second.asyncNumber, addr.toString().c_str()); + LOG_RPC_DETAIL("Found next async transaction %" PRIu64 " on %" PRIu64, + it->second.asyncNumber, addr); // justification for const_cast (consider avoiding priority_queue): // - AsyncTodo operator< doesn't depend on 'data' or 'ref' objects @@ -904,7 +913,7 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect status != OK) return status; - if (command.bodySize < sizeof(RpcWireAddress)) { + if (command.bodySize != sizeof(RpcWireAddress)) { ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireAddress. Terminating!", sizeof(RpcWireAddress), command.bodySize); (void)session->shutdownAndWait(false); @@ -912,31 +921,32 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect } RpcWireAddress* address = reinterpret_cast<RpcWireAddress*>(commandData.data()); - // TODO(b/182939933): heap allocation just for lookup - auto addr = RpcAddress::fromRawEmbedded(address); + uint64_t addr = RpcWireAddress::toRaw(*address); + std::unique_lock<std::mutex> _l(mNodeMutex); auto it = mNodeForAddress.find(addr); if (it == mNodeForAddress.end()) { - ALOGE("Unknown binder address %s for dec strong.", addr.toString().c_str()); + ALOGE("Unknown binder address %" PRIu64 " for dec strong.", addr); return OK; } sp<IBinder> target = it->second.binder.promote(); if (target == nullptr) { - ALOGE("While requesting dec strong, binder has been deleted at address %s. Terminating!", - addr.toString().c_str()); + ALOGE("While requesting dec strong, binder has been deleted at address %" PRIu64 + ". Terminating!", + addr); _l.unlock(); (void)session->shutdownAndWait(false); return BAD_VALUE; } if (it->second.timesSent == 0) { - ALOGE("No record of sending binder, but requested decStrong: %s", addr.toString().c_str()); + ALOGE("No record of sending binder, but requested decStrong: %" PRIu64, addr); return OK; } - LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s", - addr.toString().c_str()); + LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %" PRIu64, + addr); it->second.timesSent--; sp<IBinder> tempHold = tryEraseNode(it); @@ -946,7 +956,7 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect return OK; } -sp<IBinder> RpcState::tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it) { +sp<IBinder> RpcState::tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it) { sp<IBinder> ref; if (it->second.timesSent == 0) { diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h index 1446eecc64..dcfb5699e8 100644 --- a/libs/binder/RpcState.h +++ b/libs/binder/RpcState.h @@ -73,17 +73,17 @@ public: status_t getMaxThreads(const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session, size_t* maxThreadsOut); status_t getSessionId(const sp<RpcSession::RpcConnection>& connection, - const sp<RpcSession>& session, RpcAddress* sessionIdOut); + const sp<RpcSession>& session, std::vector<uint8_t>* sessionIdOut); [[nodiscard]] status_t transact(const sp<RpcSession::RpcConnection>& connection, const sp<IBinder>& address, uint32_t code, const Parcel& data, const sp<RpcSession>& session, Parcel* reply, uint32_t flags); [[nodiscard]] status_t transactAddress(const sp<RpcSession::RpcConnection>& connection, - const RpcAddress& address, uint32_t code, - const Parcel& data, const sp<RpcSession>& session, - Parcel* reply, uint32_t flags); + uint64_t address, uint32_t code, const Parcel& data, + const sp<RpcSession>& session, Parcel* reply, + uint32_t flags); [[nodiscard]] status_t sendDecStrong(const sp<RpcSession::RpcConnection>& connection, - const sp<RpcSession>& session, const RpcAddress& address); + const sp<RpcSession>& session, uint64_t address); enum class CommandType { ANY, @@ -99,15 +99,15 @@ public: * ownership to the outgoing binder. */ [[nodiscard]] status_t onBinderLeaving(const sp<RpcSession>& session, const sp<IBinder>& binder, - RpcAddress* outAddress); + uint64_t* outAddress); /** * Called by Parcel for incoming binders. This either returns the refcount * to the process, if this process already has one, or it takes ownership of * that refcount */ - [[nodiscard]] status_t onBinderEntering(const sp<RpcSession>& session, - const RpcAddress& address, sp<IBinder>* out); + [[nodiscard]] status_t onBinderEntering(const sp<RpcSession>& session, uint64_t address, + sp<IBinder>* out); size_t countBinders(); void dump(); @@ -221,15 +221,16 @@ private: // happens, and there is a strong reference to the binder kept by // binderNode, this returns that strong reference, so that it can be // dropped after any locks are removed. - sp<IBinder> tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it); + sp<IBinder> tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it); // true - success // false - session shutdown, halt [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node); std::mutex mNodeMutex; bool mTerminated = false; + uint32_t mNextId = 0; // binders known by both sides of a session - std::map<RpcAddress, BinderNode> mNodeForAddress; + std::map<uint64_t, BinderNode> mNodeForAddress; }; } // namespace android diff --git a/libs/binder/RpcWireFormat.h b/libs/binder/RpcWireFormat.h index 067c4ad551..a87aa074a9 100644 --- a/libs/binder/RpcWireFormat.h +++ b/libs/binder/RpcWireFormat.h @@ -20,18 +20,23 @@ namespace android { #pragma clang diagnostic push #pragma clang diagnostic error "-Wpadded" -enum : uint8_t { - RPC_CONNECTION_OPTION_INCOMING = 0x1, // default is outgoing -}; +constexpr uint8_t RPC_CONNECTION_OPTION_INCOMING = 0x1; // default is outgoing -constexpr uint64_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address -constexpr uint64_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1; +constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address +constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1; struct RpcWireAddress { - uint64_t options; - uint8_t address[32]; + uint32_t options; + uint32_t address; + + static inline RpcWireAddress fromRaw(uint64_t raw) { + return *reinterpret_cast<RpcWireAddress*>(&raw); + } + static inline uint64_t toRaw(RpcWireAddress addr) { + return *reinterpret_cast<uint64_t*>(&addr); + } }; -static_assert(sizeof(RpcWireAddress) == 40); +static_assert(sizeof(RpcWireAddress) == sizeof(uint64_t)); /** * This is sent to an RpcServer in order to request a new connection is created, @@ -39,12 +44,13 @@ static_assert(sizeof(RpcWireAddress) == 40); */ struct RpcConnectionHeader { uint32_t version; // maximum supported by caller - uint8_t reserver0[4]; - RpcWireAddress sessionId; uint8_t options; - uint8_t reserved1[7]; + uint8_t reservered[9]; + // Follows is sessionIdSize bytes. + // if size is 0, this is requesting a new session. + uint16_t sessionIdSize; }; -static_assert(sizeof(RpcConnectionHeader) == 56); +static_assert(sizeof(RpcConnectionHeader) == 16); /** * In response to an RpcConnectionHeader which corresponds to a new session, @@ -122,7 +128,7 @@ struct RpcWireTransaction { uint8_t data[]; }; -static_assert(sizeof(RpcWireTransaction) == 72); +static_assert(sizeof(RpcWireTransaction) == 40); struct RpcWireReply { int32_t status; // transact return diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h index b58cb7e69a..9f2ce1efba 100644 --- a/libs/binder/include/binder/BpBinder.h +++ b/libs/binder/include/binder/BpBinder.h @@ -17,7 +17,6 @@ #pragma once #include <binder/IBinder.h> -#include <binder/RpcAddress.h> #include <utils/KeyedVector.h> #include <utils/Mutex.h> #include <utils/threads.h> @@ -41,7 +40,7 @@ class BpBinder : public IBinder { public: static sp<BpBinder> create(int32_t handle); - static sp<BpBinder> create(const sp<RpcSession>& session, const RpcAddress& address); + static sp<BpBinder> create(const sp<RpcSession>& session, uint64_t address); /** * Return value: @@ -129,7 +128,7 @@ public: int32_t binderHandle() const { return mBinder->binderHandle(); } // valid if isRpcBinder - const RpcAddress& rpcAddress() const { return mBinder->rpcAddress(); } + uint64_t rpcAddress() const { return mBinder->rpcAddress(); } const sp<RpcSession>& rpcSession() const { return mBinder->rpcSession(); } const BpBinder* mBinder; @@ -147,12 +146,12 @@ private: }; struct RpcHandle { sp<RpcSession> session; - RpcAddress address; + uint64_t address; }; using Handle = std::variant<BinderHandle, RpcHandle>; int32_t binderHandle() const; - const RpcAddress& rpcAddress() const; + uint64_t rpcAddress() const; const sp<RpcSession>& rpcSession() const; explicit BpBinder(Handle&& handle); diff --git a/libs/binder/include/binder/RpcAddress.h b/libs/binder/include/binder/RpcAddress.h deleted file mode 100644 index e428908c88..0000000000 --- a/libs/binder/include/binder/RpcAddress.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> - -#include <utils/Errors.h> - -// WARNING: This is a feature which is still in development, and it is subject -// to radical change. Any production use of this may subject your code to any -// number of problems. - -namespace android { - -class Parcel; -struct RpcWireAddress; - -/** - * This class represents an identifier across an RPC boundary. - */ -class RpcAddress { -public: - /** - * The zero address is used for special RPC transactions, but it might also - * be used in conjunction with readFromParcel. - */ - static RpcAddress zero(); - - bool isZero() const; - - /** - * Create a new random address. - */ - static RpcAddress random(bool forServer); - - /** - * Whether this address was created with 'bool forServer' true - */ - bool isForServer() const; - - /** - * Whether this address is one that could be created with this version of - * libbinder. - */ - bool isRecognizedType() const; - - /** - * Creates a new address as a copy of an embedded object. - */ - static RpcAddress fromRawEmbedded(const RpcWireAddress* raw); - const RpcWireAddress& viewRawEmbedded() const; - - bool operator<(const RpcAddress& rhs) const; - std::string toString() const; - - status_t writeToParcel(Parcel* parcel) const; - status_t readFromParcel(const Parcel& parcel); - - ~RpcAddress(); - -private: - RpcAddress(); - - std::shared_ptr<RpcWireAddress> mRawAddr; -}; - -} // namespace android diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h index da1f79b67b..5229cfeb5b 100644 --- a/libs/binder/include/binder/RpcServer.h +++ b/libs/binder/include/binder/RpcServer.h @@ -17,7 +17,6 @@ #include <android-base/unique_fd.h> #include <binder/IBinder.h> -#include <binder/RpcAddress.h> #include <binder/RpcSession.h> #include <binder/RpcTransport.h> #include <utils/Errors.h> @@ -195,7 +194,7 @@ private: std::map<std::thread::id, std::thread> mConnectingThreads; sp<IBinder> mRootObject; wp<IBinder> mRootObjectWeak; - std::map<RpcAddress, sp<RpcSession>> mSessions; + std::map<std::vector<uint8_t>, sp<RpcSession>> mSessions; std::unique_ptr<FdTrigger> mShutdownTrigger; std::condition_variable mShutdownCv; }; diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index a40116fed7..91db637f43 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -17,7 +17,6 @@ #include <android-base/unique_fd.h> #include <binder/IBinder.h> -#include <binder/RpcAddress.h> #include <binder/RpcTransport.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -152,7 +151,7 @@ public: [[nodiscard]] status_t transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); - [[nodiscard]] status_t sendDecStrong(const RpcAddress& address); + [[nodiscard]] status_t sendDecStrong(uint64_t address); ~RpcSession(); @@ -220,19 +219,21 @@ private: static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result); [[nodiscard]] status_t setupClient( - const std::function<status_t(const RpcAddress& sessionId, bool incoming)>& + const std::function<status_t(const std::vector<uint8_t>& sessionId, bool incoming)>& connectAndInit); [[nodiscard]] status_t setupSocketClient(const RpcSocketAddress& address); [[nodiscard]] status_t setupOneSocketConnection(const RpcSocketAddress& address, - const RpcAddress& sessionId, bool incoming); - [[nodiscard]] status_t initAndAddConnection(base::unique_fd fd, const RpcAddress& sessionId, + const std::vector<uint8_t>& sessionId, + bool incoming); + [[nodiscard]] status_t initAndAddConnection(base::unique_fd fd, + const std::vector<uint8_t>& sessionId, bool incoming); [[nodiscard]] status_t addIncomingConnection(std::unique_ptr<RpcTransport> rpcTransport); [[nodiscard]] status_t addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTransport, bool init); [[nodiscard]] bool setForServer(const wp<RpcServer>& server, const wp<RpcSession::EventListener>& eventListener, - const RpcAddress& sessionId); + const std::vector<uint8_t>& sessionId); sp<RpcConnection> assignIncomingConnectionToThisThread( std::unique_ptr<RpcTransport> rpcTransport); [[nodiscard]] bool removeIncomingConnection(const sp<RpcConnection>& connection); @@ -289,7 +290,7 @@ private: sp<WaitForShutdownListener> mShutdownListener; // used for client sessions wp<EventListener> mEventListener; // mForServer if server, mShutdownListener if client - std::optional<RpcAddress> mId; + std::vector<uint8_t> mId; std::unique_ptr<FdTrigger> mShutdownTrigger; |