1
#pragma once
2

            
3
#include <string>
4

            
5
#include "envoy/buffer/buffer.h"
6
#include "envoy/network/connection.h"
7

            
8
#include "source/common/buffer/buffer_impl.h"
9
#include "source/common/common/logger.h"
10
#include "source/common/http/header_map_impl.h"
11
#include "source/common/http/headers.h"
12

            
13
#include "absl/strings/str_cat.h"
14
#include "absl/strings/string_view.h"
15

            
16
namespace Envoy {
17
namespace Extensions {
18
namespace Bootstrap {
19
namespace ReverseConnection {
20

            
21
class ReverseConnectionUtility : public Logger::Loggable<Logger::Id::connection> {
22
public:
23
  static constexpr absl::string_view PING_MESSAGE = "RPING";
24
  static constexpr absl::string_view PROXY_MESSAGE = "PROXY";
25
  static constexpr absl::string_view DEFAULT_REVERSE_TUNNEL_REQUEST_PATH =
26
      "/reverse_connections/request";
27
  static constexpr absl::string_view TENANT_SCOPE_DELIMITER = ":";
28

            
29
  struct TenantScopedIdentifierView {
30
    absl::string_view tenant;
31
    absl::string_view identifier;
32
51
    bool hasTenant() const { return !tenant.empty(); }
33
  };
34

            
35
  static bool isPingMessage(absl::string_view data);
36

            
37
  static Buffer::InstancePtr createPingResponse();
38

            
39
  static bool sendPingResponse(Network::Connection& connection);
40

            
41
  static Api::IoCallUint64Result sendPingResponse(Network::IoHandle& io_handle);
42

            
43
  static bool handlePingMessage(absl::string_view data, Network::Connection& connection);
44

            
45
  static bool extractPingFromHttpData(absl::string_view http_data);
46

            
47
  static TenantScopedIdentifierView splitTenantScopedIdentifier(absl::string_view value);
48

            
49
  static std::string buildTenantScopedIdentifier(absl::string_view tenant,
50
                                                 absl::string_view identifier);
51

            
52
private:
53
  ReverseConnectionUtility() = delete;
54
};
55

            
56
// Header names used by reverse tunnel handshake over HTTP.
57
134
inline const Http::LowerCaseString& reverseTunnelNodeIdHeader() {
58
134
  static const Http::LowerCaseString kHeader{
59
134
      absl::StrCat(Http::Headers::get().prefix(), "-reverse-tunnel-node-id")};
60
134
  return kHeader;
61
134
}
62

            
63
134
inline const Http::LowerCaseString& reverseTunnelClusterIdHeader() {
64
134
  static const Http::LowerCaseString kHeader{
65
134
      absl::StrCat(Http::Headers::get().prefix(), "-reverse-tunnel-cluster-id")};
66
134
  return kHeader;
67
134
}
68

            
69
134
inline const Http::LowerCaseString& reverseTunnelTenantIdHeader() {
70
134
  static const Http::LowerCaseString kHeader{
71
134
      absl::StrCat(Http::Headers::get().prefix(), "-reverse-tunnel-tenant-id")};
72
134
  return kHeader;
73
134
}
74

            
75
43
inline const Http::LowerCaseString& reverseTunnelUpstreamClusterNameHeader() {
76
43
  static const Http::LowerCaseString kHeader{
77
43
      absl::StrCat(Http::Headers::get().prefix(), "-reverse-tunnel-upstream-cluster-name")};
78
43
  return kHeader;
79
43
}
80

            
81
class ReverseConnectionMessageHandlerFactory {
82
public:
83
  static std::shared_ptr<class PingMessageHandler> createPingHandler();
84
};
85

            
86
class PingMessageHandler : public std::enable_shared_from_this<PingMessageHandler>,
87
                           public Logger::Loggable<Logger::Id::connection> {
88
public:
89
6
  PingMessageHandler() = default;
90
6
  ~PingMessageHandler() = default;
91

            
92
  bool processPingMessage(absl::string_view data, Network::Connection& connection);
93

            
94
7
  uint64_t getPingCount() const { return ping_count_; }
95

            
96
private:
97
  uint64_t ping_count_{0};
98
};
99

            
100
} // namespace ReverseConnection
101
} // namespace Bootstrap
102
} // namespace Extensions
103
} // namespace Envoy