| Steven Moreland | 611d15f | 2021-05-01 01:28:27 +0000 | [diff] [blame] | 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 |  | 
| Steven Moreland | bd5002b | 2021-05-04 23:12:56 +0000 | [diff] [blame] | 27 | #include "vm_sockets.h" | 
| Steven Moreland | 611d15f | 2021-05-01 01:28:27 +0000 | [diff] [blame] | 28 |  | 
|  | 29 | namespace android { | 
|  | 30 |  | 
|  | 31 | class RpcSocketAddress { | 
|  | 32 | public: | 
|  | 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: | 
|  | 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 | } | 
|  | 47 | virtual ~UnixSocketAddress() {} | 
|  | 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 | } | 
|  | 53 | const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } | 
|  | 54 | size_t addrSize() const override { return sizeof(mAddr); } | 
|  | 55 |  | 
|  | 56 | private: | 
|  | 57 | sockaddr_un mAddr; | 
|  | 58 | }; | 
|  | 59 |  | 
| Steven Moreland | 611d15f | 2021-05-01 01:28:27 +0000 | [diff] [blame] | 60 | class VsockSocketAddress : public RpcSocketAddress { | 
|  | 61 | public: | 
|  | 62 | VsockSocketAddress(unsigned int cid, unsigned int port) | 
|  | 63 | : mAddr({ | 
|  | 64 | .svm_family = AF_VSOCK, | 
|  | 65 | .svm_port = port, | 
|  | 66 | .svm_cid = cid, | 
|  | 67 | }) {} | 
|  | 68 | virtual ~VsockSocketAddress() {} | 
|  | 69 | std::string toString() const override { | 
|  | 70 | return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str(); | 
|  | 71 | } | 
|  | 72 | const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); } | 
|  | 73 | size_t addrSize() const override { return sizeof(mAddr); } | 
|  | 74 |  | 
|  | 75 | private: | 
|  | 76 | sockaddr_vm mAddr; | 
|  | 77 | }; | 
|  | 78 |  | 
| Steven Moreland | 611d15f | 2021-05-01 01:28:27 +0000 | [diff] [blame] | 79 | class InetSocketAddress : public RpcSocketAddress { | 
|  | 80 | public: | 
|  | 81 | InetSocketAddress(const sockaddr* sockAddr, size_t size, const char* addr, unsigned int port) | 
|  | 82 | : mSockAddr(sockAddr), mSize(size), mAddr(addr), mPort(port) {} | 
|  | 83 | [[nodiscard]] std::string toString() const override { | 
|  | 84 | return String8::format("%s:%u", mAddr, mPort).c_str(); | 
|  | 85 | } | 
|  | 86 | [[nodiscard]] const sockaddr* addr() const override { return mSockAddr; } | 
|  | 87 | [[nodiscard]] size_t addrSize() const override { return mSize; } | 
|  | 88 |  | 
|  | 89 | using AddrInfo = std::unique_ptr<addrinfo, decltype(&freeaddrinfo)>; | 
|  | 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 |