|  | /* | 
|  | * 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. | 
|  | */ | 
|  | #pragma once | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include <arpa/inet.h> | 
|  | #include <netdb.h> | 
|  | #include <netinet/in.h> | 
|  | #include <sys/socket.h> | 
|  | #include <sys/types.h> | 
|  | #include <sys/un.h> | 
|  |  | 
|  | #include "vm_sockets.h" | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | class RpcSocketAddress { | 
|  | public: | 
|  | virtual ~RpcSocketAddress() {} | 
|  | virtual std::string toString() const = 0; | 
|  | virtual const sockaddr* addr() const = 0; | 
|  | virtual size_t addrSize() const = 0; | 
|  | }; | 
|  |  | 
|  | class UnixSocketAddress : public RpcSocketAddress { | 
|  | public: | 
|  | explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) { | 
|  | unsigned int pathLen = strlen(path) + 1; | 
|  | LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s", | 
|  | pathLen, path); | 
|  | memcpy(mAddr.sun_path, path, pathLen); | 
|  | } | 
|  | virtual ~UnixSocketAddress() {} | 
|  | std::string toString() const override { | 
|  | return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)), | 
|  | mAddr.sun_path) | 
|  | .c_str(); | 
|  | } | 
|  | const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } | 
|  | size_t addrSize() const override { return sizeof(mAddr); } | 
|  |  | 
|  | private: | 
|  | sockaddr_un mAddr; | 
|  | }; | 
|  |  | 
|  | class VsockSocketAddress : public RpcSocketAddress { | 
|  | public: | 
|  | VsockSocketAddress(unsigned int cid, unsigned int port) | 
|  | : mAddr({ | 
|  | .svm_family = AF_VSOCK, | 
|  | .svm_port = port, | 
|  | .svm_cid = cid, | 
|  | }) {} | 
|  | virtual ~VsockSocketAddress() {} | 
|  | std::string toString() const override { | 
|  | return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str(); | 
|  | } | 
|  | const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } | 
|  | size_t addrSize() const override { return sizeof(mAddr); } | 
|  |  | 
|  | private: | 
|  | sockaddr_vm mAddr; | 
|  | }; | 
|  |  | 
|  | class InetSocketAddress : public RpcSocketAddress { | 
|  | public: | 
|  | InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port) | 
|  | : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {} | 
|  | [[nodiscard]] std::string toString() const override { | 
|  | return String8::format("%s:%u", mAddr, mPort).c_str(); | 
|  | } | 
|  | [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; } | 
|  | [[nodiscard]] size_t addrSize() const override { return mSize; } | 
|  |  | 
|  | using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>; | 
|  | static 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); | 
|  | } | 
|  |  | 
|  | private: | 
|  | const sockaddr* mSockAddr; | 
|  | size_t mSize; | 
|  | const char* mAddr; | 
|  | unsigned int mPort; | 
|  | }; | 
|  |  | 
|  | } // namespace android |