xref: /aosp_15_r20/frameworks/native/libs/binder/RpcSocketAddress.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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