LCOV - code coverage report
Current view: top level - source/common/network - socket_interface_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 66 79 83.5 %
Date: 2024-01-05 06:35:25 Functions: 6 7 85.7 %

          Line data    Source code
       1             : #include "source/common/network/socket_interface_impl.h"
       2             : 
       3             : #include "envoy/common/exception.h"
       4             : #include "envoy/extensions/network/socket_interface/v3/default_socket_interface.pb.h"
       5             : 
       6             : #include "source/common/api/os_sys_calls_impl.h"
       7             : #include "source/common/common/assert.h"
       8             : #include "source/common/common/utility.h"
       9             : #include "source/common/network/address_impl.h"
      10             : #include "source/common/network/io_socket_handle_impl.h"
      11             : #include "source/common/network/win32_socket_handle_impl.h"
      12             : 
      13             : namespace Envoy {
      14             : namespace Network {
      15             : 
      16             : IoHandlePtr SocketInterfaceImpl::makePlatformSpecificSocket(int socket_fd, bool socket_v6only,
      17        3978 :                                                             absl::optional<int> domain) {
      18        3978 :   if constexpr (Event::PlatformDefaultTriggerType == Event::FileTriggerType::EmulatedEdge) {
      19           0 :     return std::make_unique<Win32SocketHandleImpl>(socket_fd, socket_v6only, domain);
      20           0 :   }
      21        3978 :   return std::make_unique<IoSocketHandleImpl>(socket_fd, socket_v6only, domain);
      22        3978 : }
      23             : 
      24             : IoHandlePtr SocketInterfaceImpl::makeSocket(int socket_fd, bool socket_v6only,
      25        2645 :                                             absl::optional<int> domain) const {
      26        2645 :   return makePlatformSpecificSocket(socket_fd, socket_v6only, domain);
      27        2645 : }
      28             : 
      29             : IoHandlePtr SocketInterfaceImpl::socket(Socket::Type socket_type, Address::Type addr_type,
      30             :                                         Address::IpVersion version, bool socket_v6only,
      31        2645 :                                         const SocketCreationOptions& options) const {
      32        2645 :   int protocol = 0;
      33             : #if defined(__APPLE__) || defined(WIN32)
      34             :   ASSERT(!options.mptcp_enabled_, "MPTCP is only supported on Linux");
      35             :   int flags = 0;
      36             : #else
      37        2645 :   int flags = SOCK_NONBLOCK;
      38             : 
      39        2645 :   if (options.mptcp_enabled_) {
      40           0 :     ASSERT(socket_type == Socket::Type::Stream);
      41           0 :     ASSERT(addr_type == Address::Type::Ip);
      42           0 :     protocol = IPPROTO_MPTCP;
      43           0 :   }
      44        2645 : #endif
      45             : 
      46        2645 :   if (socket_type == Socket::Type::Stream) {
      47        1948 :     flags |= SOCK_STREAM;
      48        2645 :   } else {
      49         697 :     flags |= SOCK_DGRAM;
      50         697 :   }
      51             : 
      52        2645 :   int domain;
      53        2645 :   if (addr_type == Address::Type::Ip) {
      54        2640 :     if (version == Address::IpVersion::v6 || Address::forceV6()) {
      55         515 :       domain = AF_INET6;
      56        2640 :     } else {
      57        2125 :       ASSERT(version == Address::IpVersion::v4);
      58        2125 :       domain = AF_INET;
      59        2125 :     }
      60        2645 :   } else if (addr_type == Address::Type::Pipe) {
      61           5 :     domain = AF_UNIX;
      62           5 :   } else {
      63           0 :     ASSERT(addr_type == Address::Type::EnvoyInternal);
      64           0 :     PANIC("not implemented");
      65             :     // TODO(lambdai): Add InternalIoSocketHandleImpl to support internal address.
      66           0 :     return nullptr;
      67           0 :   }
      68             : 
      69        2645 :   const Api::SysCallSocketResult result =
      70        2645 :       Api::OsSysCallsSingleton::get().socket(domain, flags, protocol);
      71        2645 :   RELEASE_ASSERT(SOCKET_VALID(result.return_value_),
      72        2645 :                  fmt::format("socket(2) failed, got error: {}", errorDetails(result.errno_)));
      73        2645 :   IoHandlePtr io_handle = makeSocket(result.return_value_, socket_v6only, domain);
      74             : 
      75             : #if defined(__APPLE__) || defined(WIN32)
      76             :   // Cannot set SOCK_NONBLOCK as a ::socket flag.
      77             :   const int rc = io_handle->setBlocking(false).return_value_;
      78             :   RELEASE_ASSERT(!SOCKET_FAILURE(rc),
      79             :                  fmt::format("Unable to set socket non-blocking: got error: {}", rc));
      80             : #endif
      81             : 
      82        2645 :   return io_handle;
      83        2645 : }
      84             : 
      85             : IoHandlePtr SocketInterfaceImpl::socket(Socket::Type socket_type,
      86             :                                         const Address::InstanceConstSharedPtr addr,
      87        2645 :                                         const SocketCreationOptions& options) const {
      88        2645 :   Address::IpVersion ip_version = addr->ip() ? addr->ip()->version() : Address::IpVersion::v4;
      89        2645 :   int v6only = 0;
      90        2645 :   if (addr->type() == Address::Type::Ip && ip_version == Address::IpVersion::v6) {
      91         515 :     v6only = addr->ip()->ipv6()->v6only();
      92         515 :   }
      93             : 
      94        2645 :   IoHandlePtr io_handle =
      95        2645 :       SocketInterfaceImpl::socket(socket_type, addr->type(), ip_version, v6only, options);
      96        2645 :   if (addr->type() == Address::Type::Ip && ip_version == Address::IpVersion::v6 &&
      97        2645 :       !Address::forceV6()) {
      98             :     // Setting IPV6_V6ONLY restricts the IPv6 socket to IPv6 connections only.
      99         515 :     const Api::SysCallIntResult result = io_handle->setOption(
     100         515 :         IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char*>(&v6only), sizeof(v6only));
     101         515 :     ENVOY_BUG(!SOCKET_FAILURE(result.return_value_),
     102         515 :               fmt::format("Unable to set socket v6-only: got error: {}", result.return_value_));
     103         515 :   }
     104        2645 :   return io_handle;
     105        2645 : }
     106             : 
     107        2562 : bool SocketInterfaceImpl::ipFamilySupported(int domain) {
     108        2562 :   Api::OsSysCalls& os_sys_calls = Api::OsSysCallsSingleton::get();
     109        2562 :   const Api::SysCallSocketResult result = os_sys_calls.socket(domain, SOCK_STREAM, 0);
     110        2562 :   if (SOCKET_VALID(result.return_value_)) {
     111        2562 :     RELEASE_ASSERT(
     112        2562 :         os_sys_calls.close(result.return_value_).return_value_ == 0,
     113        2562 :         fmt::format("Fail to close fd: response code {}", errorDetails(result.return_value_)));
     114        2562 :   }
     115        2562 :   return SOCKET_VALID(result.return_value_);
     116        2562 : }
     117             : 
     118             : Server::BootstrapExtensionPtr
     119             : SocketInterfaceImpl::createBootstrapExtension(const Protobuf::Message&,
     120           0 :                                               Server::Configuration::ServerFactoryContext&) {
     121           0 :   return std::make_unique<SocketInterfaceExtension>(*this);
     122           0 : }
     123             : 
     124          12 : ProtobufTypes::MessagePtr SocketInterfaceImpl::createEmptyConfigProto() {
     125          12 :   return std::make_unique<
     126          12 :       envoy::extensions::network::socket_interface::v3::DefaultSocketInterface>();
     127          12 : }
     128             : 
     129             : REGISTER_FACTORY(SocketInterfaceImpl, Server::Configuration::BootstrapExtensionFactory);
     130             : 
     131             : static SocketInterfaceLoader* socket_interface_ =
     132             :     new SocketInterfaceLoader(std::make_unique<SocketInterfaceImpl>());
     133             : 
     134             : } // namespace Network
     135             : } // namespace Envoy

Generated by: LCOV version 1.15