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

Commit d67deada authored by Yifan Hong's avatar Yifan Hong Committed by Automerger Merge Worker
Browse files

Merge "libbinder: Add inet support." am: 035c3c18 am: fd541684 am: 843f56e1 am: 228e7ea3

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1675165

Change-Id: Iacee3239e0de8d1d43fbc5d2be9d7da44bdb11c4
parents ca5e18dd 228e7ea3
Loading
Loading
Loading
Loading
+75 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,16 @@


#include <binder/RpcConnection.h>
#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/Parcel.h>
#include <binder/Stability.h>
#include <binder/Stability.h>
#include <utils/String8.h>
#include <utils/String8.h>
@@ -25,11 +35,6 @@
#include "RpcState.h"
#include "RpcState.h"
#include "RpcWireFormat.h"
#include "RpcWireFormat.h"


#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#ifdef __GLIBC__
#ifdef __GLIBC__
extern "C" pid_t gettid();
extern "C" pid_t gettid();
#endif
#endif
@@ -41,6 +46,7 @@ extern "C" pid_t gettid();
namespace android {
namespace android {


using base::unique_fd;
using base::unique_fd;
using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>;


RpcConnection::SocketAddress::~SocketAddress() {}
RpcConnection::SocketAddress::~SocketAddress() {}


@@ -120,6 +126,70 @@ bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) {


#endif // __BIONIC__
#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() {
bool RpcConnection::addNullDebuggingClient() {
    unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
    unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));


+10 −0
Original line number Original line Diff line number Diff line
@@ -73,6 +73,16 @@ public:
    [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port);
    [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port);
#endif // __BIONIC__
#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!
     * For debugging!
     *
     *
+14 −4
Original line number Original line Diff line number Diff line
@@ -257,6 +257,7 @@ enum class SocketType {
#ifdef __BIONIC__
#ifdef __BIONIC__
    VSOCK,
    VSOCK,
#endif // __BIONIC__
#endif // __BIONIC__
    INET,
};
};
static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
    switch (info.param) {
    switch (info.param) {
@@ -266,6 +267,8 @@ static inline std::string PrintSocketType(const testing::TestParamInfo<SocketTyp
        case SocketType::VSOCK:
        case SocketType::VSOCK:
            return "vm_socket";
            return "vm_socket";
#endif // __BIONIC__
#endif // __BIONIC__
        case SocketType::INET:
            return "inet_socket";
        default:
        default:
            LOG_ALWAYS_FATAL("Unknown socket type");
            LOG_ALWAYS_FATAL("Unknown socket type");
            return "";
            return "";
@@ -305,6 +308,9 @@ public:
                            CHECK(connection->setupVsockServer(port));
                            CHECK(connection->setupVsockServer(port));
                            break;
                            break;
#endif // __BIONIC__
#endif // __BIONIC__
                        case SocketType::INET:
                            CHECK(connection->setupInetServer(port));
                            break;
                        default:
                        default:
                            LOG_ALWAYS_FATAL("Unknown socket type");
                            LOG_ALWAYS_FATAL("Unknown socket type");
                    }
                    }
@@ -335,6 +341,9 @@ public:
                        if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
                        if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
                        break;
                        break;
#endif // __BIONIC__
#endif // __BIONIC__
                    case SocketType::INET:
                        if (ret.connection->addInetClient("127.0.0.1", port)) goto success;
                        break;
                    default:
                    default:
                        LOG_ALWAYS_FATAL("Unknown socket type");
                        LOG_ALWAYS_FATAL("Unknown socket type");
                }
                }
@@ -852,12 +861,13 @@ TEST_P(BinderRpc, Fds) {
}
}


INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
                        ::testing::Values(SocketType::UNIX
                        ::testing::ValuesIn({
                                SocketType::UNIX,
#ifdef __BIONIC__
#ifdef __BIONIC__
                                          ,
                                SocketType::VSOCK,
                                          SocketType::VSOCK
#endif // __BIONIC__
#endif // __BIONIC__
                                          ),
                                SocketType::INET,
                        }),
                        PrintSocketType);
                        PrintSocketType);


} // namespace android
} // namespace android