LCOV - code coverage report
Current view: top level - source/common/network - address_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 202 304 66.4 %
Date: 2024-01-05 06:35:25 Functions: 28 40 70.0 %

          Line data    Source code
       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          74 : std::string friendlyNameFromAbstractPath(absl::string_view path) {
      26          74 :   std::string friendly_name(path.data(), path.size());
      27          74 :   std::replace(friendly_name.begin(), friendly_name.end(), '\0', '@');
      28          74 :   return friendly_name;
      29          74 : }
      30             : 
      31      204131 : const SocketInterface* sockInterfaceOrDefault(const SocketInterface* sock_interface) {
      32      204131 :   return sock_interface == nullptr ? &SocketInterfaceSingleton::get() : sock_interface;
      33      204131 : }
      34             : 
      35        8315 : void throwOnError(absl::Status status) {
      36        8315 :   if (!status.ok()) {
      37           0 :     throwEnvoyExceptionOrPanic(status.ToString());
      38           0 :   }
      39        8315 : }
      40             : 
      41        3439 : InstanceConstSharedPtr throwOnError(StatusOr<InstanceConstSharedPtr> address) {
      42        3439 :   if (!address.ok()) {
      43           0 :     throwOnError(address.status());
      44           0 :   }
      45        3439 :   return *address;
      46        3439 : }
      47             : 
      48             : } // namespace
      49             : 
      50        7915 : bool forceV6() {
      51             : #if defined(__APPLE__) || defined(__ANDROID_API__)
      52             :   return Runtime::runtimeFeatureEnabled("envoy.reloadable_features.always_use_v6");
      53             : #else
      54        7915 :   return false;
      55        7915 : #endif
      56        7915 : }
      57             : 
      58           0 : void ipv6ToIpv4CompatibleAddress(const struct sockaddr_in6* sin6, struct sockaddr_in* sin) {
      59             : #if defined(__APPLE__)
      60             :   *sin = {{}, AF_INET, sin6->sin6_port, {sin6->sin6_addr.__u6_addr.__u6_addr32[3]}, {}};
      61             : #elif defined(WIN32)
      62             :   struct in_addr in_v4 = {};
      63             :   in_v4.S_un.S_addr = reinterpret_cast<const uint32_t*>(sin6->sin6_addr.u.Byte)[3];
      64             :   *sin = {AF_INET, sin6->sin6_port, in_v4, {}};
      65             : #else
      66           0 :   *sin = {AF_INET, sin6->sin6_port, {sin6->sin6_addr.s6_addr32[3]}, {}};
      67           0 : #endif
      68           0 : }
      69             : 
      70             : StatusOr<Address::InstanceConstSharedPtr> addressFromSockAddr(const sockaddr_storage& ss,
      71        5275 :                                                               socklen_t ss_len, bool v6only) {
      72        5275 :   RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) >= sizeof(sa_family_t), "");
      73        5275 :   if (forceV6()) {
      74           0 :     v6only = false;
      75           0 :   }
      76        5275 :   switch (ss.ss_family) {
      77        5071 :   case AF_INET: {
      78        5071 :     RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in), "");
      79        5071 :     const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&ss);
      80        5071 :     ASSERT(AF_INET == sin->sin_family);
      81        5071 :     return Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(sin);
      82        5071 :   }
      83         204 :   case AF_INET6: {
      84         204 :     RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) == sizeof(sockaddr_in6), "");
      85         204 :     const struct sockaddr_in6* sin6 = reinterpret_cast<const struct sockaddr_in6*>(&ss);
      86         204 :     ASSERT(AF_INET6 == sin6->sin6_family);
      87         204 :     if (!v6only && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
      88           0 :       struct sockaddr_in sin;
      89           0 :       ipv6ToIpv4CompatibleAddress(sin6, &sin);
      90           0 :       return Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(&sin);
      91         204 :     } else {
      92         204 :       return Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(*sin6, v6only);
      93         204 :     }
      94         204 :   }
      95           0 :   case AF_UNIX: {
      96           0 :     const struct sockaddr_un* sun = reinterpret_cast<const struct sockaddr_un*>(&ss);
      97           0 :     ASSERT(AF_UNIX == sun->sun_family);
      98           0 :     RELEASE_ASSERT(ss_len == 0 || static_cast<unsigned int>(ss_len) >=
      99           0 :                                       offsetof(struct sockaddr_un, sun_path) + 1,
     100           0 :                    "");
     101           0 :     return Address::InstanceFactory::createInstancePtr<Address::PipeInstance>(sun, ss_len);
     102           0 :   }
     103           0 :   default:
     104           0 :     return absl::InvalidArgumentError(fmt::format("Unexpected sockaddr family: {}", ss.ss_family));
     105        5275 :   }
     106        5275 : }
     107             : 
     108             : Address::InstanceConstSharedPtr addressFromSockAddrOrThrow(const sockaddr_storage& ss,
     109        3440 :                                                            socklen_t ss_len, bool v6only) {
     110             :   // Though we don't have any test coverage where address validation in addressFromSockAddr() fails,
     111             :   // this code is called in worker thread and can throw in theory. In that case, the program will
     112             :   // crash due to uncaught exception. In practice, we don't expect any address validation in
     113             :   // addressFromSockAddr() to fail in worker thread.
     114        3440 :   StatusOr<InstanceConstSharedPtr> address = addressFromSockAddr(ss, ss_len, v6only);
     115        3440 :   return throwOnError(address);
     116        3440 : }
     117             : 
     118             : Address::InstanceConstSharedPtr
     119        1443 : addressFromSockAddrOrDie(const sockaddr_storage& ss, socklen_t ss_len, os_fd_t fd, bool v6only) {
     120             :   // Set v6only to false so that mapped-v6 address can be normalize to v4
     121             :   // address. Though dual stack may be disabled, it's still okay to assume the
     122             :   // address is from a dual stack socket. This is because mapped-v6 address
     123             :   // must come from a dual stack socket. An actual v6 address can come from
     124             :   // both dual stack socket and v6 only socket. If |peer_addr| is an actual v6
     125             :   // address and the socket is actually v6 only, the returned address will be
     126             :   // regarded as a v6 address from dual stack socket. However, this address is not going to be
     127             :   // used to create socket. Wrong knowledge of dual stack support won't hurt.
     128        1443 :   StatusOr<Address::InstanceConstSharedPtr> address =
     129        1443 :       Address::addressFromSockAddr(ss, ss_len, v6only);
     130        1443 :   if (!address.ok()) {
     131           0 :     PANIC(fmt::format("Invalid address for fd: {}, error: {}", fd, address.status().ToString()));
     132           0 :   }
     133        1443 :   return *address;
     134        1443 : }
     135             : 
     136             : Ipv4Instance::Ipv4Instance(const sockaddr_in* address, const SocketInterface* sock_interface)
     137           0 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     138           0 :   throwOnError(validateProtocolSupported());
     139           0 :   initHelper(address);
     140           0 : }
     141             : 
     142             : Ipv4Instance::Ipv4Instance(const std::string& address, const SocketInterface* sock_interface)
     143        3700 :     : Ipv4Instance(address, 0, sockInterfaceOrDefault(sock_interface)) {}
     144             : 
     145             : Ipv4Instance::Ipv4Instance(const std::string& address, uint32_t port,
     146             :                            const SocketInterface* sock_interface)
     147        6685 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     148        6685 :   throwOnError(validateProtocolSupported());
     149        6685 :   memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
     150        6685 :   ip_.ipv4_.address_.sin_family = AF_INET;
     151        6685 :   ip_.ipv4_.address_.sin_port = htons(port);
     152        6685 :   int rc = inet_pton(AF_INET, address.c_str(), &ip_.ipv4_.address_.sin_addr);
     153        6685 :   if (1 != rc) {
     154         261 :     throwEnvoyExceptionOrPanic(fmt::format("invalid ipv4 address '{}'", address));
     155         261 :   }
     156             : 
     157        6424 :   friendly_name_ = absl::StrCat(address, ":", port);
     158        6424 :   ip_.friendly_address_ = address;
     159        6424 : }
     160             : 
     161             : Ipv4Instance::Ipv4Instance(uint32_t port, const SocketInterface* sock_interface)
     162        1204 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     163        1204 :   throwOnError(validateProtocolSupported());
     164        1204 :   memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
     165        1204 :   ip_.ipv4_.address_.sin_family = AF_INET;
     166        1204 :   ip_.ipv4_.address_.sin_port = htons(port);
     167        1204 :   ip_.ipv4_.address_.sin_addr.s_addr = INADDR_ANY;
     168        1204 :   friendly_name_ = absl::StrCat("0.0.0.0:", port);
     169        1204 :   ip_.friendly_address_ = "0.0.0.0";
     170        1204 : }
     171             : 
     172             : Ipv4Instance::Ipv4Instance(absl::Status& status, const sockaddr_in* address,
     173             :                            const SocketInterface* sock_interface)
     174      190296 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     175      190296 :   status = validateProtocolSupported();
     176      190296 :   if (!status.ok()) {
     177           0 :     return;
     178           0 :   }
     179      190296 :   initHelper(address);
     180      190296 : }
     181             : 
     182          18 : bool Ipv4Instance::operator==(const Instance& rhs) const {
     183          18 :   const Ipv4Instance* rhs_casted = dynamic_cast<const Ipv4Instance*>(&rhs);
     184          18 :   return (rhs_casted && (ip_.ipv4_.address() == rhs_casted->ip_.ipv4_.address()) &&
     185          18 :           (ip_.port() == rhs_casted->ip_.port()));
     186          18 : }
     187             : 
     188      190296 : std::string Ipv4Instance::sockaddrToString(const sockaddr_in& addr) {
     189      190296 :   static constexpr size_t BufferSize = 16; // enough space to hold an IPv4 address in string form
     190      190296 :   char str[BufferSize];
     191             :   // Write backwards from the end of the buffer for simplicity.
     192      190296 :   char* start = str + BufferSize;
     193      190296 :   uint32_t ipv4_addr = ntohl(addr.sin_addr.s_addr);
     194      951480 :   for (unsigned i = 4; i != 0; i--, ipv4_addr >>= 8) {
     195      761184 :     uint32_t octet = ipv4_addr & 0xff;
     196      761184 :     if (octet == 0) {
     197      382013 :       ASSERT(start > str);
     198      382013 :       *--start = '0';
     199      382195 :     } else {
     200      755407 :       do {
     201      755407 :         ASSERT(start > str);
     202      755407 :         *--start = '0' + (octet % 10);
     203      755407 :         octet /= 10;
     204      755407 :       } while (octet != 0);
     205      379171 :     }
     206      761184 :     if (i != 1) {
     207      570888 :       ASSERT(start > str);
     208      570888 :       *--start = '.';
     209      570888 :     }
     210      761184 :   }
     211      190296 :   const std::string::size_type end = str + BufferSize - start;
     212      190296 :   return {start, end};
     213      190296 : }
     214             : 
     215      198185 : absl::Status Ipv4Instance::validateProtocolSupported() {
     216      198185 :   static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET);
     217      198185 :   if (supported) {
     218      198185 :     return absl::OkStatus();
     219      198185 :   }
     220           0 :   return absl::FailedPreconditionError("IPv4 addresses are not supported on this machine");
     221      198185 : }
     222             : 
     223      190296 : void Ipv4Instance::initHelper(const sockaddr_in* address) {
     224      190296 :   memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_));
     225      190296 :   ip_.ipv4_.address_ = *address;
     226      190296 :   ip_.friendly_address_ = sockaddrToString(*address);
     227             : 
     228             :   // Based on benchmark testing, this reserve+append implementation runs faster than absl::StrCat.
     229      190296 :   fmt::format_int port(ntohs(address->sin_port));
     230      190296 :   friendly_name_.reserve(ip_.friendly_address_.size() + 1 + port.size());
     231      190296 :   friendly_name_.append(ip_.friendly_address_);
     232      190296 :   friendly_name_.push_back(':');
     233      190296 :   friendly_name_.append(port.data(), port.size());
     234      190296 : }
     235             : 
     236         423 : absl::uint128 Ipv6Instance::Ipv6Helper::address() const {
     237         423 :   absl::uint128 result{0};
     238         423 :   static_assert(sizeof(absl::uint128) == 16, "The size of absl::uint128 is not 16.");
     239         423 :   safeMemcpyUnsafeSrc(&result, &address_.sin6_addr.s6_addr[0]);
     240         423 :   return result;
     241         423 : }
     242             : 
     243          98 : uint32_t Ipv6Instance::Ipv6Helper::scopeId() const { return address_.sin6_scope_id; }
     244             : 
     245        1596 : uint32_t Ipv6Instance::Ipv6Helper::port() const { return ntohs(address_.sin6_port); }
     246             : 
     247         515 : bool Ipv6Instance::Ipv6Helper::v6only() const { return v6only_; };
     248             : 
     249        1081 : std::string Ipv6Instance::Ipv6Helper::makeFriendlyAddress() const {
     250        1081 :   char str[INET6_ADDRSTRLEN];
     251        1081 :   const char* ptr = inet_ntop(AF_INET6, &address_.sin6_addr, str, INET6_ADDRSTRLEN);
     252        1081 :   ASSERT(str == ptr);
     253        1081 :   if (address_.sin6_scope_id != 0) {
     254             :     // Note that here we don't use the `if_indextoname` that will give a more user friendly
     255             :     // output just because in the past created a performance bottleneck if the machine had a
     256             :     // lot of IPv6 Link local addresses.
     257          98 :     return absl::StrCat(ptr, "%", scopeId());
     258          98 :   }
     259         983 :   return ptr;
     260        1081 : }
     261             : 
     262           0 : InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::v4CompatibleAddress() const {
     263           0 :   if (!v6only_ && IN6_IS_ADDR_V4MAPPED(&address_.sin6_addr)) {
     264           0 :     struct sockaddr_in sin;
     265           0 :     ipv6ToIpv4CompatibleAddress(&address_, &sin);
     266           0 :     auto addr = Address::InstanceFactory::createInstancePtr<Address::Ipv4Instance>(&sin);
     267           0 :     return addr.ok() ? addr.value() : nullptr;
     268           0 :   }
     269           0 :   return nullptr;
     270           0 : }
     271             : 
     272           0 : InstanceConstSharedPtr Ipv6Instance::Ipv6Helper::addressWithoutScopeId() const {
     273           0 :   struct sockaddr_in6 ret_addr = address_;
     274           0 :   ret_addr.sin6_scope_id = 0;
     275           0 :   auto addr = Address::InstanceFactory::createInstancePtr<Address::Ipv6Instance>(ret_addr, v6only_);
     276           0 :   return addr.ok() ? addr.value() : nullptr;
     277           0 : }
     278             : 
     279             : Ipv6Instance::Ipv6Instance(const sockaddr_in6& address, bool v6only,
     280             :                            const SocketInterface* sock_interface)
     281           0 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     282           0 :   throwOnError(validateProtocolSupported());
     283           0 :   initHelper(address, v6only);
     284           0 : }
     285             : 
     286             : Ipv6Instance::Ipv6Instance(const std::string& address, const SocketInterface* sock_interface)
     287           0 :     : Ipv6Instance(address, 0, sockInterfaceOrDefault(sock_interface)) {}
     288             : 
     289             : Ipv6Instance::Ipv6Instance(const std::string& address, uint32_t port,
     290             :                            const SocketInterface* sock_interface, bool v6only)
     291         426 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     292         426 :   throwOnError(validateProtocolSupported());
     293         426 :   sockaddr_in6 addr_in;
     294         426 :   memset(&addr_in, 0, sizeof(addr_in));
     295         426 :   addr_in.sin6_family = AF_INET6;
     296         426 :   addr_in.sin6_port = htons(port);
     297         426 :   if (!address.empty()) {
     298           3 :     if (1 != inet_pton(AF_INET6, address.c_str(), &addr_in.sin6_addr)) {
     299           0 :       throwEnvoyExceptionOrPanic(fmt::format("invalid ipv6 address '{}'", address));
     300           0 :     }
     301         426 :   } else {
     302         423 :     addr_in.sin6_addr = in6addr_any;
     303         423 :   }
     304         426 :   initHelper(addr_in, v6only);
     305         426 : }
     306             : 
     307             : Ipv6Instance::Ipv6Instance(uint32_t port, const SocketInterface* sock_interface)
     308         423 :     : Ipv6Instance("", port, sockInterfaceOrDefault(sock_interface)) {}
     309             : 
     310           0 : bool Ipv6Instance::operator==(const Instance& rhs) const {
     311           0 :   const auto* rhs_casted = dynamic_cast<const Ipv6Instance*>(&rhs);
     312           0 :   return (rhs_casted && (ip_.ipv6_.address() == rhs_casted->ip_.ipv6_.address()) &&
     313           0 :           (ip_.port() == rhs_casted->ip_.port()) &&
     314           0 :           (ip_.ipv6_.scopeId() == rhs_casted->ip_.ipv6_.scopeId()));
     315           0 : }
     316             : 
     317             : Ipv6Instance::Ipv6Instance(absl::Status& status, const sockaddr_in6& address, bool v6only,
     318             :                            const SocketInterface* sock_interface)
     319         655 :     : InstanceBase(Type::Ip, sockInterfaceOrDefault(sock_interface)) {
     320         655 :   status = validateProtocolSupported();
     321         655 :   if (!status.ok()) {
     322           0 :     return;
     323           0 :   }
     324         655 :   initHelper(address, v6only);
     325         655 : }
     326             : 
     327        1081 : absl::Status Ipv6Instance::validateProtocolSupported() {
     328        1081 :   static const bool supported = SocketInterfaceSingleton::get().ipFamilySupported(AF_INET6);
     329        1081 :   if (supported) {
     330        1081 :     return absl::OkStatus();
     331        1081 :   }
     332           0 :   return absl::FailedPreconditionError("IPv6 addresses are not supported on this machine");
     333        1081 : }
     334             : 
     335        1081 : void Ipv6Instance::initHelper(const sockaddr_in6& address, bool v6only) {
     336        1081 :   ip_.ipv6_.address_ = address;
     337        1081 :   ip_.friendly_address_ = ip_.ipv6_.makeFriendlyAddress();
     338        1081 :   ip_.ipv6_.v6only_ = v6only;
     339        1081 :   friendly_name_ = fmt::format("[{}]:{}", ip_.friendly_address_, ip_.port());
     340        1081 : }
     341             : 
     342             : PipeInstance::PipeInstance(const sockaddr_un* address, socklen_t ss_len, mode_t mode,
     343             :                            const SocketInterface* sock_interface)
     344           0 :     : InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
     345           0 :   if (address->sun_path[0] == '\0') {
     346             : #if !defined(__linux__)
     347             :     throwEnvoyExceptionOrPanic("Abstract AF_UNIX sockets are only supported on linux.");
     348             : #endif
     349           0 :     RELEASE_ASSERT(static_cast<unsigned int>(ss_len) >= offsetof(struct sockaddr_un, sun_path) + 1,
     350           0 :                    "");
     351           0 :     pipe_.abstract_namespace_ = true;
     352           0 :     pipe_.address_length_ = ss_len - offsetof(struct sockaddr_un, sun_path);
     353           0 :   }
     354           0 :   absl::Status status = initHelper(address, mode);
     355           0 :   throwOnError(status);
     356           0 : }
     357             : 
     358             : PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode,
     359             :                            const SocketInterface* sock_interface)
     360         738 :     : InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
     361         738 :   if (pipe_path.size() >= sizeof(pipe_.address_.sun_path)) {
     362         201 :     throwEnvoyExceptionOrPanic(
     363         201 :         fmt::format("Path \"{}\" exceeds maximum UNIX domain socket path size of {}.", pipe_path,
     364         201 :                     sizeof(pipe_.address_.sun_path)));
     365         201 :   }
     366         537 :   memset(&pipe_.address_, 0, sizeof(pipe_.address_));
     367         537 :   pipe_.address_.sun_family = AF_UNIX;
     368         537 :   if (pipe_path[0] == '@') {
     369             :     // This indicates an abstract namespace.
     370             :     // In this case, null bytes in the name have no special significance, and so we copy all
     371             :     // characters of pipe_path to sun_path, including null bytes in the name. The pathname must also
     372             :     // be null terminated. The friendly name is the address path with embedded nulls replaced with
     373             :     // '@' for consistency with the first character.
     374             : #if !defined(__linux__)
     375             :     throwEnvoyExceptionOrPanic("Abstract AF_UNIX sockets are only supported on linux.");
     376             : #endif
     377          74 :     if (mode != 0) {
     378           0 :       throwEnvoyExceptionOrPanic("Cannot set mode for Abstract AF_UNIX sockets");
     379           0 :     }
     380          74 :     pipe_.abstract_namespace_ = true;
     381          74 :     pipe_.address_length_ = pipe_path.size();
     382             :     // The following statement is safe since pipe_path size was checked at the beginning of this
     383             :     // function
     384          74 :     memcpy(&pipe_.address_.sun_path[0], pipe_path.data(), pipe_path.size()); // NOLINT(safe-memcpy)
     385          74 :     pipe_.address_.sun_path[0] = '\0';
     386          74 :     pipe_.address_.sun_path[pipe_path.size()] = '\0';
     387          74 :     friendly_name_ = friendlyNameFromAbstractPath(
     388          74 :         absl::string_view(pipe_.address_.sun_path, pipe_.address_length_));
     389         491 :   } else {
     390             :     // Throw an error if the pipe path has an embedded null character.
     391         463 :     if (pipe_path.size() != strlen(pipe_path.c_str())) {
     392         168 :       throwEnvoyExceptionOrPanic("UNIX domain socket pathname contains embedded null characters");
     393         168 :     }
     394         295 :     StringUtil::strlcpy(&pipe_.address_.sun_path[0], pipe_path.c_str(),
     395         295 :                         sizeof(pipe_.address_.sun_path));
     396         295 :     friendly_name_ = pipe_.address_.sun_path;
     397         295 :   }
     398         369 :   pipe_.mode_ = mode;
     399         369 : }
     400             : 
     401             : PipeInstance::PipeInstance(absl::Status& error, const sockaddr_un* address, socklen_t ss_len,
     402             :                            mode_t mode, const SocketInterface* sock_interface)
     403           0 :     : InstanceBase(Type::Pipe, sockInterfaceOrDefault(sock_interface)) {
     404           0 :   if (address->sun_path[0] == '\0') {
     405             : #if !defined(__linux__)
     406             :     error = absl::FailedPreconditionError("Abstract AF_UNIX sockets are only supported on linux.");
     407             :     return;
     408             : #endif
     409           0 :     RELEASE_ASSERT(static_cast<unsigned int>(ss_len) >= offsetof(struct sockaddr_un, sun_path) + 1,
     410           0 :                    "");
     411           0 :     pipe_.abstract_namespace_ = true;
     412           0 :     pipe_.address_length_ = ss_len - offsetof(struct sockaddr_un, sun_path);
     413           0 :   }
     414           0 :   error = initHelper(address, mode);
     415           0 : }
     416             : 
     417           0 : bool PipeInstance::operator==(const Instance& rhs) const { return asString() == rhs.asString(); }
     418             : 
     419           0 : absl::Status PipeInstance::initHelper(const sockaddr_un* address, mode_t mode) {
     420           0 :   pipe_.address_ = *address;
     421           0 :   if (pipe_.abstract_namespace_) {
     422           0 :     if (mode != 0) {
     423           0 :       return absl::FailedPreconditionError("Cannot set mode for Abstract AF_UNIX sockets");
     424           0 :     }
     425             :     // Replace all null characters with '@' in friendly_name_.
     426           0 :     friendly_name_ = friendlyNameFromAbstractPath(
     427           0 :         absl::string_view(pipe_.address_.sun_path, pipe_.address_length_));
     428           0 :   } else {
     429           0 :     friendly_name_ = address->sun_path;
     430           0 :   }
     431           0 :   pipe_.mode_ = mode;
     432           0 :   return absl::OkStatus();
     433           0 : }
     434             : 
     435             : EnvoyInternalInstance::EnvoyInternalInstance(const std::string& address_id,
     436             :                                              const std::string& endpoint_id,
     437             :                                              const SocketInterface* sock_interface)
     438             :     : InstanceBase(Type::EnvoyInternal, sockInterfaceOrDefault(sock_interface)),
     439           4 :       internal_address_(address_id, endpoint_id) {
     440           4 :   friendly_name_ = absl::StrCat("envoy://", address_id, "/", endpoint_id);
     441           4 : }
     442             : 
     443           0 : bool EnvoyInternalInstance::operator==(const Instance& rhs) const {
     444           0 :   return rhs.type() == Type::EnvoyInternal && asString() == rhs.asString();
     445           0 : }
     446             : 
     447             : } // namespace Address
     448             : } // namespace Network
     449             : } // namespace Envoy

Generated by: LCOV version 1.15