]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/jaeger-client-cpp/src/jaegertracing/net/IPAddress.h
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / jaeger-client-cpp / src / jaegertracing / net / IPAddress.h
1 /*
2 * Copyright (c) 2017 Uber Technologies, Inc.
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
17 #ifndef JAEGERTRACING_NET_IPADDRESS_H
18 #define JAEGERTRACING_NET_IPADDRESS_H
19
20
21 #include <array>
22 #include <cassert>
23 #include <cstring>
24 #include <functional>
25 #include <memory>
26 #include <sstream>
27 #include <stdexcept>
28 #include <system_error>
29 #include <vector>
30
31 #include "jaegertracing/Compilers.h"
32
33 #ifdef WIN32
34 #include <winsock2.h>
35 #include <iphlpapi.h>
36 #include <ws2tcpip.h>
37 #include <windows.h>
38 #else
39 #include <arpa/inet.h>
40 #include <netdb.h>
41 #include <sys/socket.h>
42 #include <sys/types.h>
43 #include <unistd.h>
44 #endif
45
46
47
48
49 struct ifaddrs;
50
51 namespace jaegertracing {
52 namespace net {
53
54 class IPAddress {
55 public:
56 static std::pair<std::string, int> parse(const std::string& hostPort)
57 {
58 const auto colonPos = hostPort.find(':');
59 const auto ip = hostPort.substr(0, colonPos);
60 int port = 0;
61 if (colonPos != std::string::npos) {
62 const auto portStr = hostPort.substr(colonPos + 1);
63 std::istringstream iss(portStr);
64 if (!(iss >> port)) {
65 port = 0;
66 }
67 }
68 return std::make_pair(ip, port);
69 }
70
71 static IPAddress v4(const std::string& hostPort)
72 {
73 auto result = parse(hostPort);
74 return v4(result.first, result.second);
75 }
76
77 static IPAddress v4(const std::string& ip, int port)
78 {
79 return versionFromString(ip, port, AF_INET);
80 }
81
82 static IPAddress v6(const std::string& ip, int port)
83 {
84 return versionFromString(ip, port, AF_INET6);
85 }
86
87 static IPAddress localIP(int family);
88
89 IPAddress()
90 : _addr()
91 , _addrLen(sizeof(::sockaddr_in))
92 {
93 std::memset(&_addr, 0, sizeof(_addr));
94 }
95
96 IPAddress(const ::sockaddr_storage& addr, ::socklen_t addrLen)
97 : _addr(addr)
98 , _addrLen(addrLen)
99 {
100 }
101
102 IPAddress(const ::sockaddr& addr, ::socklen_t addrLen)
103 : IPAddress()
104 {
105 std::memcpy(&_addr, &addr, addrLen);
106 }
107
108 explicit IPAddress(const ::sockaddr_in& addr)
109 : IPAddress(reinterpret_cast<const ::sockaddr&>(addr), sizeof(addr))
110 {
111 }
112
113 explicit IPAddress(const ::sockaddr_in6& addr)
114 : IPAddress(reinterpret_cast<const ::sockaddr&>(addr), sizeof(addr))
115 {
116 }
117
118 bool operator==(const IPAddress& rhs) const
119 {
120 if (_addrLen != rhs._addrLen) {
121 return false;
122 }
123 return std::memcmp(&_addr, &rhs._addr, _addrLen) == 0;
124 }
125
126 const ::sockaddr_storage& addr() const { return _addr; }
127
128 ::socklen_t addrLen() const { return _addrLen; }
129
130 void print(std::ostream& out) const
131 {
132 out << "{ family=" << family();
133 const auto addrStr = host();
134 if (!addrStr.empty()) {
135 out << ", addr=" << addrStr;
136 }
137 out << ", port=" << port() << " }";
138 }
139
140 std::string authority() const
141 {
142 const auto portNum = port();
143 if (portNum != 0) {
144 return host() + ':' + std::to_string(portNum);
145 }
146 return host();
147 }
148
149 std::string host() const
150 {
151 std::array<char, INET6_ADDRSTRLEN> buffer;
152 const auto af = family();
153 const auto* addrStr = ::inet_ntop(
154 af,
155 af == AF_INET
156 ? const_cast<void*>(
157 static_cast<const void*>(
158 &reinterpret_cast<const ::sockaddr_in&>(_addr).sin_addr))
159 : const_cast<void*>(
160 static_cast<const void*>(
161 &reinterpret_cast<const ::sockaddr_in6&>(_addr).sin6_addr)),
162 &buffer[0],
163 buffer.size());
164 return addrStr ? addrStr : "";
165 }
166
167 int port() const
168 {
169 if (family() == AF_INET) {
170 return ntohs(
171 reinterpret_cast<const ::sockaddr_in&>(_addr).sin_port);
172 }
173 return ntohs(reinterpret_cast<const ::sockaddr_in6&>(_addr).sin6_port);
174 }
175
176 int family() const
177 {
178 if (_addrLen == sizeof(::sockaddr_in)) {
179 return AF_INET;
180 }
181 assert(_addrLen == sizeof(::sockaddr_in6));
182 return AF_INET6;
183 }
184
185 private:
186 static IPAddress versionFromString(const std::string& ip, int port, int family);
187
188 ::sockaddr_storage _addr;
189 ::socklen_t _addrLen;
190 };
191
192 struct AddrInfoDeleter : public std::function<void(::addrinfo*)> {
193 void operator()(::addrinfo* addrInfo) const { ::freeaddrinfo(addrInfo); }
194 };
195
196 std::unique_ptr<::addrinfo, AddrInfoDeleter> resolveAddress(
197 const std::string& host, int port, int family, int type = SOCK_STREAM);
198
199 } // namespace net
200 } // namespace jaegertracing
201
202 inline std::ostream& operator<<(std::ostream& out,
203 const jaegertracing::net::IPAddress& addr)
204 {
205 addr.print(out);
206 return out;
207 }
208
209 #endif // JAEGERTRACING_NET_IPADDRESS_H