summaryrefslogtreecommitdiff
path: root/libs/binder/RpcState.cpp
diff options
context:
space:
mode:
author Steven Moreland <smoreland@google.com> 2021-06-10 00:40:39 +0000
committer Steven Moreland <smoreland@google.com> 2021-06-10 18:14:42 +0000
commitc88b7fccbbc449d4bd0e371ccf489df0eb401750 (patch)
tree03d6cf688ccbb7209ba9fd540c1cd4816bc0978a /libs/binder/RpcState.cpp
parentada72bd2674ed8e04f6d8aa06803b058bad88560 (diff)
libbinder: RPC know when connections setup
Previously, there was a race where: a. client creates connection to server b. client sends request for reverse connection to server (but this may still be traveling on the wire) c. client sends transaction to server d. server tries to make a callback e. server fails to make callback because no reverse connection is setup Now, when a new connection is setup, a header on this connection is setup. So, we can wait on this header to be received in (b). Note: currently, (e) results in an abort, this is tracked in b/167966510 with a TODO in the ExclusiveConnection code. This would make a less obvious flake (or perhaps the problem would be ignored), but this race still needs to be fixed for well-behaved clients to be able to function reliably. Fixes: 190639665 Test: binderRpcTest (callback test 10,000s of times) Change-Id: I13bc912692d63ea73d46c5441fa7d51121df2f58
Diffstat (limited to 'libs/binder/RpcState.cpp')
-rw-r--r--libs/binder/RpcState.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 62eb58adba..53eba5aea6 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -265,6 +265,27 @@ status_t RpcState::rpcRec(const base::unique_fd& fd, const sp<RpcSession>& sessi
return OK;
}
+status_t RpcState::sendConnectionInit(const base::unique_fd& fd, const sp<RpcSession>& session) {
+ RpcClientConnectionInit init{
+ .msg = RPC_CONNECTION_INIT_OKAY,
+ };
+ return rpcSend(fd, session, "connection init", &init, sizeof(init));
+}
+
+status_t RpcState::readConnectionInit(const base::unique_fd& fd, const sp<RpcSession>& session) {
+ RpcClientConnectionInit init;
+ if (status_t status = rpcRec(fd, session, "connection init", &init, sizeof(init)); status != OK)
+ return status;
+
+ static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY));
+ if (0 != strncmp(init.msg, RPC_CONNECTION_INIT_OKAY, sizeof(init.msg))) {
+ ALOGE("Connection init message unrecognized %.*s", static_cast<int>(sizeof(init.msg)),
+ init.msg);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
sp<IBinder> RpcState::getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session) {
Parcel data;
data.markForRpc(session);