1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <string> 19 20 #include <arpa/inet.h> 21 #include <netdb.h> 22 #include <netinet/in.h> 23 #include <sys/socket.h> 24 #include <sys/types.h> 25 #include <sys/un.h> 26 27 #include "vm_sockets.h" 28 29 namespace android { 30 31 class RpcSocketAddress { 32 public: ~RpcSocketAddress()33 virtual ~RpcSocketAddress() {} 34 virtual std::string toString() const = 0; 35 virtual const sockaddr* addr() const = 0; 36 virtual size_t addrSize() const = 0; 37 }; 38 39 class UnixSocketAddress : public RpcSocketAddress { 40 public: UnixSocketAddress(const char * path)41 explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) { 42 unsigned int pathLen = strlen(path) + 1; 43 LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s", 44 pathLen, path); 45 memcpy(mAddr.sun_path, path, pathLen); 46 } ~UnixSocketAddress()47 virtual ~UnixSocketAddress() {} toString()48 std::string toString() const override { 49 return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)), 50 mAddr.sun_path) 51 .c_str(); 52 } addr()53 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } addrSize()54 size_t addrSize() const override { return sizeof(mAddr); } 55 56 private: 57 sockaddr_un mAddr; 58 }; 59 60 class VsockSocketAddress : public RpcSocketAddress { 61 public: VsockSocketAddress(unsigned int cid,unsigned int port)62 VsockSocketAddress(unsigned int cid, unsigned int port) 63 : mAddr({ 64 .svm_family = AF_VSOCK, 65 .svm_port = port, 66 .svm_cid = cid, 67 }) {} ~VsockSocketAddress()68 virtual ~VsockSocketAddress() {} toString()69 std::string toString() const override { 70 return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str(); 71 } addr()72 const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } addrSize()73 size_t addrSize() const override { return sizeof(mAddr); } 74 75 private: 76 sockaddr_vm mAddr; 77 }; 78 79 class InetSocketAddress : public RpcSocketAddress { 80 public: InetSocketAddress(const sockaddr * sockAddr,size_t size,const char * addr,unsigned int port)81 InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port) 82 : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {} toString()83 [[nodiscard]] std::string toString() const override { 84 return String8::format("%s:%u", mAddr, mPort).c_str(); 85 } addr()86 [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; } addrSize()87 [[nodiscard]] size_t addrSize() const override { return mSize; } 88 89 using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>; getAddrInfo(const char * addr,unsigned int port)90 static AddrInfo getAddrInfo(const char* addr, unsigned int port) { 91 addrinfo hint{ 92 .ai_flags = 0, 93 .ai_family = AF_UNSPEC, 94 .ai_socktype = SOCK_STREAM, 95 .ai_protocol = 0, 96 }; 97 addrinfo* aiStart = nullptr; 98 if (int rc = getaddrinfo(addr, std::to_string(port).data(), &hint, &aiStart); 0 != rc) { 99 ALOGE("Unable to resolve %s:%u: %s", addr, port, gai_strerror(rc)); 100 return AddrInfo(nullptr, nullptr); 101 } 102 if (aiStart == nullptr) { 103 ALOGE("Unable to resolve %s:%u: getaddrinfo returns null", addr, port); 104 return AddrInfo(nullptr, nullptr); 105 } 106 return AddrInfo(aiStart, &freeaddrinfo); 107 } 108 109 private: 110 const sockaddr* mSockAddr; 111 size_t mSize; 112 const char* mAddr; 113 unsigned int mPort; 114 }; 115 116 } // namespace android 117