1
#include "source/common/network/address_impl.h"
2

            
3
#include <array>
4
#include <cstdint>
5
#include <string>
6

            
7
#include "envoy/common/exception.h"
8
#include "envoy/common/platform.h"
9

            
10
#include "source/common/common/assert.h"
11
#include "source/common/common/fmt.h"
12
#include "source/common/common/safe_memcpy.h"
13
#include "source/common/common/thread.h"
14
#include "source/common/common/utility.h"
15
#include "source/common/network/socket_interface.h"
16
#include "source/common/runtime/runtime_features.h"
17

            
18
namespace Envoy {
19
namespace Network {
20
namespace Address {
21

            
22
namespace {
23

            
24
// Constructs a readable string with the embedded nulls in the abstract path replaced with '@'.
25
207
std::string friendlyNameFromAbstractPath(absl::string_view path) {
26
207
  std::string friendly_name(path.data(), path.size());
27
207
  std::replace(friendly_name.begin(), friendly_name.end(), '\0', '@');
28
207
  return friendly_name;
29
207
}
30

            
31
3774918
const SocketInterface* sockInterfaceOrDefault(const SocketInterface* sock_interface) {
32
3774918
  return sock_interface == nullptr ? &SocketInterfaceSingleton::get() : sock_interface;
33
3774918
}
34

            
35
} // namespace
36

            
37
3145118
bool forceV6() {
38
#if defined(__APPLE__) || defined(__ANDROID_API__)
39
  return Runtime::runtimeFeatureEnabled("envoy.reloadable_features.always_use_v6");
40
#else
41
3145118
  return false;
42
3145118
#endif
43
3145118
}
44

            
45
5
void ipv6ToIpv4CompatibleAddress(const struct sockaddr_in6* sin6, struct sockaddr_in* sin) {
46
#if defined(__APPLE__)
47
  *sin = {{}, AF_INET, sin6->sin6_port, {sin6->sin6_addr.__u6_addr.__u6_addr32[3]}, {}};
48
#elif defined(WIN32)
49
  struct in_addr in_v4 = {};
50
  in_v4.S_un.S_addr = reinterpret_cast<const uint32_t*>(sin6->sin6_addr.u.Byte)[3];
51
  *sin = {AF_INET, sin6->sin6_port, in_v4, {}};
52
#else
53
5
  *sin = {AF_INET, sin6->sin6_port, {sin6->sin6_addr.s6_addr32[3]}, {}};
54
5
#endif
55
5
}
56

            
57
StatusOr<Address::InstanceConstSharedPtr> addressFromSockAddr(const sockaddr_storage& ss,
58
3048036
                                                              socklen_t ss_len, bool v6only) {
59
3048036
  RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) >= sizeof(sa_family_t), "");
60
3048036
  if (forceV6()) {
61
    v6only = false;
62
  }
63
3048036
  switch (ss.ss_family) {
64
3015305
  case AF_INET: {
65
3015305
    RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in), "");
66
3015305
    const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&ss);
67
3015305
    ASSERT(AF_INET == sin->sin_family);
68
3015305
    return Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(sin);
69
3015305
  }
70
32679
  case AF_INET6: {
71
32679
    RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in6), "");
72
32679
    const struct sockaddr_in6* sin6 = reinterpret_cast<const struct sockaddr_in6*>(&ss);
73
32679
    ASSERT(AF_INET6 == sin6->sin6_family);
74
32679
    if (!v6only && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
75
2
      struct sockaddr_in sin;
76
2
      ipv6ToIpv4CompatibleAddress(sin6, &sin);
77
2
      return Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(&sin);
78
32677
    } else {
79
32677
      return Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(*sin6, v6only);
80
32677
    }
81
32679
  }
82
30
  case AF_UNIX: {
83
30
    const struct sockaddr_un* sun = reinterpret_cast<const struct sockaddr_un*>(&ss);
84
30
    ASSERT(AF_UNIX == sun->sun_family);
85
30
    RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) >=
86
30
                                      offsetof(struct sockaddr_un, sun_path) + 1,
87
30
                   "");
88
30
    return Address::InstanceFactory::createInstancePtr<Address::PipeInstance>(sun, ss_len);
89
30
  }
90
1
  default:
91
1
    return absl::InvalidArgumentError(fmt::format("Unexpected sockaddr family: {}", ss.ss_family));
92
3048036
  }
