binder: Add RpcTransport class.
RpcTransport represents the transport
layer. The transport layer may have security (TLS) enabled
or not, depending on how it is configured.
In libbinder, RpcTransportRaw implements RpcTransport without TLS.
Add RpcTransportShim that wraps usage of RpcTransport*. If TLS is not
requested, return RpcTranpsortRaw. Otherwise return RpcTransportTls.
RpcTransportTls will be added in follow up CL.
Bug: 190868302
Test: TH
Change-Id: Ic6c6bec4a2135e42f32840dcd5f60b57e57439b5
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 2027b6e..f34672c 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -123,6 +123,7 @@
"RpcSession.cpp",
"RpcServer.cpp",
"RpcState.cpp",
+ "RpcTransportRaw.cpp",
"Static.cpp",
"Stability.cpp",
"Status.cpp",
diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp
new file mode 100644
index 0000000..953d233
--- /dev/null
+++ b/libs/binder/RpcTransportRaw.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "RpcRawTransport"
+#include <log/log.h>
+
+#include <binder/RpcTransportRaw.h>
+
+#include "RpcState.h"
+
+using android::base::ErrnoError;
+using android::base::Result;
+
+namespace android {
+
+namespace {
+
+// RpcTransport with TLS disabled.
+class RpcTransportRaw : public RpcTransport {
+public:
+ explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {}
+ Result<ssize_t> send(const void *buf, int size) override {
+ ssize_t ret = TEMP_FAILURE_RETRY(::send(mSocket.get(), buf, size, MSG_NOSIGNAL));
+ if (ret < 0) {
+ return ErrnoError() << "send()";
+ }
+ return ret;
+ }
+ Result<ssize_t> recv(void *buf, int size) override {
+ ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_NOSIGNAL));
+ if (ret < 0) {
+ return ErrnoError() << "recv()";
+ }
+ return ret;
+ }
+ Result<ssize_t> peek(void *buf, int size) override {
+ ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK | MSG_DONTWAIT));
+ if (ret < 0) {
+ return ErrnoError() << "recv(MSG_PEEK)";
+ }
+ return ret;
+ }
+ bool pending() override { return false; }
+ android::base::borrowed_fd pollSocket() const override { return mSocket; }
+
+private:
+ android::base::unique_fd mSocket;
+};
+
+// RpcTransportCtx with TLS disabled.
+class RpcTransportCtxRaw : public RpcTransportCtx {
+public:
+ std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd) const {
+ return std::make_unique<RpcTransportRaw>(std::move(fd));
+ }
+};
+} // namespace
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newServerCtx() const {
+ return std::make_unique<RpcTransportCtxRaw>();
+}
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newClientCtx() const {
+ return std::make_unique<RpcTransportCtxRaw>();
+}
+
+const char *RpcTransportCtxFactoryRaw::toCString() const {
+ return "raw";
+}
+
+std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryRaw::make() {
+ return std::unique_ptr<RpcTransportCtxFactoryRaw>(new RpcTransportCtxFactoryRaw());
+}
+
+} // namespace android
diff --git a/libs/binder/include/binder/RpcTransport.h b/libs/binder/include/binder/RpcTransport.h
new file mode 100644
index 0000000..1778cae
--- /dev/null
+++ b/libs/binder/include/binder/RpcTransport.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Wraps the transport layer of RPC. Implementation may use plain sockets or TLS.
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+namespace android {
+
+// Represents a socket connection.
+class RpcTransport {
+public:
+ virtual ~RpcTransport() = default;
+
+ // replacement of ::send(). errno may not be set if TLS is enabled.
+ virtual android::base::Result<ssize_t> send(const void *buf, int size) = 0;
+
+ // replacement of ::recv(). errno may not be set if TLS is enabled.
+ virtual android::base::Result<ssize_t> recv(void *buf, int size) = 0;
+
+ // replacement of ::recv(MSG_PEEK). errno may not be set if TLS is enabled.
+ //
+ // Implementation details:
+ // - For TLS, this may invoke syscalls and read data from the transport
+ // into an internal buffer in userspace. After that, pending() == true.
+ // - For raw sockets, this calls ::recv(MSG_PEEK), which leaves the data in the kernel buffer;
+ // pending() is always false.
+ virtual android::base::Result<ssize_t> peek(void *buf, int size) = 0;
+
+ // Returns true if there are data pending in a userspace buffer that RpcTransport holds.
+ //
+ // Implementation details:
+ // - For TLS, this does not invoke any syscalls or read any data from the
+ // transport. This only returns whether there are data pending in the internal buffer in
+ // userspace.
+ // - For raw sockets, this always returns false.
+ virtual bool pending() = 0;
+
+ // Returns fd for polling.
+ //
+ // Do not directly read / write on this raw fd!
+ [[nodiscard]] virtual android::base::borrowed_fd pollSocket() const = 0;
+
+protected:
+ RpcTransport() = default;
+};
+
+// Represents the context that generates the socket connection.
+class RpcTransportCtx {
+public:
+ virtual ~RpcTransportCtx() = default;
+ [[nodiscard]] virtual std::unique_ptr<RpcTransport> newTransport(
+ android::base::unique_fd fd) const = 0;
+
+protected:
+ RpcTransportCtx() = default;
+};
+
+// A factory class that generates RpcTransportCtx.
+class RpcTransportCtxFactory {
+public:
+ virtual ~RpcTransportCtxFactory() = default;
+ // Creates server context.
+ [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newServerCtx() const = 0;
+
+ // Creates client context.
+ [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newClientCtx() const = 0;
+
+ // Return a short description of this transport (e.g. "raw"). For logging / debugging / testing
+ // only.
+ [[nodiscard]] virtual const char *toCString() const = 0;
+
+protected:
+ RpcTransportCtxFactory() = default;
+};
+
+} // namespace android
diff --git a/libs/binder/include/binder/RpcTransportRaw.h b/libs/binder/include/binder/RpcTransportRaw.h
new file mode 100644
index 0000000..6fb1f92
--- /dev/null
+++ b/libs/binder/include/binder/RpcTransportRaw.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Wraps the transport layer of RPC. Implementation uses plain sockets.
+// Note: don't use directly. You probably want newServerRpcTransportCtx / newClientRpcTransportCtx.
+
+#pragma once
+
+#include <memory>
+
+#include <binder/RpcTransport.h>
+
+namespace android {
+
+// RpcTransportCtxFactory with TLS disabled.
+class RpcTransportCtxFactoryRaw : public RpcTransportCtxFactory {
+public:
+ static std::unique_ptr<RpcTransportCtxFactory> make();
+
+ std::unique_ptr<RpcTransportCtx> newServerCtx() const override;
+ std::unique_ptr<RpcTransportCtx> newClientCtx() const override;
+ const char* toCString() const override;
+
+private:
+ RpcTransportCtxFactoryRaw() = default;
+};
+
+} // namespace android