]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Host / common / SocketAddress.cpp
1 //===-- SocketAddress.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Note: This file is used on Darwin by debugserver, so it needs to remain as
11 //       self contained as possible, and devoid of references to LLVM unless 
12 //       there is compelling reason.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #if defined(_MSC_VER)
17 #define _WINSOCK_DEPRECATED_NO_WARNINGS
18 #endif
19
20 #include "lldb/Host/SocketAddress.h"
21 #include <stddef.h>
22 #include <stdio.h>
23
24 // C Includes
25 #if !defined(_WIN32)
26 #include <arpa/inet.h>
27 #endif
28
29 #include <assert.h>
30 #include <string.h>
31
32 // C++ Includes
33 // Other libraries and framework includes
34 // Project includes
35 #include "lldb/Host/PosixApi.h"
36
37 // WindowsXP needs an inet_ntop implementation
38 #ifdef _WIN32
39
40 #ifndef INET6_ADDRSTRLEN // might not be defined in older Windows SDKs
41 #define INET6_ADDRSTRLEN 46
42 #endif
43
44 // TODO: implement shortened form "::" for runs of zeros
45 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
46   if (size == 0) {
47     return nullptr;
48   }
49
50   switch (af) {
51   case AF_INET: {
52     {
53       const char *formatted = inet_ntoa(*static_cast<const in_addr *>(src));
54       if (formatted && strlen(formatted) < static_cast<size_t>(size)) {
55         return ::strcpy(dst, formatted);
56       }
57     }
58     return nullptr;
59   case AF_INET6: {
60     char tmp[INET6_ADDRSTRLEN] = {0};
61     const uint16_t *src16 = static_cast<const uint16_t *>(src);
62     int full_size = ::snprintf(
63         tmp, sizeof(tmp), "%x:%x:%x:%x:%x:%x:%x:%x", ntohs(src16[0]),
64         ntohs(src16[1]), ntohs(src16[2]), ntohs(src16[3]), ntohs(src16[4]),
65         ntohs(src16[5]), ntohs(src16[6]), ntohs(src16[7]));
66     if (full_size < static_cast<int>(size)) {
67       return ::strcpy(dst, tmp);
68     }
69     return nullptr;
70   }
71   }
72   }
73   return nullptr;
74 }
75 #endif
76
77 using namespace lldb_private;
78
79 //----------------------------------------------------------------------
80 // SocketAddress constructor
81 //----------------------------------------------------------------------
82 SocketAddress::SocketAddress() { Clear(); }
83
84 SocketAddress::SocketAddress(const struct sockaddr &s) { m_socket_addr.sa = s; }
85
86 SocketAddress::SocketAddress(const struct sockaddr_in &s) {
87   m_socket_addr.sa_ipv4 = s;
88 }
89
90 SocketAddress::SocketAddress(const struct sockaddr_in6 &s) {
91   m_socket_addr.sa_ipv6 = s;
92 }
93
94 SocketAddress::SocketAddress(const struct sockaddr_storage &s) {
95   m_socket_addr.sa_storage = s;
96 }
97
98 SocketAddress::SocketAddress(const struct addrinfo *addr_info) {
99   *this = addr_info;
100 }
101
102 //----------------------------------------------------------------------
103 // SocketAddress copy constructor
104 //----------------------------------------------------------------------
105 SocketAddress::SocketAddress(const SocketAddress &rhs)
106     : m_socket_addr(rhs.m_socket_addr) {}
107
108 //----------------------------------------------------------------------
109 // Destructor
110 //----------------------------------------------------------------------
111 SocketAddress::~SocketAddress() {}
112
113 void SocketAddress::Clear() {
114   memset(&m_socket_addr, 0, sizeof(m_socket_addr));
115 }
116
117 bool SocketAddress::IsValid() const { return GetLength() != 0; }
118
119 static socklen_t GetFamilyLength(sa_family_t family) {
120   switch (family) {
121   case AF_INET:
122     return sizeof(struct sockaddr_in);
123   case AF_INET6:
124     return sizeof(struct sockaddr_in6);
125   }
126   assert(0 && "Unsupported address family");
127   return 0;
128 }
129
130 socklen_t SocketAddress::GetLength() const {
131 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
132   return m_socket_addr.sa.sa_len;
133 #else
134   return GetFamilyLength(GetFamily());
135 #endif
136 }
137
138 socklen_t SocketAddress::GetMaxLength() { return sizeof(sockaddr_t); }
139
140 sa_family_t SocketAddress::GetFamily() const {
141   return m_socket_addr.sa.sa_family;
142 }
143
144 void SocketAddress::SetFamily(sa_family_t family) {
145   m_socket_addr.sa.sa_family = family;
146 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
147   m_socket_addr.sa.sa_len = GetFamilyLength(family);
148 #endif
149 }
150
151 std::string SocketAddress::GetIPAddress() const {
152   char str[INET6_ADDRSTRLEN] = {0};
153   switch (GetFamily()) {
154   case AF_INET:
155     if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv4.sin_addr, str,
156                   sizeof(str)))
157       return str;
158     break;
159   case AF_INET6:
160     if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv6.sin6_addr, str,
161                   sizeof(str)))
162       return str;
163     break;
164   }
165   return "";
166 }
167
168 uint16_t SocketAddress::GetPort() const {
169   switch (GetFamily()) {
170   case AF_INET:
171     return ntohs(m_socket_addr.sa_ipv4.sin_port);
172   case AF_INET6:
173     return ntohs(m_socket_addr.sa_ipv6.sin6_port);
174   }
175   return 0;
176 }
177
178 bool SocketAddress::SetPort(uint16_t port) {
179   switch (GetFamily()) {
180   case AF_INET:
181     m_socket_addr.sa_ipv4.sin_port = htons(port);
182     return true;
183
184   case AF_INET6:
185     m_socket_addr.sa_ipv6.sin6_port = htons(port);
186     return true;
187   }
188   return false;
189 }
190
191 //----------------------------------------------------------------------
192 // SocketAddress assignment operator
193 //----------------------------------------------------------------------
194 const SocketAddress &SocketAddress::operator=(const SocketAddress &rhs) {
195   if (this != &rhs)
196     m_socket_addr = rhs.m_socket_addr;
197   return *this;
198 }
199
200 const SocketAddress &SocketAddress::
201 operator=(const struct addrinfo *addr_info) {
202   Clear();
203   if (addr_info && addr_info->ai_addr && addr_info->ai_addrlen > 0 &&
204       addr_info->ai_addrlen <= sizeof m_socket_addr) {
205     ::memcpy(&m_socket_addr, addr_info->ai_addr, addr_info->ai_addrlen);
206   }
207   return *this;
208 }
209
210 const SocketAddress &SocketAddress::operator=(const struct sockaddr &s) {
211   m_socket_addr.sa = s;
212   return *this;
213 }
214
215 const SocketAddress &SocketAddress::operator=(const struct sockaddr_in &s) {
216   m_socket_addr.sa_ipv4 = s;
217   return *this;
218 }
219
220 const SocketAddress &SocketAddress::operator=(const struct sockaddr_in6 &s) {
221   m_socket_addr.sa_ipv6 = s;
222   return *this;
223 }
224
225 const SocketAddress &SocketAddress::
226 operator=(const struct sockaddr_storage &s) {
227   m_socket_addr.sa_storage = s;
228   return *this;
229 }
230
231 bool SocketAddress::getaddrinfo(const char *host, const char *service,
232                                 int ai_family, int ai_socktype, int ai_protocol,
233                                 int ai_flags) {
234   Clear();
235
236   auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype,
237                                   ai_protocol, ai_flags);
238   if (!addresses.empty())
239     *this = addresses[0];
240   return IsValid();
241 }
242
243 std::vector<SocketAddress>
244 SocketAddress::GetAddressInfo(const char *hostname, const char *servname,
245                               int ai_family, int ai_socktype, int ai_protocol,
246                               int ai_flags) {
247   std::vector<SocketAddress> addr_list;
248
249   struct addrinfo hints;
250   memset(&hints, 0, sizeof(hints));
251   hints.ai_family = ai_family;
252   hints.ai_socktype = ai_socktype;
253   hints.ai_protocol = ai_protocol;
254   hints.ai_flags = ai_flags;
255
256   struct addrinfo *service_info_list = NULL;
257   int err = ::getaddrinfo(hostname, servname, &hints, &service_info_list);
258   if (err == 0 && service_info_list) {
259     for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL;
260          service_ptr = service_ptr->ai_next) {
261       addr_list.emplace_back(SocketAddress(service_ptr));
262     }
263   }
264
265   if (service_info_list)
266     ::freeaddrinfo(service_info_list);
267   return addr_list;
268 }
269
270 bool SocketAddress::SetToLocalhost(sa_family_t family, uint16_t port) {
271   switch (family) {
272   case AF_INET:
273     SetFamily(AF_INET);
274     if (SetPort(port)) {
275       m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
276       return true;
277     }
278     break;
279
280   case AF_INET6:
281     SetFamily(AF_INET6);
282     if (SetPort(port)) {
283       m_socket_addr.sa_ipv6.sin6_addr = in6addr_loopback;
284       return true;
285     }
286     break;
287   }
288   Clear();
289   return false;
290 }
291
292 bool SocketAddress::SetToAnyAddress(sa_family_t family, uint16_t port) {
293   switch (family) {
294   case AF_INET:
295     SetFamily(AF_INET);
296     if (SetPort(port)) {
297       m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
298       return true;
299     }
300     break;
301
302   case AF_INET6:
303     SetFamily(AF_INET6);
304     if (SetPort(port)) {
305       m_socket_addr.sa_ipv6.sin6_addr = in6addr_any;
306       return true;
307     }
308     break;
309   }
310   Clear();
311   return false;
312 }
313
314 bool SocketAddress::IsAnyAddr() const {
315   return (GetFamily() == AF_INET)
316              ? m_socket_addr.sa_ipv4.sin_addr.s_addr == htonl(INADDR_ANY)
317              : 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_any, 16);
318 }
319
320 bool SocketAddress::operator==(const SocketAddress &rhs) const {
321   if (GetFamily() != rhs.GetFamily())
322     return false;
323   if (GetLength() != rhs.GetLength())
324     return false;
325   switch (GetFamily()) {
326   case AF_INET:
327     return m_socket_addr.sa_ipv4.sin_addr.s_addr ==
328            rhs.m_socket_addr.sa_ipv4.sin_addr.s_addr;
329   case AF_INET6:
330     return 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr,
331                        &rhs.m_socket_addr.sa_ipv6.sin6_addr, 16);
332   }
333   return false;
334 }
335
336 bool SocketAddress::operator!=(const SocketAddress &rhs) const {
337   return !(*this == rhs);
338 }