93
3048036
}
94

            
95
Address::InstanceConstSharedPtr
96
2833992
addressFromSockAddrOrDie(const sockaddr_storage& ss, socklen_t ss_len, os_fd_t fd, bool v6only) {
97
  // Set v6only to false so that mapped-v6 address can be normalize to v4
98
  // address. Though dual stack may be disabled, it's still okay to assume the
99
  // address is from a dual stack socket. This is because mapped-v6 address
100
  // must come from a dual stack socket. An actual v6 address can come from
101
  // both dual stack socket and v6 only socket. If |peer_addr| is an actual v6
102
  // address and the socket is actually v6 only, the returned address will be
103
  // regarded as a v6 address from dual stack socket. However, this address is not going to be
104
  // used to create socket. Wrong knowledge of dual stack support won't hurt.
105
2833992
  StatusOr<Address::InstanceConstSharedPtr> address =
106
2833992
      Address::addressFromSockAddr(ss, ss_len, v6only);
107
2833992
  if (!address.ok()) {
108
    PANIC(fmt::format("Invalid address for fd: {}, error: {}", fd, address.status().ToString()));
109
  }
110
2833992
  return *address;
111
2833992
}
112

            
113
Ipv4Instance::Ipv4Instance(const sockaddr_in* address, const SocketInterface* sock_interface,
114
                           absl::optional<std::string> network_namespace)
115
19472
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
116
19472
      network_namespace_(network_namespace) {
117
19472
  THROW_IF_NOT_OK(validateProtocolSupported());
118
19472
  initHelper(address);
119
19472
}
120

            
121
Ipv4Instance::Ipv4Instance(const std::string& address, const SocketInterface* sock_interface,
122
                           absl::optional<std::string> network_namespace)
123
90093
    : Ipv4Instance(address, 0, sockInterfaceOrDefault(sock_interface), network_namespace) {}
124

            
125
Ipv4Instance::Ipv4Instance(const std::string& address, uint32_t port,
126
                           const SocketInterface* sock_interface,
127
                           absl::optional<std::string> network_namespace)
128
156589
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
129
156589
      network_namespace_(network_namespace) {
130
156589
  THROW_IF_NOT_OK(validateProtocolSupported());
131
156589
  memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
132
156589
  ip_.ipv4_.address_.sin_family = AF_INET;
133
156589
  ip_.ipv4_.address_.sin_port = htons(port);
134
156589
  int rc = inet_pton(AF_INET, address.c_str(), &ip_.ipv4_.address_.sin_addr);
135
156589
  if (1 != rc) {
136
9
    throwEnvoyExceptionOrPanic(fmt::format("invalid ipv4 address '{}'", address));
137
9
  }
138

            
139
156580
  friendly_name_ = absl::StrCat(address, ":", port);
140
156580
  ip_.friendly_address_ = address;
141
156580
}
142

            
143
Ipv4Instance::Ipv4Instance(uint32_t port, const SocketInterface* sock_interface,
144
                           absl::optional<std::string> network_namespace)
145
42008
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
146
42008
      network_namespace_(network_namespace) {
147
42008
  THROW_IF_NOT_OK(validateProtocolSupported());
148
42008
  memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
149
42008
  ip_.ipv4_.address_.sin_family = AF_INET;
150
42008
  ip_.ipv4_.address_.sin_port = htons(port);
151
42008
  ip_.ipv4_.address_.sin_addr.s_addr = INADDR_ANY;
152
42008
  friendly_name_ = absl::StrCat("0.0.0.0:", port);
153
42008
  ip_.friendly_address_ = "0.0.0.0";
154
42008
}
155

            
156
Ipv4Instance::Ipv4Instance(absl::Status& status, const sockaddr_in* address,
157
                           const SocketInterface* sock_interface,
158
                           absl::optional<std::string> network_namespace)
159
3316892
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
160
3316892
      network_namespace_(network_namespace) {
161
3316892
  status = validateProtocolSupported();
162
3316892
  if (!status.ok()) {
163
4
    return;
164
4
  }
165
3316888
  initHelper(address);
166
3316888
}
167

            
168
Ipv4Instance::Ipv4Instance(const Ipv4Instance& that,
169
                           const absl::optional<std::string>& network_namespace)
170
10
    : InstanceBase(Type::Ip, &that.socket_interface_), ip_(that.ip_),
