Coverage Report

Created: 2023-09-12 09:32

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