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