1
#pragma once
2

            
3
#include <netinet/in.h>
4
#include <sys/socket.h>
5

            
6
#include <functional>
7

            
8
#include "envoy/network/address.h"
9

            
10
#include "source/common/common/logger.h"
11
#include "source/common/network/address_impl.h"
12
#include "source/common/network/socket_interface.h"
13

            
14
namespace Envoy {
15
namespace Extensions {
16
namespace Bootstrap {
17
namespace ReverseConnection {
18

            
19
/**
20
 * Custom address type that embeds reverse connection metadata.
21
 */
22
class ReverseConnectionAddress : public Network::Address::Instance,
23
                                 public Envoy::Logger::Loggable<Envoy::Logger::Id::connection> {
24
public:
25
  // Placeholder port for reverse connection listeners. Non-zero to prevent port resolution logic
26
  // from updating the address, since reverse connection listeners do not actually bind to port.
27
  static constexpr uint32_t kReverseConnectionListenerPortPlaceholder = 1;
28

            
29
  // Struct to hold reverse connection configuration
30
  struct ReverseConnectionConfig {
31
    // Source node id of initiator envoy
32
    std::string src_node_id;
33
    // Source cluster id of initiator envoy
34
    std::string src_cluster_id;
35
    // Source tenant id of initiator envoy
36
    std::string src_tenant_id;
37
    // Remote cluster name of the reverse connection
38
    std::string remote_cluster;
39
    // Connection count of the reverse connection
40
    uint32_t connection_count;
41
  };
42

            
43
  // Minimal IP implementation for reverse connections. Provides the required Ip interface
44
  // but returns a placeholder port since reverse connection listeners do not actually bind to port.
45
  class ReverseConnectionIp : public Network::Address::Ip {
46
  public:
47
    // Minimal Ipv4 implementation for reverse connections
48
    class ReverseConnectionIpv4 : public Network::Address::Ipv4 {
49
    public:
50
15
      uint32_t address() const override { return htonl(INADDR_LOOPBACK); } // 127.0.0.1
51
    };
52

            
53
1
    const std::string& addressAsString() const override { return address_str_; }
54
15
    bool isAnyAddress() const override { return false; }
55
1
    bool isUnicastAddress() const override { return true; }
56
1
    bool isLinkLocalAddress() const override { return false; }
57
1
    bool isUniqueLocalAddress() const override { return false; }
58
1
    bool isSiteLocalAddress() const override { return false; }
59
1
    bool isTeredoAddress() const override { return false; }
60
16
    const Network::Address::Ipv4* ipv4() const override { return &ipv4_; }
61
1
    const Network::Address::Ipv6* ipv6() const override { return nullptr; }
62
    // Return the placeholder port.
63
111
    uint32_t port() const override { return kReverseConnectionListenerPortPlaceholder; }
64
60
    Network::Address::IpVersion version() const override { return Network::Address::IpVersion::v4; }
65

            
66
    // Public static address string used by both the Ip interface and ReverseConnectionAddress.
67
    static const std::string address_str_;
68

            
69
  private:
70
    ReverseConnectionIpv4 ipv4_;
71
  };
72

            
73
  ReverseConnectionAddress(const ReverseConnectionConfig& config);
74

            
75
  // Network::Address::Instance
76
  bool operator==(const Instance& rhs) const override;
77
131
  Network::Address::Type type() const override {
78
131
    return Network::Address::Type::Ip;
79
131
  } // Use IP type with our custom IP implementation
80
  const std::string& asString() const override;
81
  absl::string_view asStringView() const override;
82
  const std::string& logicalName() const override;
83
  // Return our minimal IP implementation with placeholder port
84
312
  const Network::Address::Ip* ip() const override { return &ip_; }
85
1
  const Network::Address::Pipe* pipe() const override { return nullptr; }
86
1
  const Network::Address::EnvoyInternalAddress* envoyInternalAddress() const override {
87
1
    return nullptr;
88
1
  }
89
77
  absl::optional<std::string> networkNamespace() const override { return absl::nullopt; }
90
1
  Network::Address::InstanceConstSharedPtr withNetworkNamespace(absl::string_view) const override {
91
1
    return nullptr;
92
1
  }
93
  const sockaddr* sockAddr() const override;
94
  socklen_t sockAddrLen() const override;
95
1
  absl::string_view addressType() const override { return "reverse_connection"; }
96
16
  const Network::SocketInterface& socketInterface() const override {
97
    // Return the appropriate reverse connection socket interface for downstream connections
98
16
    auto* reverse_socket_interface =
99
16
        Network::socketInterface("envoy.bootstrap.reverse_tunnel.downstream_socket_interface");
100
16
    if (reverse_socket_interface) {
101
15
      ENVOY_LOG_MISC(debug, "reverse connection address: using reverse socket interface");
102
15
      return *reverse_socket_interface;
103
15
    }
104
    // Fallback to default socket interface if reverse connection interface is not available.
105
1
    return Network::SocketInterfaceSingleton::get();
106
16
  }
107

            
108
  // Accessor for reverse connection config
109
20
  const ReverseConnectionConfig& reverseConnectionConfig() const { return config_; }
110

            
111
private:
112
  ReverseConnectionConfig config_;
113
  std::string address_string_;
114
  std::string logical_name_;
115
  ReverseConnectionIp ip_;
116
};
117

            
118
} // namespace ReverseConnection
119
} // namespace Bootstrap
120
} // namespace Extensions
121
} // namespace Envoy