1
#pragma once
2

            
3
#include <cstdint>
4
#include <memory>
5

            
6
#include "envoy/http/codec.h"
7
#include "envoy/tcp/conn_pool.h"
8

            
9
#include "source/common/buffer/watermark_buffer.h"
10
#include "source/common/common/cleanup.h"
11
#include "source/common/common/logger.h"
12
#include "source/common/config/well_known_names.h"
13
#include "source/common/router/upstream_request.h"
14
#include "source/common/stream_info/stream_info_impl.h"
15

            
16
namespace Envoy {
17
namespace Extensions {
18
namespace Upstreams {
19
namespace Http {
20
namespace Tcp {
21

            
22
class TcpConnPool : public Router::GenericConnPool, public Envoy::Tcp::ConnectionPool::Callbacks {
23
public:
24
  TcpConnPool(Upstream::HostConstSharedPtr host, Upstream::ThreadLocalCluster& thread_local_cluster,
25
374
              Upstream::ResourcePriority priority, Upstream::LoadBalancerContext* ctx) {
26
374
    conn_pool_data_ = thread_local_cluster.tcpConnPool(host, priority, ctx);
27
374
  }
28
374
  ~TcpConnPool() override {
29
374
    ENVOY_BUG(upstream_handle_ == nullptr, "upstream_handle not null");
30
374
    resetUpstreamHandleIfSet();
31
374
  }
32
  // Router::GenericConnPool
33
373
  void newStream(Router::GenericConnectionPoolCallbacks* callbacks) override {
34
373
    callbacks_ = callbacks;
35
373
    upstream_handle_ = conn_pool_data_.value().newConnection(*this);
36
373
  }
37
336
  bool cancelAnyPendingStream() override { return resetUpstreamHandleIfSet(); }
38
740
  Upstream::HostDescriptionConstSharedPtr host() const override {
39
740
    return conn_pool_data_.value().host();
40
740
  }
41
371
  bool valid() const override { return conn_pool_data_.has_value(); }
42

            
43
  // Tcp::ConnectionPool::Callbacks
44
  void onPoolFailure(ConnectionPool::PoolFailureReason reason,
45
                     absl::string_view transport_failure_reason,
46
1
                     Upstream::HostDescriptionConstSharedPtr host) override {
47
1
    upstream_handle_ = nullptr;
48
1
    callbacks_->onPoolFailure(reason, transport_failure_reason, host);
49
1
  }
50

            
51
  void onPoolReady(Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& conn_data,
52
                   Upstream::HostDescriptionConstSharedPtr host) override;
53

            
54
private:
55
710
  bool resetUpstreamHandleIfSet() {
56
710
    if (upstream_handle_) {
57
153
      upstream_handle_->cancel(Envoy::Tcp::ConnectionPool::CancelPolicy::Default);
58
153
      upstream_handle_ = nullptr;
59
153
      return true;
60
153
    }
61
557
    return false;
62
710
  }
63

            
64
  absl::optional<Envoy::Upstream::TcpPoolData> conn_pool_data_;
65
  Envoy::Tcp::ConnectionPool::Cancellable* upstream_handle_{};
66
  Router::GenericConnectionPoolCallbacks* callbacks_{};
67
};
68

            
69
class TcpUpstream : public Router::GenericUpstream,
70
                    public Envoy::Tcp::ConnectionPool::UpstreamCallbacks {
71
public:
72
  TcpUpstream(Router::UpstreamToDownstream* upstream_request,
73
              Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& upstream);
74

            
75
  // GenericUpstream
76
  void encodeData(Buffer::Instance& data, bool end_stream) override;
77
1
  void encodeMetadata(const Envoy::Http::MetadataMapVector&) override {}
78
  Envoy::Http::Status encodeHeaders(const Envoy::Http::RequestHeaderMap&, bool end_stream) override;
79
  void encodeTrailers(const Envoy::Http::RequestTrailerMap&) override;
80
  void enableTcpTunneling() override {}
81
  void readDisable(bool disable) override;
82
  void resetStream() override;
83
218
  void setAccount(Buffer::BufferMemoryAccountSharedPtr) override {}
84

            
85
  // Tcp::ConnectionPool::UpstreamCallbacks
86
  void onUpstreamData(Buffer::Instance& data, bool end_stream) override;
87
  void onEvent(Network::ConnectionEvent event) override;
88
  void onAboveWriteBufferHighWatermark() override;
89
  void onBelowWriteBufferLowWatermark() override;
90
218
  const StreamInfo::BytesMeterSharedPtr& bytesMeter() override { return bytes_meter_; }
91

            
92
private:
93
  Router::UpstreamToDownstream* upstream_request_;
94
  Envoy::Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_;
95
  StreamInfo::BytesMeterSharedPtr bytes_meter_{std::make_shared<StreamInfo::BytesMeter>()};
96
  bool downstream_complete_ = false;
97
  const bool force_reset_on_upstream_half_close_{};
98
};
99

            
100
} // namespace Tcp
101
} // namespace Http
102
} // namespace Upstreams
103
} // namespace Extensions
104
} // namespace Envoy