diff options
author | 2021-04-13 17:38:36 -0700 | |
---|---|---|
committer | 2021-04-19 14:12:15 -0700 | |
commit | 0d2bd11e555bda3d894fbb54b500d89dc702c21c (patch) | |
tree | a68254a28ed41af30f7b1b9081f9fa3ac0dc94ac | |
parent | d0c6510fd326683acbbb6f0044c2222a2361b1d7 (diff) |
libbinder: Add inet support.
Test: binderRpcTest
Bug: 182914638
Change-Id: Idf70050060d708e919ce0e828b58e77aa6032563
-rw-r--r-- | libs/binder/RpcConnection.cpp | 80 | ||||
-rw-r--r-- | libs/binder/include/binder/RpcConnection.h | 10 | ||||
-rw-r--r-- | libs/binder/tests/binderRpcTest.cpp | 18 |
3 files changed, 99 insertions, 9 deletions
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp index 4aff92b58a..22e04666eb 100644 --- a/libs/binder/RpcConnection.cpp +++ b/libs/binder/RpcConnection.cpp @@ -18,6 +18,16 @@ #include <binder/RpcConnection.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> +#include <unistd.h> + +#include <string_view> + #include <binder/Parcel.h> #include <binder/Stability.h> #include <utils/String8.h> @@ -25,11 +35,6 @@ #include "RpcState.h" #include "RpcWireFormat.h" -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/un.h> -#include <unistd.h> - #ifdef __GLIBC__ extern "C" pid_t gettid(); #endif @@ -41,6 +46,7 @@ extern "C" pid_t gettid(); namespace android { using base::unique_fd; +using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>; RpcConnection::SocketAddress::~SocketAddress() {} @@ -120,6 +126,70 @@ bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) { #endif // __BIONIC__ +class SocketAddressImpl : public RpcConnection::SocketAddress { +public: + SocketAddressImpl(const sockaddr* addr, size_t size, const String8& desc) + : mAddr(addr), mSize(size), mDesc(desc) {} + [[nodiscard]] std::string toString() const override { + return std::string(mDesc.c_str(), mDesc.size()); + } + [[nodiscard]] const sockaddr* addr() const override { return mAddr; } + [[nodiscard]] size_t addrSize() const override { return mSize; } + void set(const sockaddr* addr, size_t size) { + mAddr = addr; + mSize = size; + } + +private: + const sockaddr* mAddr = nullptr; + size_t mSize = 0; + String8 mDesc; +}; + +AddrInfo GetAddrInfo(const char* addr, unsigned int port) { + addrinfo hint{ + .ai_flags = 0, + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = 0, + }; + addrinfo* aiStart = nullptr; + if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) { + ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc)); + return AddrInfo(nullptr, nullptr); + } + if (aiStart == nullptr) { + ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port); + return AddrInfo(nullptr, nullptr); + } + return AddrInfo(aiStart, &freeaddrinfo); +} + +bool RpcConnection::setupInetServer(unsigned int port) { + auto aiStart = GetAddrInfo("127.0.0.1", port); + if (aiStart == nullptr) return false; + SocketAddressImpl socketAddress(nullptr, 0, String8::format("127.0.0.1:%u", port)); + for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) { + socketAddress.set(ai->ai_addr, ai->ai_addrlen); + if (setupSocketServer(socketAddress)) return true; + } + ALOGE("None of the socket address resolved for 127.0.0.1:%u can be set up as inet server.", + port); + return false; +} + +bool RpcConnection::addInetClient(const char* addr, unsigned int port) { + auto aiStart = GetAddrInfo(addr, port); + if (aiStart == nullptr) return false; + SocketAddressImpl socketAddress(nullptr, 0, String8::format("%s:%u", addr, port)); + for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) { + socketAddress.set(ai->ai_addr, ai->ai_addrlen); + if (addSocketClient(socketAddress)) return true; + } + ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port); + return false; +} + bool RpcConnection::addNullDebuggingClient() { unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC))); diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h index dba47b4d15..1763d10a8e 100644 --- a/libs/binder/include/binder/RpcConnection.h +++ b/libs/binder/include/binder/RpcConnection.h @@ -74,6 +74,16 @@ public: #endif // __BIONIC__ /** + * Creates an RPC server at the current port. + */ + [[nodiscard]] bool setupInetServer(unsigned int port); + + /** + * Connects to an RPC server at the given address and port. + */ + [[nodiscard]] bool addInetClient(const char* addr, unsigned int port); + + /** * For debugging! * * Sets up an empty socket. All queries to this socket which require a diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp index 33402937ab..ec4ced299b 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -257,6 +257,7 @@ enum class SocketType { #ifdef __BIONIC__ VSOCK, #endif // __BIONIC__ + INET, }; static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) { switch (info.param) { @@ -266,6 +267,8 @@ static inline std::string PrintSocketType(const testing::TestParamInfo<SocketTyp case SocketType::VSOCK: return "vm_socket"; #endif // __BIONIC__ + case SocketType::INET: + return "inet_socket"; default: LOG_ALWAYS_FATAL("Unknown socket type"); return ""; @@ -305,6 +308,9 @@ public: CHECK(connection->setupVsockServer(port)); break; #endif // __BIONIC__ + case SocketType::INET: + CHECK(connection->setupInetServer(port)); + break; default: LOG_ALWAYS_FATAL("Unknown socket type"); } @@ -335,6 +341,9 @@ public: if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success; break; #endif // __BIONIC__ + case SocketType::INET: + if (ret.connection->addInetClient("127.0.0.1", port)) goto success; + break; default: LOG_ALWAYS_FATAL("Unknown socket type"); } @@ -852,12 +861,13 @@ TEST_P(BinderRpc, Fds) { } INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc, - ::testing::Values(SocketType::UNIX + ::testing::ValuesIn({ + SocketType::UNIX, #ifdef __BIONIC__ - , - SocketType::VSOCK + SocketType::VSOCK, #endif // __BIONIC__ - ), + SocketType::INET, + }), PrintSocketType); } // namespace android |