171
10
      network_namespace_(network_namespace) {
172
10
  friendly_name_ = that.friendly_name_;
173
10
}
174

            
175
1146
bool Ipv4Instance::operator==(const Instance& rhs) const {
176
1146
  const Ipv4Instance* rhs_casted = dynamic_cast<const Ipv4Instance*>(&rhs);
177
1146
  return (rhs_casted && (ip_.ipv4_.address() == rhs_casted->ip_.ipv4_.address()) &&
178
1146
          (ip_.port() == rhs_casted->ip_.port()) && (networkNamespace() == rhs.networkNamespace()));
179
1146
}
180

            
181
3335943
std::string Ipv4Instance::sockaddrToString(const sockaddr_in& addr) {
182
3335943
  static constexpr size_t BufferSize = 16; // enough space to hold an IPv4 address in string form
183
3335943
  char str[BufferSize];
184
  // Write backwards from the end of the buffer for simplicity.
185
3335943
  char* start = str + BufferSize;
186
3335943
  uint32_t ipv4_addr = ntohl(addr.sin_addr.s_addr);
187
16677961
  for (unsigned i = 4; i != 0; i--, ipv4_addr >>= 8) {
188
13342018
    uint32_t octet = ipv4_addr & 0xff;
189
13342018
    if (octet == 0) {
190
6732491
      ASSERT(start > str);
191
6732491
      *--start = '0';
192
6755457
    } else {
193
13077358
      do {
194
13077358
        ASSERT(start > str);
195
13077358
        *--start = '0' + (octet % 10);
196
13077358
        octet /= 10;
197
13077358
      } while (octet != 0);
198
6609527
    }
199
13342018
    if (i != 1) {
200
10006822
      ASSERT(start > str);
201
10006822
      *--start = '.';
202
10006822
    }
203
13342018
  }
204
3335943
  const std::string::size_type end = str + BufferSize - start;
205
3335943
  return {start, end};
206
3335943
}
207

            
208
namespace {
209
std::atomic<bool> force_ipv4_unsupported_for_test = false;
210
}
211

            
212
2
Cleanup Ipv4Instance::forceProtocolUnsupportedForTest(bool new_val) {
213
2
  bool old_val = force_ipv4_unsupported_for_test.load();
214
2
  force_ipv4_unsupported_for_test.store(new_val);
215
2
  return {[old_val]() { force_ipv4_unsupported_for_test.store(old_val); }};
216
2
}
217

            
218
3535098
absl::Status Ipv4Instance::validateProtocolSupported() {
219
3535098
  static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET);
220
3535159
  if (supported && !force_ipv4_unsupported_for_test.load(std::memory_order_relaxed)) {
221
3535091
    return absl::OkStatus();
222
3535091
  }
223
47
  return absl::FailedPreconditionError("IPv4 addresses are not supported on this machine");
