LCOV - code coverage report
Current view: top level - source/extensions/common/proxy_protocol - proxy_protocol_header.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 122 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "source/extensions/common/proxy_protocol/proxy_protocol_header.h"
       2             : 
       3             : #include <sstream>
       4             : 
       5             : #include "envoy/buffer/buffer.h"
       6             : #include "envoy/network/address.h"
       7             : 
       8             : #include "source/common/network/address_impl.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Extensions {
      12             : namespace Common {
      13             : namespace ProxyProtocol {
      14             : 
      15             : void generateV1Header(const std::string& src_addr, const std::string& dst_addr, uint32_t src_port,
      16             :                       uint32_t dst_port, Network::Address::IpVersion ip_version,
      17           0 :                       Buffer::Instance& out) {
      18           0 :   std::ostringstream stream;
      19           0 :   stream << PROXY_PROTO_V1_SIGNATURE;
      20             : 
      21           0 :   switch (ip_version) {
      22           0 :   case Network::Address::IpVersion::v4:
      23           0 :     stream << PROXY_PROTO_V1_AF_INET << " ";
      24           0 :     break;
      25           0 :   case Network::Address::IpVersion::v6:
      26           0 :     stream << PROXY_PROTO_V1_AF_INET6 << " ";
      27           0 :     break;
      28           0 :   }
      29             : 
      30           0 :   stream << src_addr << " ";
      31           0 :   stream << dst_addr << " ";
      32           0 :   stream << src_port << " ";
      33           0 :   stream << dst_port << "\r\n";
      34             : 
      35           0 :   out.add(stream.str());
      36           0 : }
      37             : 
      38             : void generateV1Header(const Network::Address::Ip& source_address,
      39           0 :                       const Network::Address::Ip& dest_address, Buffer::Instance& out) {
      40           0 :   generateV1Header(source_address.addressAsString(), dest_address.addressAsString(),
      41           0 :                    source_address.port(), dest_address.port(), source_address.version(), out);
      42           0 : }
      43             : 
      44             : void generateV2Header(const std::string& src_addr, const std::string& dst_addr, uint32_t src_port,
      45             :                       uint32_t dst_port, Network::Address::IpVersion ip_version,
      46           0 :                       uint16_t extension_length, Buffer::Instance& out) {
      47           0 :   out.add(PROXY_PROTO_V2_SIGNATURE, PROXY_PROTO_V2_SIGNATURE_LEN);
      48             : 
      49           0 :   const uint8_t version_and_command = PROXY_PROTO_V2_VERSION << 4 | PROXY_PROTO_V2_ONBEHALF_OF;
      50           0 :   out.add(&version_and_command, 1);
      51             : 
      52           0 :   uint8_t address_family_and_protocol;
      53           0 :   switch (ip_version) {
      54           0 :   case Network::Address::IpVersion::v4:
      55           0 :     address_family_and_protocol = PROXY_PROTO_V2_AF_INET << 4;
      56           0 :     break;
      57           0 :   case Network::Address::IpVersion::v6:
      58           0 :     address_family_and_protocol = PROXY_PROTO_V2_AF_INET6 << 4;
      59           0 :     break;
      60           0 :   }
      61           0 :   address_family_and_protocol |= PROXY_PROTO_V2_TRANSPORT_STREAM;
      62           0 :   out.add(&address_family_and_protocol, 1);
      63             : 
      64             :   // Number of following bytes part of the header in V2 protocol.
      65           0 :   uint16_t addr_length;
      66           0 :   uint16_t addr_length_n; // Network byte order
      67             : 
      68           0 :   switch (ip_version) {
      69           0 :   case Network::Address::IpVersion::v4: {
      70           0 :     addr_length = PROXY_PROTO_V2_ADDR_LEN_INET + extension_length;
      71           0 :     addr_length_n = htons(addr_length);
      72           0 :     out.add(&addr_length_n, 2);
      73           0 :     const uint32_t net_src_addr =
      74           0 :         Network::Address::Ipv4Instance(src_addr, src_port).ip()->ipv4()->address();
      75           0 :     const uint32_t net_dst_addr =
      76           0 :         Network::Address::Ipv4Instance(dst_addr, dst_port).ip()->ipv4()->address();
      77           0 :     out.add(&net_src_addr, 4);
      78           0 :     out.add(&net_dst_addr, 4);
      79           0 :     break;
      80           0 :   }
      81           0 :   case Network::Address::IpVersion::v6: {
      82           0 :     addr_length = PROXY_PROTO_V2_ADDR_LEN_INET6 + extension_length;
      83           0 :     addr_length_n = htons(addr_length);
      84           0 :     out.add(&addr_length_n, 2);
      85           0 :     const absl::uint128 net_src_addr =
      86           0 :         Network::Address::Ipv6Instance(src_addr, src_port).ip()->ipv6()->address();
      87           0 :     const absl::uint128 net_dst_addr =
      88           0 :         Network::Address::Ipv6Instance(dst_addr, dst_port).ip()->ipv6()->address();
      89           0 :     out.add(&net_src_addr, 16);
      90           0 :     out.add(&net_dst_addr, 16);
      91           0 :     break;
      92           0 :   }
      93           0 :   }
      94             : 
      95           0 :   const uint16_t net_src_port = htons(static_cast<uint16_t>(src_port));
      96           0 :   const uint16_t net_dst_port = htons(static_cast<uint16_t>(dst_port));
      97           0 :   out.add(&net_src_port, 2);
      98           0 :   out.add(&net_dst_port, 2);
      99           0 : }
     100             : 
     101             : void generateV2Header(const std::string& src_addr, const std::string& dst_addr, uint32_t src_port,
     102             :                       uint32_t dst_port, Network::Address::IpVersion ip_version,
     103           0 :                       Buffer::Instance& out) {
     104           0 :   generateV2Header(src_addr, dst_addr, src_port, dst_port, ip_version, 0, out);
     105           0 : }
     106             : 
     107             : void generateV2Header(const Network::Address::Ip& source_address,
     108           0 :                       const Network::Address::Ip& dest_address, Buffer::Instance& out) {
     109           0 :   generateV2Header(source_address.addressAsString(), dest_address.addressAsString(),
     110           0 :                    source_address.port(), dest_address.port(), source_address.version(), 0, out);
     111           0 : }
     112             : 
     113             : bool generateV2Header(const Network::ProxyProtocolData& proxy_proto_data, Buffer::Instance& out,
     114           0 :                       bool pass_all_tlvs, const absl::flat_hash_set<uint8_t>& pass_through_tlvs) {
     115           0 :   uint64_t extension_length = 0;
     116           0 :   for (auto&& tlv : proxy_proto_data.tlv_vector_) {
     117           0 :     if (!pass_all_tlvs && !pass_through_tlvs.contains(tlv.type)) {
     118           0 :       continue;
     119           0 :     }
     120           0 :     extension_length += PROXY_PROTO_V2_TLV_TYPE_LENGTH_LEN + tlv.value.size();
     121           0 :     if (extension_length > std::numeric_limits<uint16_t>::max()) {
     122           0 :       ENVOY_LOG_MISC(
     123           0 :           warn, "Generating Proxy Protocol V2 header: TLVs exceed length limit {}, already got {}",
     124           0 :           std::numeric_limits<uint16_t>::max(), extension_length);
     125           0 :       return false;
     126           0 :     }
     127           0 :   }
     128             : 
     129           0 :   ASSERT(extension_length <= std::numeric_limits<uint16_t>::max());
     130           0 :   const auto& src = *proxy_proto_data.src_addr_->ip();
     131           0 :   const auto& dst = *proxy_proto_data.dst_addr_->ip();
     132           0 :   generateV2Header(src.addressAsString(), dst.addressAsString(), src.port(), dst.port(),
     133           0 :                    src.version(), static_cast<uint16_t>(extension_length), out);
     134             : 
     135             :   // Generate the TLV vector.
     136           0 :   for (auto&& tlv : proxy_proto_data.tlv_vector_) {
     137           0 :     if (!pass_all_tlvs && !pass_through_tlvs.contains(tlv.type)) {
     138           0 :       continue;
     139           0 :     }
     140           0 :     out.add(&tlv.type, 1);
     141           0 :     uint16_t size = htons(static_cast<uint16_t>(tlv.value.size()));
     142           0 :     out.add(&size, sizeof(uint16_t));
     143           0 :     out.add(&tlv.value.front(), tlv.value.size());
     144           0 :   }
     145           0 :   return true;
     146           0 : }
     147             : 
     148             : void generateProxyProtoHeader(const envoy::config::core::v3::ProxyProtocolConfig& config,
     149           0 :                               const Network::Connection& connection, Buffer::Instance& out) {
     150           0 :   const Network::Address::Ip& dest_address =
     151           0 :       *connection.connectionInfoProvider().localAddress()->ip();
     152           0 :   const Network::Address::Ip& source_address =
     153           0 :       *connection.connectionInfoProvider().remoteAddress()->ip();
     154           0 :   if (config.version() == envoy::config::core::v3::ProxyProtocolConfig::V1) {
     155           0 :     generateV1Header(source_address, dest_address, out);
     156           0 :   } else if (config.version() == envoy::config::core::v3::ProxyProtocolConfig::V2) {
     157           0 :     generateV2Header(source_address, dest_address, out);
     158           0 :   }
     159           0 : }
     160             : 
     161           0 : void generateV2LocalHeader(Buffer::Instance& out) {
     162           0 :   out.add(PROXY_PROTO_V2_SIGNATURE, PROXY_PROTO_V2_SIGNATURE_LEN);
     163           0 :   const uint8_t addr_fam_protocol_and_length[4]{PROXY_PROTO_V2_VERSION << 4, 0, 0, 0};
     164           0 :   out.add(addr_fam_protocol_and_length, 4);
     165           0 : }
     166             : 
     167             : } // namespace ProxyProtocol
     168             : } // namespace Common
     169             : } // namespace Extensions
     170             : } // namespace Envoy

Generated by: LCOV version 1.15