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
3793931
const SocketInterface* sockInterfaceOrDefault(const SocketInterface* sock_interface) {
32
3793931
  return sock_interface == nullptr ? &SocketInterfaceSingleton::get() : sock_interface;
33
3793931
}
34

            
35
} // namespace
36

            
37
3163422
bool forceV6() {
38
#if defined(__APPLE__) || defined(__ANDROID_API__)
39
  return Runtime::runtimeFeatureEnabled("envoy.reloadable_features.always_use_v6");
40
#else
41
3163422
  return false;
42
3163422
#endif
43
3163422
}
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
3066380
                                                              socklen_t ss_len, bool v6only) {
59
3066380
  RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) >= sizeof(sa_family_t), "");
60
3066380
  if (forceV6()) {
61
    v6only = false;
62
  }
63
3066380
  switch (ss.ss_family) {
64
3033592
  case AF_INET: {
65
3033592
    RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in), "");
66
3033592
    const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&ss);
67
3033592
    ASSERT(AF_INET == sin->sin_family);
68
3033592
    return Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(sin);
69
3033592
  }
70
32727
  case AF_INET6: {
71
32727
    RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in6), "");
72
32727
    const struct sockaddr_in6* sin6 = reinterpret_cast<const struct sockaddr_in6*>(&ss);
73
32727
    ASSERT(AF_INET6 == sin6->sin6_family);
74
32727
    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
32725
    } else {
79
32725
      return Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(*sin6, v6only);
80
32725
    }
81
32727
  }
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
3066380
  }
93
3066380
}
94

            
95
Address::InstanceConstSharedPtr
96
2852615
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
2852615
  StatusOr<Address::InstanceConstSharedPtr> address =
106
2852615
      Address::addressFromSockAddr(ss, ss_len, v6only);
107
2852615
  if (!address.ok()) {
108
    PANIC(fmt::format("Invalid address for fd: {}, error: {}", fd, address.status().ToString()));
109
  }
110
2852615
  return *address;
111
2852615
}
112

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

            
121
Ipv4Instance::Ipv4Instance(const std::string& address, const SocketInterface* sock_interface,
122
                           absl::optional<std::string> network_namespace)
123
90130
    : 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
156638
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
129
156638
      network_namespace_(network_namespace) {
130
156638
  THROW_IF_NOT_OK(validateProtocolSupported());
131
156638
  memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
132
156638
  ip_.ipv4_.address_.sin_family = AF_INET;
133
156638
  ip_.ipv4_.address_.sin_port = htons(port);
134
156638
  int rc = inet_pton(AF_INET, address.c_str(), &ip_.ipv4_.address_.sin_addr);
135
156638
  if (1 != rc) {
136
9
    throwEnvoyExceptionOrPanic(fmt::format("invalid ipv4 address '{}'", address));
137
9
  }
138

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

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

            
156
Ipv4Instance::Ipv4Instance(absl::Status& status, const sockaddr_in* address,
157
                           const SocketInterface* sock_interface,
158
                           absl::optional<std::string> network_namespace)
159
3335455
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
160
3335455
      network_namespace_(network_namespace) {
161
3335455
  status = validateProtocolSupported();
162
3335455
  if (!status.ok()) {
163
4
    return;
164
4
  }
165
3335451
  initHelper(address);
166
3335451
}
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
1144
bool Ipv4Instance::operator==(const Instance& rhs) const {
176
1144
  const Ipv4Instance* rhs_casted = dynamic_cast<const Ipv4Instance*>(&rhs);
177
1144
  return (rhs_casted && (ip_.ipv4_.address() == rhs_casted->ip_.ipv4_.address()) &&
178
1144
          (ip_.port() == rhs_casted->ip_.port()) && (networkNamespace() == rhs.networkNamespace()));
179
1144
}
180

            
181
3354696
std::string Ipv4Instance::sockaddrToString(const sockaddr_in& addr) {
182
3354696
  static constexpr size_t BufferSize = 16; // enough space to hold an IPv4 address in string form
183
3354696
  char str[BufferSize];
184
  // Write backwards from the end of the buffer for simplicity.
185
3354696
  char* start = str + BufferSize;
186
3354696
  uint32_t ipv4_addr = ntohl(addr.sin_addr.s_addr);
187
16772112
  for (unsigned i = 4; i != 0; i--, ipv4_addr >>= 8) {
188
13417416
    uint32_t octet = ipv4_addr & 0xff;
189
13417416
    if (octet == 0) {
190
6770049
      ASSERT(start > str);
191
6770049
      *--start = '0';
192
6793033
    } else {
193
13152962
      do {
194
13152962
        ASSERT(start > str);
195
13152962
        *--start = '0' + (octet % 10);
196
13152962
        octet /= 10;
197
13152962
      } while (octet != 0);
198
6647367
    }
199
13417416
    if (i != 1) {
200
10063359
      ASSERT(start > str);
201
10063359
      *--start = '.';
202
10063359
    }
203
13417416
  }
204
3354696
  const std::string::size_type end = str + BufferSize - start;
205
3354696
  return {start, end};
206
3354696
}
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
3553706
absl::Status Ipv4Instance::validateProtocolSupported() {
219
3553706
  static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET);
220
3553817
  if (supported && !force_ipv4_unsupported_for_test.load(std::memory_order_relaxed)) {
221
3553764
    return absl::OkStatus();
222
3553764
  }
223
40
  return absl::FailedPreconditionError("IPv4 addresses are not supported on this machine");
224
3553706
}
225

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

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

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

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

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

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

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

            
256
114289
std::string Ipv6Instance::Ipv6Helper::makeFriendlyAddress(const sockaddr_in6& address) {
257
114289
  char str[INET6_ADDRSTRLEN];
258
114289
  const char* ptr = inet_ntop(AF_INET6, &address.sin6_addr, str, INET6_ADDRSTRLEN);
259
114289
  ASSERT(str == ptr);
260
114289
  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
10682
    return absl::StrCat(ptr, "%", address.sin6_scope_id);
265
10682
  }
