Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/tcp/conn_pool.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <list>
4
#include <memory>
5
6
#include "envoy/event/deferred_deletable.h"
7
#include "envoy/event/timer.h"
8
#include "envoy/network/connection.h"
9
#include "envoy/network/filter.h"
10
#include "envoy/stats/timespan.h"
11
#include "envoy/tcp/conn_pool.h"
12
#include "envoy/upstream/upstream.h"
13
14
#include "source/common/common/linked_object.h"
15
#include "source/common/common/logger.h"
16
#include "source/common/http/conn_pool_base.h"
17
#include "source/common/network/filter_impl.h"
18
#include "source/common/runtime/runtime_features.h"
19
20
namespace Envoy {
21
namespace Tcp {
22
23
class ConnPoolImpl;
24
25
struct TcpAttachContext : public Envoy::ConnectionPool::AttachContext {
26
0
  TcpAttachContext(Tcp::ConnectionPool::Callbacks* callbacks) : callbacks_(callbacks) {}
27
  Tcp::ConnectionPool::Callbacks* callbacks_;
28
};
29
30
class TcpPendingStream : public Envoy::ConnectionPool::PendingStream {
31
public:
32
  TcpPendingStream(Envoy::ConnectionPool::ConnPoolImplBase& parent, bool can_send_early_data,
33
                   TcpAttachContext& context)
34
0
      : Envoy::ConnectionPool::PendingStream(parent, can_send_early_data), context_(context) {}
35
0
  Envoy::ConnectionPool::AttachContext& context() override { return context_; }
36
37
  TcpAttachContext context_;
38
};
39
40
class ActiveTcpClient : public Envoy::ConnectionPool::ActiveClient {
41
public:
42
  struct ConnReadFilter : public Network::ReadFilterBaseImpl {
43
0
    ConnReadFilter(ActiveTcpClient& parent) : parent_(parent) {}
44
45
    // Network::ReadFilter
46
0
    Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override {
47
0
      parent_.onUpstreamData(data, end_stream);
48
0
      return Network::FilterStatus::StopIteration;
49
0
    }
50
    ActiveTcpClient& parent_;
51
  };
52
53
  // This acts as the bridge between the ActiveTcpClient and an individual TCP connection.
54
  class TcpConnectionData : public Envoy::Tcp::ConnectionPool::ConnectionData {
55
  public:
56
    TcpConnectionData(ActiveTcpClient& parent, Network::ClientConnection& connection)
57
0
        : parent_(&parent), connection_(connection) {
58
0
      parent_->tcp_connection_data_ = this;
59
0
    }
60
0
    ~TcpConnectionData() override {
61
      // Generally it is the case that TcpConnectionData will be destroyed before the
62
      // ActiveTcpClient. Because ordering on the deferred delete list is not guaranteed in the
63
      // case of a disconnect, make sure parent_ is valid before doing clean-up.
64
0
      if (parent_) {
65
0
        parent_->clearCallbacks();
66
0
      }
67
0
    }
68
69
0
    Network::ClientConnection& connection() override { return connection_; }
70
0
    void setConnectionState(ConnectionPool::ConnectionStatePtr&& state) override {
71
0
      parent_->connection_state_ = std::move(state);
72
0
    }
73
74
0
    void addUpstreamCallbacks(ConnectionPool::UpstreamCallbacks& callbacks) override {
75
0
      parent_->callbacks_ = &callbacks;
76
0
    }
77
0
    void release() { parent_ = nullptr; }
78
79
  protected:
80
0
    ConnectionPool::ConnectionState* connectionState() override {
81
0
      return parent_->connection_state_.get();
82
0
    }
83
84
  private:
85
    ActiveTcpClient* parent_;
86
    Network::ClientConnection& connection_;
87
  };
88
89
  ActiveTcpClient(Envoy::ConnectionPool::ConnPoolImplBase& parent,
90
                  const Upstream::HostConstSharedPtr& host, uint64_t concurrent_stream_limit,
91
                  absl::optional<std::chrono::milliseconds> idle_timeout);
92
  ~ActiveTcpClient() override;
93
94
  // Override the default's of Envoy::ConnectionPool::ActiveClient for class-specific functions.
95
  // Network::ConnectionCallbacks
96
  void onEvent(Network::ConnectionEvent event) override;
97
0
  void onAboveWriteBufferHighWatermark() override { callbacks_->onAboveWriteBufferHighWatermark(); }
98
0
  void onBelowWriteBufferLowWatermark() override { callbacks_->onBelowWriteBufferLowWatermark(); }
99
100
  // Undos the readDisable done in onEvent(Connected)
101
  void readEnableIfNew();
102
103
0
  void initializeReadFilters() override { connection_->initializeReadFilters(); }
104
0
  absl::optional<Http::Protocol> protocol() const override { return {}; }
105
  void close() override;
106
0
  uint32_t numActiveStreams() const override { return callbacks_ ? 1 : 0; }
107
0
  bool closingWithIncompleteStream() const override { return false; }
108
0
  uint64_t id() const override { return connection_->id(); }
109
110
0
  void onUpstreamData(Buffer::Instance& data, bool end_stream) {
111
0
    if (callbacks_) {
112
0
      callbacks_->onUpstreamData(data, end_stream);
113
0
    } else {
114
0
      close();
115
0
    }
116
0
  }
117
  virtual void clearCallbacks();
118
119
  // Called if the underlying connection is idle over the cluster's tcpPoolIdleTimeout()
120
  void onIdleTimeout();
121
  void disableIdleTimer();
122
  void setIdleTimer();
123
124
  std::shared_ptr<ConnReadFilter> read_filter_handle_;
125
  Envoy::ConnectionPool::ConnPoolImplBase& parent_;
126
  ConnectionPool::UpstreamCallbacks* callbacks_{};
127
  Network::ClientConnectionPtr connection_;
128
  ConnectionPool::ConnectionStatePtr connection_state_;
129
  TcpConnectionData* tcp_connection_data_{};
130
  bool associated_before_{};
131
  absl::optional<std::chrono::milliseconds> idle_timeout_;
132
  Event::TimerPtr idle_timer_;
133
};
134
135
class ConnPoolImpl : public Envoy::ConnectionPool::ConnPoolImplBase,
136
                     public Tcp::ConnectionPool::Instance {
137
public:
138
  ConnPoolImpl(Event::Dispatcher& dispatcher, Upstream::HostConstSharedPtr host,
139
               Upstream::ResourcePriority priority,
140
               const Network::ConnectionSocket::OptionsSharedPtr& options,
141
               Network::TransportSocketOptionsConstSharedPtr transport_socket_options,
142
               Upstream::ClusterConnectivityState& state,
143
               absl::optional<std::chrono::milliseconds> idle_timeout)
144
      : Envoy::ConnectionPool::ConnPoolImplBase(host, priority, dispatcher, options,
145
                                                transport_socket_options, state),
146
0
        idle_timeout_(idle_timeout) {}
147
0
  ~ConnPoolImpl() override { destructAllConnections(); }
148
149
  // Event::DeferredDeletable
150
0
  void deleteIsPending() override { deleteIsPendingImpl(); }
151
152
0
  void addIdleCallback(IdleCb cb) override { addIdleCallbackImpl(cb); }
153
0
  bool isIdle() const override { return isIdleImpl(); }
154
  void drainConnections(Envoy::ConnectionPool::DrainBehavior drain_behavior) override;
155
  void closeConnections() override;
156
  ConnectionPool::Cancellable* newConnection(Tcp::ConnectionPool::Callbacks& callbacks) override;
157
0
  bool maybePreconnect(float preconnect_ratio) override {
158
0
    return maybePreconnectImpl(preconnect_ratio);
159
0
  }
160
  ConnectionPool::Cancellable* newPendingStream(Envoy::ConnectionPool::AttachContext& context,
161
                                                bool can_send_early_data) override;
162
0
  Upstream::HostDescriptionConstSharedPtr host() const override {
163
0
    return Envoy::ConnectionPool::ConnPoolImplBase::host();
164
0
  }
165
  Envoy::ConnectionPool::ActiveClientPtr instantiateActiveClient() override;
166
  void onPoolReady(Envoy::ConnectionPool::ActiveClient& client,
167
                   Envoy::ConnectionPool::AttachContext& context) override;
168
  void onPoolFailure(const Upstream::HostDescriptionConstSharedPtr& host_description,
169
                     absl::string_view failure_reason, ConnectionPool::PoolFailureReason reason,
170
                     Envoy::ConnectionPool::AttachContext& context) override;
171
0
  bool enforceMaxRequests() const override { return false; }
172
  // These two functions exist for testing parity between old and new Tcp Connection Pools.
173
0
  virtual void onConnReleased(Envoy::ConnectionPool::ActiveClient&) {}
174
0
  virtual void onConnDestroyed() {}
175
176
  absl::optional<std::chrono::milliseconds> idle_timeout_;
177
};
178
179
} // namespace Tcp
180
} // namespace Envoy