224
3535098
}
225

            
226
3336084
void Ipv4Instance::initHelper(const sockaddr_in* address) {
227
3336084
  memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
228
3336084
  ip_.ipv4_.address_ = *address;
229
3336084
  ip_.friendly_address_ = sockaddrToString(*address);
230

            
231
  // Based on benchmark testing, this reserve+append implementation runs faster than absl::StrCat.
232
3336084
  fmt::format_int port(ntohs(address->sin_port));
233
3336084
  friendly_name_.reserve(ip_.friendly_address_.size() + 1 + port.size());
234
3336084
  friendly_name_.append(ip_.friendly_address_);
235
3336084
  friendly_name_.push_back(':');
236
3336084
  friendly_name_.append(port.data(), port.size());
237
3336084
}
238

            
239
35723
absl::uint128 Ipv6Instance::Ipv6Helper::address() const {
240
35723
  absl::uint128 result{0};
241
35723
  static_assert(sizeof(absl::uint128) == 16, "The size of absl::uint128 is not 16.");
242
35723
  safeMemcpyUnsafeSrc(&result, &address_.sin6_addr.s6_addr[0]);
243
35723
  return result;
244
35723
}
245

            
246
32
uint32_t Ipv6Instance::Ipv6Helper::scopeId() const { return address_.sin6_scope_id; }
247

            
248
115196
uint32_t Ipv6Instance::Ipv6Helper::port() const { return ntohs(address_.sin6_port); }
249

            
250
1035
bool Ipv6Instance::Ipv6Helper::v6only() const { return v6only_; };
251

            
252
114068
std::string Ipv6Instance::Ipv6Helper::makeFriendlyAddress() const {
253
114068
  return makeFriendlyAddress(address_);
254
114068
}
255

            
256
114077
std::string Ipv6Instance::Ipv6Helper::makeFriendlyAddress(const sockaddr_in6& address) {
257
114077
  char str[INET6_ADDRSTRLEN];
258
114077
  const char* ptr = inet_ntop(AF_INET6, &address.sin6_addr, str, INET6_ADDRSTRLEN);
259
114077
  ASSERT(str == ptr);
260
114077
  if (address.sin6_scope_id != 0) {
261
    // Note that here we don't use the `if_indextoname` that will give a more user friendly
262
    // output just because in the past created a performance bottleneck if the machine had a
263
    // lot of IPv6 Link local addresses.
264
10666
    return absl::StrCat(ptr, "%", address.sin6_scope_id);
265
10666
  }
266
103411
  return ptr;
267
114077
}
268

            
269
4
InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::v4CompatibleAddress() const {
270
4
  if (!v6only_ && IN6_IS_ADDR_V4MAPPED(&address_.sin6_addr)) {
271
3
    struct sockaddr_in sin;
272
3
    ipv6ToIpv4CompatibleAddress(&address_, &sin);
273
3
    auto addr = Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(&sin);
274
3
    return addr.ok() ? addr.value() : nullptr;
275
3
  }
276
1
  return nullptr;
277
4
}
278

            
279
88
InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::addressWithoutScopeId() const {
280
88
  struct sockaddr_in6 ret_addr = address_;
281
88
  ret_addr.sin6_scope_id = 0;
282
88
  auto addr = Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(ret_addr, v6only_);
283
88
  return addr.ok() ? addr.value() : nullptr;
284
88
}
285

            
286
Ipv6Instance::Ipv6Instance(const sockaddr_in6& address, bool v6only,
287
                           const SocketInterface* sock_interface,
288
                           absl::optional<std::string> network_namespace)
289
434
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
290
434
      network_namespace_(network_namespace) {
291
434
  THROW_IF_NOT_OK(validateProtocolSupported());
292
434
  initHelper(address, v6only);
293
434
}
294

            
295
Ipv6Instance::Ipv6Instance(const std::string& address, const SocketInterface* sock_interface,
296
                           absl::optional<std::string> network_namespace)
297
159
    : Ipv6Instance(address, 0, sockInterfaceOrDefault(sock_interface), true /* v6only */,
298
159
                   network_namespace) {}
299

            
300
Ipv6Instance::Ipv6Instance(const std::string& address, uint32_t port,
301
                           const SocketInterface* sock_interface, bool v6only,
302
                           absl::optional<std::string> network_namespace)
303
35198
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
304
35198
      network_namespace_(network_namespace) {
305
35198
  THROW_IF_NOT_OK(validateProtocolSupported());
306
35198
  sockaddr_in6 addr_in;
307
35198
  memset(&addr_in, 0, sizeof(addr_in));
308
35198
  addr_in.sin6_family = AF_INET6;
309
35198
  addr_in.sin6_port = htons(port);
310
35198
  if (!address.empty()) {
311
419
    if (1 != inet_pton(AF_INET6, address.c_str(), &addr_in.sin6_addr)) {
312
4
      throwEnvoyExceptionOrPanic(fmt::format("invalid ipv6 address '{}'", address));
313
4
    }
314
35181
  } else {
315
34779
    addr_in.sin6_addr = in6addr_any;
316
34779
  }
317
35194
  initHelper(addr_in, v6only);
318
35194
}
319

            
320
Ipv6Instance::Ipv6Instance(uint32_t port, const SocketInterface* sock_interface,
321
                           absl::optional<std::string> network_namespace)
322
34779
    : Ipv6Instance("", port, sockInterfaceOrDefault(sock_interface), true /* v6only */,
323
34779
                   network_namespace) {}
324

            
325
46
bool Ipv6Instance::operator==(const Instance& rhs) const {
326
46
  const auto* rhs_casted = dynamic_cast<const Ipv6Instance*>(&rhs);
327
46
  return (rhs_casted && (ip_.ipv6_.address() == rhs_casted->ip_.ipv6_.address()) &&
328
46
          (ip_.port() == rhs_casted->ip_.port()) &&
329
46
          (ip_.ipv6_.scopeId() == rhs_casted->ip_.ipv6_.scopeId()) &&
330
46
          (networkNamespace() == rhs.networkNamespace()));
331
46
}
332

            
333
Ipv6Instance::Ipv6Instance(absl::Status& status, const sockaddr_in6& address, bool v6only,
334
                           const SocketInterface* sock_interface,
335
                           absl::optional<std::string> network_namespace)