266
103607
  return ptr;
267
114289
}
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
474
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
290
474
      network_namespace_(network_namespace) {
291
474
  THROW_IF_NOT_OK(validateProtocolSupported());
292
474
  initHelper(address, v6only);
293
474
}
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
35234
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
304
35234
      network_namespace_(network_namespace) {
305
35234
  THROW_IF_NOT_OK(validateProtocolSupported());
306
35234
  sockaddr_in6 addr_in;
307
35234
  memset(&addr_in, 0, sizeof(addr_in));
308
35234
  addr_in.sin6_family = AF_INET6;
309
35234
  addr_in.sin6_port = htons(port);
310
35234
  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
35217
  } else {
315
34815
    addr_in.sin6_addr = in6addr_any;
316
34815
  }
317
35230
  initHelper(addr_in, v6only);
318
35230
}
319

            
320
Ipv6Instance::Ipv6Instance(uint32_t port, const SocketInterface* sock_interface,
321
                           absl::optional<std::string> network_namespace)
322
34815
    : Ipv6Instance("", port, sockInterfaceOrDefault(sock_interface), true /* v6only */,
323
34815
                   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
78580
    : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)),
337
78580
      network_namespace_(network_namespace) {
338
78580
  status = validateProtocolSupported();
339
78580
  if (!status.ok()) {
340
4
    return;
341
4
  }
342
78576
  initHelper(address, v6only);
343
78576
}
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
114288
absl::Status Ipv6Instance::validateProtocolSupported() {
367
114288
  static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET6);
368
114288
  if (supported && !force_ipv6_unsupported_for_test.load(std::memory_order_relaxed)) {
369
114284
    return absl::OkStatus();
370
114284
  }
371
4
  return absl::FailedPreconditionError("IPv6 addresses are not supported on this machine");
372
114288
}
373

            
374
114280
void Ipv6Instance::initHelper(const sockaddr_in6& address, bool v6only) {
375
114280
  ip_.ipv6_.address_ = address;
376
114280
  ip_.friendly_address_ = ip_.ipv6_.makeFriendlyAddress();
377
114280
  ip_.ipv6_.v6only_ = v6only;
378
114280
  friendly_name_ = fmt::format("[{}]:{}", ip_.friendly_address_, ip_.port());
379
114280
}
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