1
#pragma once
2

            
3
#include <chrono>
4
#include <cstdint>
5
#include <functional>
6
#include <list>
7
#include <memory>
8
#include <optional>
9
#include <queue>
10
#include <string>
11
#include <vector>
12

            
13
#include "envoy/access_log/access_log.h"
14
#include "envoy/common/optref.h"
15
#include "envoy/common/random_generator.h"
16
#include "envoy/common/scope_tracker.h"
17
#include "envoy/common/time.h"
18
#include "envoy/event/deferred_deletable.h"
19
#include "envoy/http/api_listener.h"
20
#include "envoy/http/codec.h"
21
#include "envoy/http/codes.h"
22
#include "envoy/http/context.h"
23
#include "envoy/http/filter.h"
24
#include "envoy/http/header_map.h"
25
#include "envoy/network/connection.h"
26
#include "envoy/network/drain_decision.h"
27
#include "envoy/network/filter.h"
28
#include "envoy/router/rds.h"
29
#include "envoy/router/scopes.h"
30
#include "envoy/runtime/runtime.h"
31
#include "envoy/server/overload/overload_manager.h"
32
#include "envoy/ssl/connection.h"
33
#include "envoy/stats/scope.h"
34
#include "envoy/stats/stats_macros.h"
35
#include "envoy/stream_info/filter_state.h"
36
#include "envoy/tracing/tracer.h"
37
#include "envoy/upstream/upstream.h"
38

            
39
#include "source/common/buffer/watermark_buffer.h"
40
#include "source/common/common/dump_state_utils.h"
41
#include "source/common/common/linked_object.h"
42
#include "source/common/grpc/common.h"
43
#include "source/common/http/conn_manager_config.h"
44
#include "source/common/http/filter_manager.h"
45
#include "source/common/http/user_agent.h"
46
#include "source/common/http/utility.h"
47
#include "source/common/local_reply/local_reply.h"
48
#include "source/common/network/proxy_protocol_filter_state.h"
49
#include "source/common/stream_info/stream_info_impl.h"
50
#include "source/common/tracing/http_tracer_impl.h"
51

            
52
namespace Envoy {
53
namespace Http {
54

            
55
/**
56
 * Implementation of both ConnectionManager and ServerConnectionCallbacks. This is a
57
 * Network::Filter that can be installed on a connection that will perform HTTP protocol agnostic
58
 * handling of a connection and all requests/pushes that occur on a connection.
59
 */
60
class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
61
                              public Network::ReadFilter,
62
                              public ServerConnectionCallbacks,
63
                              public Network::ConnectionCallbacks,
64
                              public Http::ApiListener {
65
public:
66
  ConnectionManagerImpl(ConnectionManagerConfigSharedPtr config,
67
                        const Network::DrainDecision& drain_close,
68
                        Random::RandomGenerator& random_generator, Http::Context& http_context,
69
                        Runtime::Loader& runtime, const LocalInfo::LocalInfo& local_info,
70
                        Upstream::ClusterManager& cluster_manager,
71
                        Server::OverloadManager& overload_manager, TimeSource& time_system,
72
                        envoy::config::core::v3::TrafficDirection direction);
73
  ~ConnectionManagerImpl() override;
74

            
75
  static ConnectionManagerStats generateStats(const std::string& prefix, Stats::Scope& scope);
76
  static ConnectionManagerTracingStats generateTracingStats(const std::string& prefix,
77
                                                            Stats::Scope& scope);
78
  static void chargeTracingStats(const Tracing::Reason& tracing_reason,
79
                                 ConnectionManagerTracingStats& tracing_stats);
80
  static ConnectionManagerListenerStats generateListenerStats(const std::string& prefix,
81
                                                              Stats::Scope& scope);
82
  static const ResponseHeaderMap& continueHeader();
83

            
84
  // Currently the ConnectionManager creates a codec lazily when either:
85
  //   a) onConnection for H3.
86
  //   b) onData for H1 and H2.
87
  // With the introduction of ApiListeners, neither event occurs. This function allows consumer code
88
  // to manually create a codec.
89
  // TODO(junr03): consider passing a synthetic codec instead of creating once. The codec in the
90
  // ApiListener case is solely used to determine the protocol version.
91
  void createCodec(Buffer::Instance& data);
92

            
93
  // Network::ReadFilter
94
  Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override;
95
  Network::FilterStatus onNewConnection() override;
96
  void initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) override;
97

            
98
  // Http::ConnectionCallbacks
99
  void onGoAway(GoAwayErrorCode error_code) override;
100

            
101
  // Http::ServerConnectionCallbacks
102
  RequestDecoder& newStream(ResponseEncoder& response_encoder,
103
                            bool is_internally_created = false) override;
104

            
105
  RequestDecoderHandlePtr newStreamHandle(ResponseEncoder& response_encoder,
106
                                          bool is_internally_created = false) override;
107

            
108
  // Network::ConnectionCallbacks
109
  void onEvent(Network::ConnectionEvent event) override;
110
  // Pass connection watermark events on to all the streams associated with that connection.
111
6203
  void onAboveWriteBufferHighWatermark() override {
112
6203
    if (codec_) {
113
6202
      codec_->onUnderlyingConnectionAboveWriteBufferHighWatermark();
114
6202
    }
115
6203
  }
116
6201
  void onBelowWriteBufferLowWatermark() override {
117
6201
    if (codec_) {
118
6200
      codec_->onUnderlyingConnectionBelowWriteBufferLowWatermark();
119
6200
    }
120
6201
  }
121

            
122
188193
  TimeSource& timeSource() { return time_source_; }
123

            
124
2
  void setClearHopByHopResponseHeaders(bool value) { clear_hop_by_hop_response_headers_ = value; }
125
1
  bool clearHopByHopResponseHeaders() const { return clear_hop_by_hop_response_headers_; }
126

            
127
  // This runtime key configures the number of streams which must be closed on a connection before
128
  // envoy will potentially drain a connection due to excessive prematurely reset streams.
129
  static const absl::string_view PrematureResetTotalStreamCountKey;
130

            
131
  // The minimum lifetime of a stream, in seconds, in order not to be considered
132
  // prematurely closed.
133
  static const absl::string_view PrematureResetMinStreamLifetimeSecondsKey;
134
  static const absl::string_view MaxRequestsPerIoCycle;
135
  static const absl::string_view OptionallyDelayClose;
136

            
137
private:
138
  struct ActiveStream;
139
  class MobileConnectionManagerImpl;
140

            
141
  /**
142
   * Wraps a single active stream on the connection. These are either full request/response pairs
143
   * or pushes.
144
   */
145
  struct ActiveStream final : LinkedObject<ActiveStream>,
146
                              public Event::DeferredDeletable,
147
                              public StreamCallbacks,
148
                              public CodecEventCallbacks,
149
                              public RequestDecoder,
150
                              public Tracing::Config,
151
                              public ScopeTrackedObject,
152
                              public FilterManagerCallbacks,
153
                              public DownstreamStreamFilterCallbacks,
154
                              public RouteCache {
155
    ActiveStream(ConnectionManagerImpl& connection_manager, uint32_t buffer_limit,
156
                 Buffer::BufferMemoryAccountSharedPtr account);
157

            
158
    // Event::DeferredDeletable
159
94065
    void deleteIsPending() override {
160
      // The stream should not be accessed once deferred delete has been called.
161
94065
      still_alive_.reset();
162
94065
    }
163

            
164
    void log(AccessLog::AccessLogType type);
165
    void completeRequest();
166

            
167
    const Network::Connection* connection();
168
736
    uint64_t streamId() { return stream_id_; }
169

            
170
    // Http::StreamCallbacks
171
    void onResetStream(StreamResetReason reason,
172
                       absl::string_view transport_failure_reason) override;
173
    void onAboveWriteBufferHighWatermark() override;
174
    void onBelowWriteBufferLowWatermark() override;
175

            
176
    // Http::CodecEventCallbacks
177
    void onCodecEncodeComplete() override;
178
    void onCodecLowLevelReset() override;
179

            
180
    // Http::StreamDecoder
181
    void decodeData(Buffer::Instance& data, bool end_stream) override;
182
    void decodeMetadata(MetadataMapPtr&&) override;
183

            
184
    // Record the timestamp of last downstream byte is received.
185
    void maybeRecordLastByteReceived(bool end_stream);
186

            
187
    // Http::RequestDecoder
188
    void decodeHeaders(RequestHeaderMapSharedPtr&& headers, bool end_stream) override;
189
    void decodeTrailers(RequestTrailerMapPtr&& trailers) override;
190
189671
    StreamInfo::StreamInfo& streamInfo() override { return filter_manager_.streamInfo(); }
191
    void sendLocalReply(Code code, absl::string_view body,
192
                        const std::function<void(ResponseHeaderMap& headers)>& modify_headers,
193
                        const absl::optional<Grpc::Status::GrpcStatus> grpc_status,
194
2748
                        absl::string_view details) override {
195
2748
      return filter_manager_.sendLocalReply(code, body, modify_headers, grpc_status, details);
196
2748
    }
197

            
198
18
    void sendGoAwayAndClose(bool graceful = false) override {
199
18
      return connection_manager_.sendGoAwayAndClose(graceful);
200
18
    }
201

            
202
2527
    AccessLog::InstanceSharedPtrVector accessLogHandlers() override {
203
2527
      const AccessLog::InstanceSharedPtrVector& config_log_handlers =
204
2527
          connection_manager_.config_->accessLogs();
205
2527
      const AccessLog::InstanceSharedPtrVector& filter_log_handlers =
206
2527
          filter_manager_.accessLogHandlers();
207

            
208
2527
      AccessLog::InstanceSharedPtrVector combined_log_handlers;
209
2527
      combined_log_handlers.reserve(config_log_handlers.size() + filter_log_handlers.size());
210
2527
      combined_log_handlers.insert(combined_log_handlers.end(), config_log_handlers.begin(),
211
2527
                                   config_log_handlers.end());
212
2527
      combined_log_handlers.insert(combined_log_handlers.end(), filter_log_handlers.begin(),
213
2527
                                   filter_log_handlers.end());
214
2527
      return combined_log_handlers;
215
2527
    }
216

            
217
77254
    RequestDecoderHandlePtr getRequestDecoderHandle() override {
218
77254
      return std::make_unique<ActiveStreamHandle>(*this);
219
77254
    }
220

            
221
    // Hand off headers/trailers and stream info to the codec's response encoder, for logging later
222
    // (i.e. possibly after this stream has been destroyed).
223
    //
224
    // TODO(paulsohn): Investigate whether we can move the headers/trailers and stream info required
225
    // for logging instead of copying them (as is currently done in the HTTP/3 implementation) or
226
    // using a shared pointer. See
227
    // https://github.com/envoyproxy/envoy/pull/23648#discussion_r1066095564 for more details.
228
1508
    void deferHeadersAndTrailers() {
229
1508
      response_encoder_->setDeferredLoggingHeadersAndTrailers(request_headers_, response_headers_,
230
1508
                                                              response_trailers_, streamInfo());
231
1508
    }
232

            
233
    // ScopeTrackedObject
234
    OptRef<const StreamInfo::StreamInfo> trackedStream() const override {
235
      return filter_manager_.trackedStream();
236
    }
237
2
    void dumpState(std::ostream& os, int indent_level = 0) const override {
238
2
      const char* spaces = spacesForLevel(indent_level);
239
2
      os << spaces << "ActiveStream " << this << DUMP_MEMBER(stream_id_);
240

            
241
2
      DUMP_DETAILS(&filter_manager_);
242
2
    }
243

            
244
    // FilterManagerCallbacks
245
    void encodeHeaders(ResponseHeaderMap& response_headers, bool end_stream) override;
246
    void encode1xxHeaders(ResponseHeaderMap& response_headers) override;
247
    void encodeData(Buffer::Instance& data, bool end_stream) override;
248
    void encodeTrailers(ResponseTrailerMap& trailers) override;
249
    void encodeMetadata(MetadataMapPtr&& metadata) override;
250
24
    void setRequestTrailers(Http::RequestTrailerMapPtr&& request_trailers) override {
251
24
      ASSERT(!request_trailers_);
252
24
      request_trailers_ = std::move(request_trailers);
253
24
    }
254
132
    void setInformationalHeaders(Http::ResponseHeaderMapPtr&& informational_headers) override {
255
132
      ASSERT(!informational_headers_);
256
132
      informational_headers_ = std::move(informational_headers);
257
132
    }
258
47746
    void setResponseHeaders(Http::ResponseHeaderMapPtr&& response_headers) override {
259
47746
      if (response_headers_ != nullptr) {
260
233
        overwritten_headers_.emplace_back(std::move(response_headers_));
261
233
      }
262
47746
      response_headers_ = std::move(response_headers);
263
47746
    }
264
450
    void setResponseTrailers(Http::ResponseTrailerMapPtr&& response_trailers) override {
265
450
      if (response_trailers_ != nullptr) {
266
        overwritten_headers_.emplace_back(std::move(response_trailers_));
267
      }
268
450
      response_trailers_ = std::move(response_trailers);
269
450
    }
270
    void chargeStats(const ResponseHeaderMap& headers) override;
271

            
272
488648
    Http::RequestHeaderMapOptRef requestHeaders() override {
273
488648
      return makeOptRefFromPtr(request_headers_.get());
274
488648
    }
275
540665
    Http::RequestTrailerMapOptRef requestTrailers() override {
276
540665
      return makeOptRefFromPtr(request_trailers_.get());
277
540665
    }
278
9727
    Http::ResponseHeaderMapOptRef informationalHeaders() override {
279
9727
      return makeOptRefFromPtr(informational_headers_.get());
280
9727
    }
281
105929
    Http::ResponseHeaderMapOptRef responseHeaders() override {
282
105929
      return makeOptRefFromPtr(response_headers_.get());
283
105929
    }
284
98082
    Http::ResponseTrailerMapOptRef responseTrailers() override {
285
98082
      return makeOptRefFromPtr(response_trailers_.get());
286
98082
    }
287

            
288
46634
    void endStream() override {
289
46634
      ASSERT(!state_.codec_saw_local_complete_);
290
46634
      state_.codec_saw_local_complete_ = true;
291
46634
      connection_manager_.doEndStream(*this);
292
46634
    }
293
    void onDecoderFilterBelowWriteBufferLowWatermark() override;
294
    void onDecoderFilterAboveWriteBufferHighWatermark() override;
295
    void disarmRequestTimeout() override;
296
    void resetIdleTimer() override;
297
    void recreateStream(StreamInfo::FilterStateSharedPtr filter_state) override;
298
    void resetStream(Http::StreamResetReason reset_reason = Http::StreamResetReason::LocalReset,
299
                     absl::string_view transport_failure_reason = "") override;
300
    const Router::RouteEntry::UpgradeMap* upgradeMap() override;
301
    Upstream::ClusterInfoConstSharedPtr clusterInfo() override;
302
    Tracing::Span& activeSpan() override;
303
    void onResponseDataTooLarge() override;
304
    void onRequestDataTooLarge() override;
305
    Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override;
306
    void onLocalReply(Code code) override;
307
    OptRef<const Tracing::Config> tracingConfig() const override;
308
    const ScopeTrackedObject& scope() override;
309
387233
    OptRef<DownstreamStreamFilterCallbacks> downstreamCallbacks() override { return *this; }
310
145066
    bool isHalfCloseEnabled() override { return connection_manager_.allow_upstream_half_close_; }
311

            
312
    // DownstreamStreamFilterCallbacks
313
    void setRoute(Router::RouteConstSharedPtr route) override;
314
    Router::RouteConstSharedPtr route(const Router::RouteCallback& cb) override;
315
    void clearRouteCache() override;
316
    void refreshRouteCluster() override;
317
    void requestRouteConfigUpdate(
318
        Http::RouteConfigUpdatedCallbackSharedPtr route_config_updated_cb) override;
319

            
320
    void setVirtualHostRoute(Router::VirtualHostRoute route);
321
    // Set cached route. This method should never be called directly. This is only called in the
322
    // setRoute(), clearRouteCache(), and refreshCachedRoute() methods.
323
    void setCachedRoute(absl::optional<Router::RouteConstSharedPtr>&& route);
324
    // Block the route cache and clear the snapped route config. By doing this the route cache will
325
    // not be updated. And if the route config is updated by the RDS, the snapped route config may
326
    // be freed before the stream is destroyed.
327
    // This will be called automatically at the end of handle response headers.
328
    void blockRouteCache();
329
    // Return true if the cached route is blocked.
330
187724
    bool routeCacheBlocked() const {
331
187724
      ENVOY_BUG(!route_cache_blocked_, "Should never try to refresh or clear the route cache when "
332
187724
                                       "it is blocked!");
333
187724
      return route_cache_blocked_;
334
187724
    }
335

            
336
    absl::optional<Router::ConfigConstSharedPtr> routeConfig();
337
    void traceRequest();
338

            
339
    // Updates the snapped_route_config_ (by reselecting scoped route configuration), if a scope is
340
    // not found, snapped_route_config_ is set to Router::NullConfigImpl.
341
    void snapScopedRouteConfig();
342

            
343
    void refreshCachedRoute(const Router::RouteCallback& cb);
344

            
345
    void refreshDurationTimeout();
346
    void refreshIdleAndFlushTimeouts();
347
    void refreshAccessLogFlushTimer();
348
    void refreshTracing();
349
    void refreshBufferLimit();
350

            
351
    void setRequestDecorator(RequestHeaderMap& headers);
352
    void setResponseDecorator(ResponseHeaderMap& headers);
353

            
354
    // All state for the stream. Put here for readability.
355
    struct State {
356
      // It's possibly for the codec to see the completed response but not fully
357
      // encode it.
358
      bool codec_saw_local_complete_ : 1 = false; // This indicates that local is complete
359
                                                  // as the completed
360
                                                  // response has made its way to the codec.
361
      bool codec_encode_complete_ : 1 = false;    // This indicates that the codec has
362
                                                  // completed encoding the response.
363
      bool on_reset_stream_called_ : 1 = false;   // Whether the stream has been reset.
364
      bool is_zombie_stream_ : 1 = false;         // Whether stream is waiting for signal
365
                                                  // the underlying codec to be destroyed.
366
      bool successful_upgrade_ : 1 = false;
367

            
368
      // True if this stream was the original externally created stream, but was
369
      // destroyed as part of internal redirect.
370
      bool is_internally_destroyed_ : 1 = false;
371
      // True if this stream is internally created. Currently only used for
372
      // internal redirects or other streams created via recreateStream().
373
      bool is_internally_created_ : 1 = false;
374

            
375
      // True if the response headers indicate a successful upgrade or connect
376
      // response.
377
      bool is_tunneling_ : 1 = false;
378

            
379
      bool decorated_propagate_ : 1 = true;
380

            
381
      // True if the decorator operation is overridden by the request header.
382
      bool decorator_overriden_ : 1 = false;
383

            
384
      // Indicates that sending headers to the filter manager is deferred to the
385
      // next I/O cycle. If data or trailers are received when this flag is set
386
      // they are deferred too.
387
      // TODO(yanavlasov): encapsulate the entire state of deferred streams into a separate
388
      // structure, so it can be atomically created and cleared.
389
      bool deferred_to_next_io_iteration_ : 1 = false;
390
      bool deferred_end_stream_ : 1 = false;
391
    };
392

            
393
97061
    bool canDestroyStream() const {
394
97061
      return state_.on_reset_stream_called_ || state_.codec_encode_complete_ ||
395
97061
             state_.is_internally_destroyed_;
396
97061
    }
397

            
398
    // Computes whether to skip the delay when closing a draining connection.
399
    // Returns true if we should use FlushWrite (immediate close after flush),
400
    // false if we should use FlushWriteAndDelay (close with delay).
401
    // See https://github.com/envoyproxy/envoy/issues/30010 for background.
402
    bool shouldSkipDeferredCloseDelay() const;
403

            
404
    // Per-stream idle timeout callback.
405
    void onIdleTimeout();
406
    // Per-stream request timeout callback.
407
    void onRequestTimeout();
408
    // Per-stream request header timeout callback.
409
    void onRequestHeaderTimeout();
410
    // Per-stream alive duration reached.
411
    void onStreamMaxDurationReached();
412

            
413
    // RouteCache
414
465711
    bool hasCachedRoute() const override {
415
465711
      return cached_route_.has_value() && cached_route_.value();
416
465711
    }
417
    void refreshCachedRoute() override;
418

            
419
    // Return local port of the connection.
420
    uint32_t localPort();
421

            
422
    friend std::ostream& operator<<(std::ostream& os, const ActiveStream& s) {
423
      s.dumpState(os);
424
      return os;
425
    }
426

            
427
    // Note: this method is a noop unless ENVOY_ENABLE_UHV is defined
428
    // Call header validator extension to validate request header map after it was deserialized.
429
    // If header map failed validation, it sends an error response and returns false.
430
    bool validateHeaders();
431

            
432
    // Note: this method is a noop unless ENVOY_ENABLE_UHV is defined
433
    // Call header validator extension to validate the request trailer map after it was
434
    // deserialized. If the trailer map failed validation, this method does the following:
435
    // 1. For H/1 it sends 400 response and returns false.
436
    // 2. For H/2 and H/3 it resets the stream (without error response). Issue #24735 is filed to
437
    //    harmonize this behavior with H/1.
438
    // 3. If the `stream_error_on_invalid_http_message` is set to `false` (it is by default) in the
439
    // HTTP connection manager configuration, then the entire connection is closed.
440
    bool validateTrailers(RequestTrailerMap& trailers);
441

            
442
77260
    std::weak_ptr<bool> stillAlive() { return {still_alive_}; }
443

            
444
    // Dispatch deferred headers, body and trailers to the filter manager.
445
    // Return true if this stream was deferred and dispatched pending headers, body and trailers (if
446
    // present). Return false if this stream was not deferred.
447
    bool onDeferredRequestProcessing();
448

            
449
    ConnectionManagerImpl& connection_manager_;
450
    OptRef<const TracingConnectionManagerConfig> connection_manager_tracing_config_;
451
    // TODO(snowp): It might make sense to move this to the FilterManager to avoid storing it in
452
    // both locations, then refer to the FM when doing stream logs.
453
    const uint64_t stream_id_;
454

            
455
    RequestHeaderMapSharedPtr request_headers_;
456
    RequestTrailerMapPtr request_trailers_;
457

            
458
    ResponseHeaderMapPtr informational_headers_;
459
    ResponseHeaderMapSharedPtr response_headers_;
460
    ResponseTrailerMapSharedPtr response_trailers_;
461

            
462
    // Keep track all the historical headers to avoid potential lifetime issues.
463
    // For example,
464
    // when Envoy processing a response, if we send a local reply, then the local reply
465
    // headers will overwrite the original response and result in the previous response
466
    // being dangling. To avoid this, we store the original headers.
467
    std::vector<std::shared_ptr<HeaderMap>> overwritten_headers_;
468

            
469
    // Note: The FM must outlive the above headers, as they are possibly accessed during filter
470
    // destruction.
471
    DownstreamFilterManager filter_manager_;
472

            
473
    Tracing::SpanPtr active_span_;
474
    ResponseEncoder* response_encoder_{};
475
    Stats::TimespanPtr request_response_timespan_;
476
    // Per-stream idle timeout. This timer gets reset whenever activity occurs on the stream, and,
477
    // when triggered, will close the stream.
478
    Event::TimerPtr stream_idle_timer_;
479
    // Per-stream request timeout. This timer is enabled when the stream is created and disabled
480
    // when the stream ends. If triggered, it will close the stream.
481
    Event::TimerPtr request_timer_;
482
    // Per-stream request header timeout. This timer is enabled when the stream is created and
483
    // disabled when the downstream finishes sending headers. If triggered, it will close the
484
    // stream.
485
    Event::TimerPtr request_header_timer_;
486
    // Per-stream alive duration. This timer is enabled once when the stream is created and, if
487
    // triggered, will close the stream.
488
    Event::TimerPtr max_stream_duration_timer_;
489
    // Per-stream access log flush duration. This timer is enabled once when the stream is created
490
    // and will log to all access logs once per trigger.
491
    Event::TimerPtr access_log_flush_timer_;
492

            
493
    std::chrono::milliseconds idle_timeout_ms_{};
494
    // If an explicit global flush timeout is set, never override it with the route entry idle
495
    // timeout. If there is no explicit global flush timeout, then override with the route entry
496
    // idle timeout if it exists. This is to prevent breaking existing user expectations that the
497
    // flush timeout is the same as the idle timeout.
498
    const bool has_explicit_global_flush_timeout_{false};
499
    State state_;
500

            
501
    // Snapshot of the route configuration at the time of request is started. This is used to ensure
502
    // that the same route configuration is used throughout the lifetime of the request. This
503
    // snapshot will be cleared when the cached route is blocked. Because after that we will not
504
    // refresh the cached route and release this snapshot can help to release the memory when the
505
    // route configuration is updated frequently and the request is long-lived.
506
    Router::ConfigConstSharedPtr snapped_route_config_;
507
    Router::ScopedConfigConstSharedPtr snapped_scoped_routes_config_;
508
    // This is used to track the route that has been cached in the request. And we will keep this
509
    // route alive until the request is finished.
510
    absl::optional<Router::RouteConstSharedPtr> cached_route_;
511
    // This is used to track whether the route has been blocked. If the route is blocked, we can not
512
    // clear it or refresh it.
513
    bool route_cache_blocked_{false};
514
    // This is used to track routes that have been cleared from the request. By this way, all the
515
    // configurations that have been used in the processing of the request will be alive until the
516
    // request is finished.
517
    // For example, if a filter stored a per-route config in the decoding phase and may try to
518
    // use it in the encoding phase, but the route is cleared and refreshed by another decoder
519
    // filter, we must keep the per-route config alive to avoid use-after-free.
520
    // Note that we assume that the number of routes that have been cleared is small. So we use
521
    // inline vector to avoid heap allocation. If this assumption is wrong, we should consider using
522
    // a list or other data structures.
523
    //
524
    // TODO(wbpcode): This is a helpless compromise. To avoid exposing the complexity of the route
525
    // lifetime management to every HTTP filter, we do a hack here. But if every filter could manage
526
    // the lifetime of the route config by itself easily, we could remove this hack.
527
    absl::InlinedVector<Router::RouteConstSharedPtr, 3> cleared_cached_routes_;
528

            
529
    absl::optional<Upstream::ClusterInfoConstSharedPtr> cached_cluster_info_;
530
    absl::optional<std::unique_ptr<RouteConfigUpdateRequester>> route_config_update_requester_;
531
    Http::ServerHeaderValidatorPtr header_validator_;
532

            
533
    friend FilterManager;
534

            
535
  private:
536
    // Keep these methods private to ensure that these methods are only called by the reference
537
    // returned by the public tracingConfig() method.
538
    // Tracing::TracingConfig
539
    Tracing::OperationName operationName() const override;
540
    void modifySpan(Tracing::Span& span, bool upstream_span) const override;
541
    bool verbose() const override;
542
    uint32_t maxPathTagLength() const override;
543
    bool spawnUpstreamSpan() const override;
544
    bool noContextPropagation() const override;
545

            
546
    std::shared_ptr<bool> still_alive_ = std::make_shared<bool>(true);
547
    std::unique_ptr<Buffer::OwnedImpl> deferred_data_;
548
    std::queue<MetadataMapPtr> deferred_metadata_;
549
    RequestTrailerMapPtr deferred_request_trailers_;
550
    const Router::Decorator* route_decorator_{nullptr};
551
    const Router::RouteTracing* route_tracing_{nullptr};
552
    const bool trace_refresh_after_route_refresh_{true};
553
  };
554

            
555
  using ActiveStreamPtr = std::unique_ptr<ActiveStream>;
556

            
557
  class ActiveStreamHandle : public RequestDecoderHandle {
558
  public:
559
    explicit ActiveStreamHandle(ActiveStream& stream)
560
77260
        : valid_(stream.stillAlive()), stream_(stream) {}
561

            
562
77260
    ~ActiveStreamHandle() override = default;
563

            
564
316565
    OptRef<RequestDecoder> get() override {
565
316565
      if (valid_.expired()) {
566
2
        return {};
567
2
      }
568
316563
      return stream_;
569
316565
    }
570

            
571
  private:
572
    std::weak_ptr<bool> valid_;
573
    ActiveStream& stream_;
574
  };
575

            
576
  class HttpStreamIdProviderImpl : public StreamInfo::StreamIdProvider {
577
  public:
578
94065
    HttpStreamIdProviderImpl(ActiveStream& parent) : parent_(parent) {}
579

            
580
    // StreamInfo::StreamIdProvider
581
    absl::optional<absl::string_view> toStringView() const override;
582
    absl::optional<uint64_t> toInteger() const override;
583

            
584
    ActiveStream& parent_;
585
  };
586

            
587
  /**
588
   * Check to see if the connection can be closed after gracefully waiting to send pending codec
589
   * data.
590
   */
591
  void checkForDeferredClose(bool skip_deferred_close);
592

            
593
  /**
594
   * Do a delayed destruction of a stream to allow for stack unwind. Also calls onDestroy() for
595
   * each filter.
596
   */
597
  void doDeferredStreamDestroy(ActiveStream& stream);
598

            
599
  /**
600
   * Process a stream that is ending due to upstream response or reset.
601
   * If check_for_deferred_close is true, the ConnectionManager will check to
602
   * see if the connection was drained and should be closed if no streams remain.
603
   */
604
  void doEndStream(ActiveStream& stream, bool check_for_deferred_close = true);
605

            
606
  void resetAllStreams(absl::optional<StreamInfo::CoreResponseFlag> response_flag,
607
                       absl::string_view details);
608
  void onIdleTimeout();
609
  void onConnectionDurationTimeout();
610
  void onDrainTimeout();
611
  void startDrainSequence();
612
298
  Tracing::Tracer& tracer() { return *config_->tracer(); }
613
  void handleCodecErrorImpl(absl::string_view error, absl::string_view details,
614
                            StreamInfo::CoreResponseFlag response_flag);
615
  void handleCodecError(absl::string_view error);
616
  void handleCodecOverloadError(absl::string_view error);
617
  void doConnectionClose(absl::optional<Network::ConnectionCloseType> close_type,
618
                         absl::optional<StreamInfo::CoreResponseFlag> response_flag,
619
                         absl::string_view details);
620
  void sendGoAwayAndClose(bool graceful = false);
621

            
622
  // Returns true if a RST_STREAM for the given stream is premature. Premature
623
  // means the RST_STREAM arrived before response headers were sent and than
624
  // the stream was alive for short period of time. This period is specified
625
  // by the optional runtime value PrematureResetMinStreamLifetimeSecondsKey,
626
  // or one second if that is not present.
627
  bool isPrematureRstStream(const ActiveStream& stream) const;
628
  // Sends a GOAWAY if both sufficient streams have been closed on a connection
629
  // and at least half have been prematurely reset?
630
  void maybeDrainDueToPrematureResets();
631

            
632
  bool shouldDeferRequestProxyingToNextIoCycle();
633
  void onDeferredRequestProcessing();
634

            
635
  enum class DrainState { NotDraining, Draining, Closing };
636

            
637
  ConnectionManagerConfigSharedPtr config_;
638
  ConnectionManagerStats& stats_; // We store a reference here to avoid an extra stats() call on
639
                                  // the config in the hot path.
640
  ServerConnectionPtr codec_;
641
  std::list<ActiveStreamPtr> streams_;
642
  Stats::TimespanPtr conn_length_;
643
  const Network::DrainDecision& drain_close_;
644
  DrainState drain_state_{DrainState::NotDraining};
645
  UserAgent user_agent_;
646
  // An idle timer for the connection. This is only armed when there are no streams on the
647
  // connection. When there are active streams it is disarmed in favor of each stream's
648
  // stream_idle_timer_.
649
  Event::TimerPtr connection_idle_timer_;
650
  // A connection duration timer. Armed during handling new connection if enabled in config.
651
  Event::TimerPtr connection_duration_timer_;
652
  Event::TimerPtr drain_timer_;
653
  // When set to true, add Connection:close response header to nudge downstream client to reconnect.
654
  bool soft_drain_http1_{false};
655
  Random::RandomGenerator& random_generator_;
656
  Runtime::Loader& runtime_;
657
  const LocalInfo::LocalInfo& local_info_;
658
  Upstream::ClusterManager& cluster_manager_;
659
  Network::ReadFilterCallbacks* read_callbacks_{};
660
  Event::Dispatcher* dispatcher_{};
661
  ConnectionManagerListenerStats& listener_stats_;
662
  Server::OverloadManager& overload_manager_;
663
  Server::ThreadLocalOverloadState& overload_state_;
664
  Server::LoadShedPoint* accept_new_http_stream_{nullptr};
665
  Server::LoadShedPoint* hcm_ondata_creating_codec_{nullptr};
666
  // References into the overload manager thread local state map. Using these lets us avoid a
667
  // map lookup in the hot path of processing each request.
668
  const Server::OverloadActionState& overload_stop_accepting_requests_ref_;
669
  const Server::OverloadActionState& overload_disable_keepalive_ref_;
670
  TimeSource& time_source_;
671
  bool go_away_sent_{false};
672
  bool remote_close_{};
673
  // Hop by hop headers should always be cleared for Envoy-as-a-proxy but will
674
  // not be for Envoy-mobile.
675
  bool clear_hop_by_hop_response_headers_{true};
676
  // The number of requests accumulated on the current connection.
677
  uint64_t accumulated_requests_{};
678
  // The number of requests closed on the current connection which were
679
  // not internally destroyed
680
  uint64_t closed_non_internally_destroyed_requests_{};
681
  // The number of requests that received a premature RST_STREAM, according to
682
  // the definition given in `isPrematureRstStream()`.
683
  uint64_t number_premature_stream_resets_{0};
684
  const std::string proxy_name_; // for Proxy-Status.
685
  uint32_t requests_during_dispatch_count_{0};
686
  const uint32_t max_requests_during_dispatch_{UINT32_MAX};
687
  Event::SchedulableCallbackPtr deferred_request_processing_callback_;
688
  const envoy::config::core::v3::TrafficDirection direction_;
689

            
690
  // If independent half-close is enabled and the upstream protocol is either HTTP/2 or HTTP/3
691
  // protocols the stream is destroyed after both request and response are complete i.e. reach their
692
  // respective end-of-stream, by receiving trailers or the header/body with end-stream set in both
693
  // directions AND response has success (2xx) status code.
694
  //
695
  // For HTTP/1 upstream protocol or if independent half-close is disabled the stream is destroyed
696
  // when the response is complete and reaches its end-of-stream, i.e. when trailers or the response
697
  // header/body with end-stream set are received, even if the request has not yet completed. If
698
  // request was incomplete at response completion, the stream is reset.
699

            
700
  const bool allow_upstream_half_close_{};
701
  // Whether to call checkForDeferredClose() when zombie streams complete.
702
  // This fixes a potential FD leak where connections with zombie streams in draining state
703
  // would not be properly closed.
704
  const bool close_connection_on_zombie_stream_complete_{};
705

            
706
  // Whether the connection manager is drained due to premature resets.
707
  bool drained_due_to_premature_resets_{false};
708
};
709

            
710
} // namespace Http
711
} // namespace Envoy