336
78444
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
337
78444
      network_namespace_(network_namespace) {
338
78444
  status = validateProtocolSupported();
339
78444
  if (!status.ok()) {
340
4
    return;
341
4
  }
342
78440
  initHelper(address, v6only);
343
78440
}
344

            
345
Ipv6Instance::Ipv6Instance(const Ipv6Instance& that,
346
                           const absl::optional<std::string>& network_namespace)
347
7
    : InstanceBase(Type::Ip, &that.socket_interface_), ip_(that.ip_),
348
7
      network_namespace_(network_namespace) {
349
7
  friendly_name_ = that.friendly_name_;
350
7
}
351

            
352
9
std::string Ipv6Instance::sockaddrToString(const sockaddr_in6& addr) {
353
9
  return Ipv6Helper::makeFriendlyAddress(addr);
354
9
}
355

            
356
namespace {
357
std::atomic<bool> force_ipv6_unsupported_for_test = false;
358
}
359

            
360
3
Cleanup Ipv6Instance::forceProtocolUnsupportedForTest(bool new_val) {
361
3
  bool old_val = force_ipv6_unsupported_for_test.load();
362
3
  force_ipv6_unsupported_for_test.store(new_val);
363
3
  return {[old_val]() { force_ipv6_unsupported_for_test.store(old_val); }};
364
3
}
365

            
366
114076
absl::Status Ipv6Instance::validateProtocolSupported() {
367
114076
  static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET6);
368
114076
  if (supported && !force_ipv6_unsupported_for_test.load(std::memory_order_relaxed)) {
369
114072
    return absl::OkStatus();
370
114072
  }
371
4
  return absl::FailedPreconditionError("IPv6 addresses are not supported on this machine");
372
114076
}
373

            
374
114068
void Ipv6Instance::initHelper(const sockaddr_in6& address, bool v6only) {
375
114068
  ip_.ipv6_.address_ = address;
376
114068
  ip_.friendly_address_ = ip_.ipv6_.makeFriendlyAddress();
377
114068
  ip_.ipv6_.v6only_ = v6only;
378
114068
  friendly_name_ = fmt::format("[{}]:{}", ip_.friendly_address_, ip_.port());
379
114068
}
380

            
381
absl::StatusOr<std::unique_ptr<PipeInstance>>
382
PipeInstance::create(const sockaddr_un* address, socklen_t ss_len, mode_t mode,
383
1
                     const SocketInterface* sock_interface) {
384
1
  absl::Status creation_status = absl::OkStatus();
385
1
  auto ret = std::unique_ptr<PipeInstance>(
386
1
      new PipeInstance(creation_status, address, ss_len, mode, sock_interface));
387
1
  RETURN_IF_NOT_OK(creation_status);
388
  return ret;
389
1
}
390

            
391
absl::StatusOr<std::unique_ptr<PipeInstance>>
392
PipeInstance::create(const std::string& pipe_path, mode_t mode,
393
624
                     const SocketInterface* sock_interface) {
394
624
  absl::Status creation_status = absl::OkStatus();
395
624
  auto ret = std::unique_ptr<PipeInstance>(
396
624
      new PipeInstance(pipe_path, mode, sock_interface, creation_status));
397
624
  RETURN_IF_NOT_OK(creation_status);
398
621
  return ret;
399
624
}
400

            
401
PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode,
402
                           const SocketInterface* sock_interface, absl::Status& creation_status)
403
624
    : InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
404
624
  if (pipe_path.size() >= sizeof(pipe_.address_.sun_path)) {
405
1
    creation_status = absl::InvalidArgumentError(
406
1
        fmt::format("Path \"{}\" exceeds maximum UNIX domain socket path size of {}.", pipe_path,
407
1
                    sizeof(pipe_.address_.sun_path)));
408
1
    return;
409
1
  }
410
623
  memset(&pipe_.address_, 0, sizeof(pipe_.address_));
411
623
  pipe_.address_.sun_family = AF_UNIX;
