1
#include "source/extensions/upstreams/tcp/generic/config.h"
2

            
3
#include "envoy/stream_info/bool_accessor.h"
4
#include "envoy/stream_info/filter_state.h"
5
#include "envoy/upstream/cluster_manager.h"
6

            
7
#include "source/common/http/codec_client.h"
8
#include "source/common/stream_info/bool_accessor_impl.h"
9
#include "source/common/tcp_proxy/upstream.h"
10

            
11
namespace Envoy {
12
namespace Extensions {
13
namespace Upstreams {
14
namespace Tcp {
15
namespace Generic {
16

            
17
TcpProxy::GenericConnPoolPtr GenericConnPoolFactory::createGenericConnPool(
18
    Upstream::HostConstSharedPtr host, Upstream::ThreadLocalCluster& thread_local_cluster,
19
    TcpProxy::TunnelingConfigHelperOptConstRef config, Upstream::LoadBalancerContext* context,
20
    Envoy::Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks,
21
    Http::StreamDecoderFilterCallbacks& stream_decoder_callbacks,
22
2579
    StreamInfo::StreamInfo& downstream_info) const {
23
2579
  if (config.has_value() && !disableTunnelingByFilterState(downstream_info)) {
24
822
    Http::CodecType pool_type;
25
822
    if ((thread_local_cluster.info()->features() & Upstream::ClusterInfo::Features::HTTP2) != 0) {
26
327
      pool_type = Http::CodecType::HTTP2;
27
503
    } else if ((thread_local_cluster.info()->features() & Upstream::ClusterInfo::Features::HTTP3) !=
28
495
               0) {
29
218
      pool_type = Http::CodecType::HTTP3;
30
294
    } else {
31
277
      pool_type = Http::CodecType::HTTP1;
32
277
    }
33
822
    auto ret = std::make_unique<TcpProxy::HttpConnPool>(
34
822
        host, thread_local_cluster, context, *config, upstream_callbacks, stream_decoder_callbacks,
35
822
        pool_type, downstream_info);
36
822
    return (ret->valid() ? std::move(ret) : nullptr);
37
822
  }
38
1757
  auto ret = std::make_unique<TcpProxy::TcpConnPool>(host, thread_local_cluster, context,
39
1757
                                                     upstream_callbacks, downstream_info);
40
1757
  return (ret->valid() ? std::move(ret) : nullptr);
41
2579
}
42

            
43
bool GenericConnPoolFactory::disableTunnelingByFilterState(
44
824
    StreamInfo::StreamInfo& downstream_info) const {
45
824
  const StreamInfo::BoolAccessor* disable_tunneling =
46
824
      downstream_info.filterState()->getDataReadOnly<StreamInfo::BoolAccessor>(
47
824
          TcpProxy::DisableTunnelingFilterStateKey);
48

            
49
824
  return disable_tunneling != nullptr && disable_tunneling->value() == true;
50
824
}
51

            
52
REGISTER_FACTORY(GenericConnPoolFactory, TcpProxy::GenericConnPoolFactory);
53

            
54
class DisableTunnelingObjectFactory : public StreamInfo::FilterState::ObjectFactory {
55
public:
56
85
  std::string name() const override {
57
85
    return std::string(TcpProxy::DisableTunnelingFilterStateKey);
58
85
  }
59
  std::unique_ptr<StreamInfo::FilterState::Object>
60
1
  createFromBytes(absl::string_view data) const override {
61
1
    return std::make_unique<StreamInfo::BoolAccessorImpl>(data == "true");
62
1
  }
63
};
64

            
65
REGISTER_FACTORY(DisableTunnelingObjectFactory, StreamInfo::FilterState::ObjectFactory);
66

            
67
} // namespace Generic
68
} // namespace Tcp
69
} // namespace Upstreams
70
} // namespace Extensions
71
} // namespace Envoy