412
623
  if (pipe_path[0] == '@') {
413
    // This indicates an abstract namespace.
414
    // In this case, null bytes in the name have no special significance, and so we copy all
415
    // characters of pipe_path to sun_path, including null bytes in the name. The pathname must also
416
    // be null terminated. The friendly name is the address path with embedded nulls replaced with
417
    // '@' for consistency with the first character.
418
#if !defined(__linux__)
419
    creation_status =
420
        absl::InvalidArgumentError("Abstract AF_UNIX sockets are only supported on linux.");
421
    return;
422
#endif
423
196
    if (mode != 0) {
424
1
      creation_status = absl::InvalidArgumentError("Cannot set mode for Abstract AF_UNIX sockets");
425
1
      return;
426
1
    }
427
195
    pipe_.abstract_namespace_ = true;
428
195
    pipe_.address_length_ = pipe_path.size();
429
    // The following statement is safe since pipe_path size was checked at the beginning of this
430
    // function
431
195
    memcpy(&pipe_.address_.sun_path[0], pipe_path.data(), pipe_path.size()); // NOLINT(safe-memcpy)
432
195
    pipe_.address_.sun_path[0] = '\0';
433
195
    pipe_.address_.sun_path[pipe_path.size()] = '\0';
434
195
    friendly_name_ = friendlyNameFromAbstractPath(
435
195
        absl::string_view(pipe_.address_.sun_path, pipe_.address_length_));
436
587
  } else {
437
    // return an error if the pipe path has an embedded null character.
438
427
    if (pipe_path.size() != strlen(pipe_path.c_str())) {
439
1
      creation_status = absl::InvalidArgumentError(
440
1
          "UNIX domain socket pathname contains embedded null characters");
441
1
      return;
442
1
    }
443
426
    StringUtil::strlcpy(&pipe_.address_.sun_path[0], pipe_path.c_str(),
444
426
                        sizeof(pipe_.address_.sun_path));
445
426
    friendly_name_ = pipe_.address_.sun_path;
446
426
  }
447
621
  pipe_.mode_ = mode;
448
621
}
449

            
450
PipeInstance::PipeInstance(absl::Status& error, const sockaddr_un* address, socklen_t ss_len,
451
                           mode_t mode, const SocketInterface* sock_interface)
452
31
    : InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
453
31
  if (address->sun_path[0] == '\0') {
454
#if !defined(__linux__)
455
    error = absl::FailedPreconditionError("Abstract AF_UNIX sockets are only supported on linux.");
456
    return;
457
#endif
458
13
    RELEASE_ASSERT(static_cast<unsigned int>(ss_len) >= offsetof(struct sockaddr_un, sun_path) + 1,
459
13
                   "");
460
13
    pipe_.abstract_namespace_ = true;
461
13
    pipe_.address_length_ = ss_len - offsetof(struct sockaddr_un, sun_path);
462
13
  }
463
31
  error = initHelper(address, mode);
464
31
}
465

            
466
23
bool PipeInstance::operator==(const Instance& rhs) const { return asString() == rhs.asString(); }
467

            
468
31
absl::Status PipeInstance::initHelper(const sockaddr_un* address, mode_t mode) {
469
31
  pipe_.address_ = *address;
470
31
  if (pipe_.abstract_namespace_) {
471
13
    if (mode != 0) {
472
1
      return absl::FailedPreconditionError("Cannot set mode for Abstract AF_UNIX sockets");
473
1
    }
474
    // Replace all null characters with '@' in friendly_name_.
475
12
    friendly_name_ = friendlyNameFromAbstractPath(
476
12
        absl::string_view(pipe_.address_.sun_path, pipe_.address_length_));
477
18
  } else {
478
18
    friendly_name_ = address->sun_path;
479
18
  }
480
30
  pipe_.mode_ = mode;
481
30
  return absl::OkStatus();
482
31
}
483

            
484
EnvoyInternalInstance::EnvoyInternalInstance(const std::string& address_id,
485
                                             const std::string& endpoint_id,
486
                                             const SocketInterface* sock_interface)
487
187
    : InstanceBase(Type::EnvoyInternal, sockInterfaceOrDefault(sock_interface)),
488
187
      internal_address_(address_id, endpoint_id) {
489
187
  friendly_name_ = absl::StrCat("envoy://", address_id, "/", endpoint_id);
490
187
}
491

            
492
61
bool EnvoyInternalInstance::operator==(const Instance& rhs) const {
493
61
  return rhs.type() == Type::EnvoyInternal && asString() == rhs.asString();
494
61
}
495

            
496
} // namespace Address
497
} // namespace Network
498
} // namespace Envoy