1
#pragma once
2

            
3
#include <cstdint>
4
#include <functional>
5
#include <list>
6
#include <memory>
7
#include <ostream>
8
#include <string>
9
#include <vector>
10

            
11
#include "envoy/buffer/buffer.h"
12
#include "envoy/common/random_generator.h"
13
#include "envoy/common/scope_tracker.h"
14
#include "envoy/config/core/v3/protocol.pb.h"
15
#include "envoy/event/deferred_deletable.h"
16
#include "envoy/http/codec.h"
17
#include "envoy/network/connection.h"
18
#include "envoy/server/overload/overload_manager.h"
19

            
20
#include "source/common/buffer/buffer_impl.h"
21
#include "source/common/common/assert.h"
22
#include "source/common/common/linked_object.h"
23
#include "source/common/common/logger.h"
24
#include "source/common/http/codec_helper.h"
25
#include "source/common/http/header_map_impl.h"
26
#include "source/common/http/http2/codec_stats.h"
27
#include "source/common/http/http2/metadata_decoder.h"
28
#include "source/common/http/http2/metadata_encoder.h"
29
#include "source/common/http/http2/protocol_constraints.h"
30
#include "source/common/http/status.h"
31

            
32
#include "absl/types/optional.h"
33
#include "absl/types/span.h"
34

            
35
#ifdef ENVOY_NGHTTP2
36
#include "nghttp2/nghttp2.h"
37
#endif
38
#include "quiche/http2/adapter/http2_adapter.h"
39
#include "quiche/http2/adapter/http2_protocol.h"
40
#include "quiche/http2/adapter/oghttp2_adapter.h"
41

            
42
namespace Envoy {
43
namespace Http {
44
namespace Http2 {
45

            
46
// Types inherited from nghttp2 and preserved in oghttp2
47
enum ErrorType {
48
  OGHTTP2_NO_ERROR,
49
  OGHTTP2_PROTOCOL_ERROR,
50
  OGHTTP2_INTERNAL_ERROR,
51
  OGHTTP2_FLOW_CONTROL_ERROR,
52
  OGHTTP2_SETTINGS_TIMEOUT,
53
  OGHTTP2_STREAM_CLOSED,
54
  OGHTTP2_FRAME_SIZE_ERROR,
55
  OGHTTP2_REFUSED_STREAM,
56
  OGHTTP2_CANCEL,
57
  OGHTTP2_COMPRESSION_ERROR,
58
  OGHTTP2_CONNECT_ERROR,
59
  OGHTTP2_ENHANCE_YOUR_CALM,
60
  OGHTTP2_INADEQUATE_SECURITY,
61
  OGHTTP2_HTTP_1_1_REQUIRED,
62
};
63

            
64
class Http2CodecImplTestFixture;
65

            
66
// This is not the full client magic, but it's the smallest size that should be able to
67
// differentiate between HTTP/1 and HTTP/2.
68
const std::string CLIENT_MAGIC_PREFIX = "PRI * HTTP/2";
69
constexpr uint64_t H2_FRAME_HEADER_SIZE = 9;
70

            
71
class ReceivedSettingsImpl : public ReceivedSettings {
72
public:
73
  explicit ReceivedSettingsImpl(absl::Span<const http2::adapter::Http2Setting> settings);
74

            
75
  // ReceivedSettings
76
11317
  const absl::optional<uint32_t>& maxConcurrentStreams() const override {
77
11317
    return concurrent_stream_limit_;
78
11317
  }
79

            
80
private:
81
  absl::optional<uint32_t> concurrent_stream_limit_{};
82
};
83

            
84
class Utility {
85
public:
86
  /**
87
   * Deal with https://tools.ietf.org/html/rfc7540#section-8.1.2.5
88
   * @param key supplies the incoming header key.
89
   * @param value supplies the incoming header value.
90
   * @param cookies supplies the header string to fill if this is a cookie header that needs to be
91
   *                rebuilt.
92
   */
93
  static bool reconstituteCrumbledCookies(const HeaderString& key, const HeaderString& value,
94
                                          HeaderString& cookies);
95
};
96

            
97
class ConnectionImpl;
98

            
99
// Abstract factory. Used to enable injection of factories for testing.
100
class Http2SessionFactory {
101
public:
102
  using ConnectionImplType = ConnectionImpl;
103
1
  virtual ~Http2SessionFactory() = default;
104

            
105
  // Returns a new HTTP/2 session to be used with |connection|.
106
  virtual std::unique_ptr<http2::adapter::Http2Adapter>
107
  create(ConnectionImplType* connection,
108
         const http2::adapter::OgHttp2Adapter::Options& options) PURE;
109

            
110
#ifdef ENVOY_NGHTTP2
111
  // Returns a new HTTP/2 session to be used with |connection|.
112
  virtual std::unique_ptr<http2::adapter::Http2Adapter> create(ConnectionImplType* connection,
113
                                                               const nghttp2_option* options) PURE;
114
#endif
115

            
116
  // Initializes the |session|.
117
  virtual void init(ConnectionImplType* connection,
118
                    const envoy::config::core::v3::Http2ProtocolOptions& options) PURE;
119
};
120

            
121
class ProdNghttp2SessionFactory : public Http2SessionFactory {
122
public:
123
  std::unique_ptr<http2::adapter::Http2Adapter>
124
  create(ConnectionImpl* connection,
125
         const http2::adapter::OgHttp2Adapter::Options& options) override;
126

            
127
#ifdef ENVOY_NGHTTP2
128
  std::unique_ptr<http2::adapter::Http2Adapter> create(ConnectionImpl* connection,
129
                                                       const nghttp2_option* options) override;
130
#endif
131

            
132
  void init(ConnectionImpl* connection,
133
            const envoy::config::core::v3::Http2ProtocolOptions& options) override;
134

            
135
  // Returns a global factory instance. Note that this is possible because no
136
  // internal state is maintained; the thread safety of create() and init()'s
137
  // side effects is guaranteed by Envoy's worker based threading model.
138
14816
  static ProdNghttp2SessionFactory& get() {
139
14816
    static ProdNghttp2SessionFactory* instance = new ProdNghttp2SessionFactory();
140
14816
    return *instance;
141
14816
  }
142
};
143

            
144
/**
145
 * Base class for HTTP/2 client and server codecs.
146
 */
147
class ConnectionImpl : public virtual Connection,
148
                       protected Logger::Loggable<Logger::Id::http2>,
149
                       public ScopeTrackedObject {
150
public:
151
  ConnectionImpl(Network::Connection& connection, CodecStats& stats,
152
                 Random::RandomGenerator& random_generator,
153
                 const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
154
                 const uint32_t max_headers_kb, const uint32_t max_headers_count);
155

            
156
  ~ConnectionImpl() override;
157

            
158
  // Http::Connection
159
  // NOTE: the `dispatch` method is also overridden in the ServerConnectionImpl class
160
  Http::Status dispatch(Buffer::Instance& data) override;
161
  void goAway() override;
162
631743
  Protocol protocol() override { return Protocol::Http2; }
163
  void shutdownNotice() override;
164
  Status protocolErrorForTest(); // Used in tests to simulate errors.
165
20385
  bool wantsToWrite() override { return adapter_->want_write(); }
166
  // Propagate network connection watermark events to each stream on the connection.
167
76519
  void onUnderlyingConnectionAboveWriteBufferHighWatermark() override {
168
182095
    for (auto& stream : active_streams_) {
169
182091
      stream->runHighWatermarkCallbacks();
170
182091
    }
171
76519
  }
172
  void onUnderlyingConnectionBelowWriteBufferLowWatermark() override;
173

            
174
14817
  void setVisitor(std::unique_ptr<http2::adapter::Http2VisitorInterface> visitor) {
175
14817
    visitor_ = std::move(visitor);
176
14817
  }
177

            
178
  // ScopeTrackedObject
179
  OptRef<const StreamInfo::StreamInfo> trackedStream() const override;
180
  void dumpState(std::ostream& os, int indent_level) const override;
181

            
182
protected:
183
  friend class ProdNghttp2SessionFactory;
184

            
185
  /**
186
   * This class handles protocol events from the codec layer.
187
   */
188
  class Http2Visitor : public http2::adapter::Http2VisitorInterface {
189
  public:
190
    using Http2ErrorCode = http2::adapter::Http2ErrorCode;
191
    using Http2PingId = http2::adapter::Http2PingId;
192
    using Http2Setting = http2::adapter::Http2Setting;
193
    using Http2StreamId = http2::adapter::Http2StreamId;
194

            
195
    explicit Http2Visitor(ConnectionImpl* connection);
196

            
197
23426
    void setStreamCloseListener(std::function<void(Http2StreamId)> f) {
198
23426
      stream_close_listener_ = std::move(f);
199
23426
    }
200
    int64_t OnReadyToSend(absl::string_view serialized) override;
201
    DataFrameHeaderInfo OnReadyToSendDataForStream(Http2StreamId stream_id,
202
                                                   size_t max_length) override;
203
    bool SendDataFrame(Http2StreamId stream_id, absl::string_view frame_header,
204
                       size_t payload_bytes) override;
205
1302
    void OnConnectionError(ConnectionError /*error*/) override {}
206
    bool OnFrameHeader(Http2StreamId stream_id, size_t length, uint8_t type,
207
                       uint8_t flags) override;
208
29929
    void OnSettingsStart() override { settings_.clear(); }
209
132849
    void OnSetting(Http2Setting setting) override { settings_.push_back(setting); }
210
29928
    void OnSettingsEnd() override { connection_->onSettings(settings_); }
211
28018
    void OnSettingsAck() override {}
212
    bool OnBeginHeadersForStream(Http2StreamId stream_id) override;
213
    OnHeaderResult OnHeaderForStream(Http2StreamId stream_id, absl::string_view name_view,
214
                                     absl::string_view value_view) override;
215
    bool OnEndHeadersForStream(Http2StreamId stream_id) override;
216
    bool OnDataPaddingLength(Http2StreamId stream_id, size_t padding_length) override;
217
    bool OnBeginDataForStream(Http2StreamId stream_id, size_t payload_length) override;
218
    bool OnDataForStream(Http2StreamId stream_id, absl::string_view data) override;
219
    bool OnEndStream(Http2StreamId stream_id) override;
220
    void OnRstStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
221
    bool OnCloseStream(Http2StreamId stream_id, Http2ErrorCode error_code) override;
222
    void OnPriorityForStream(Http2StreamId /*stream_id*/, Http2StreamId /*parent_stream_id*/,
223
                             int /*weight*/, bool /*exclusive*/) override {}
224
    void OnPing(Http2PingId ping_id, bool is_ack) override;
225
    void OnPushPromiseForStream(Http2StreamId /*stream_id*/,
226
                                Http2StreamId /*promised_stream_id*/) override {}
227
    bool OnGoAway(Http2StreamId last_accepted_stream_id, Http2ErrorCode error_code,
228
                  absl::string_view opaque_data) override;
229
40013
    void OnWindowUpdate(Http2StreamId /*stream_id*/, int /*window_increment*/) override {}
230
    int OnBeforeFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length,
231
                          uint8_t flags) override;
232
    int OnFrameSent(uint8_t frame_type, Http2StreamId stream_id, size_t length, uint8_t flags,
233
                    uint32_t error_code) override;
234
    bool OnInvalidFrame(Http2StreamId stream_id, InvalidFrameError error) override;
235
2481
    void OnBeginMetadataForStream(Http2StreamId /*stream_id*/, size_t /*payload_length*/) override {
236
2481
    }
237
    bool OnMetadataForStream(Http2StreamId stream_id, absl::string_view metadata) override;
238
    bool OnMetadataEndForStream(Http2StreamId stream_id) override;
239
    void OnErrorDebug(absl::string_view message) override;
240

            
241
  private:
242
    ConnectionImpl* const connection_;
243
    std::vector<http2::adapter::Http2Setting> settings_;
244
    struct FrameHeaderInfo {
245
      Http2StreamId stream_id;
246
      size_t length;
247
      uint8_t type;
248
      uint8_t flags;
249
    };
250
    FrameHeaderInfo current_frame_ = {};
251
    size_t padding_length_ = 0;
252
    size_t remaining_data_payload_ = 0;
253
    // TODO: remove when removing `envoy.reloadable_features.http2_use_oghttp2`.
254
    std::function<void(Http2StreamId)> stream_close_listener_;
255
  };
256

            
257
  /**
258
   * Wrapper for static nghttp2 session options.
259
   */
260
  class Http2Options {
261
  public:
262
    Http2Options(const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
263
                 uint32_t max_headers_kb);
264
    ~Http2Options();
265

            
266
#ifdef ENVOY_NGHTTP2
267
23426
    const nghttp2_option* options() { return options_; }
268
#endif
269
6998
    const http2::adapter::OgHttp2Adapter::Options& ogOptions() { return og_options_; }
270

            
271
  protected:
272
#ifdef ENVOY_NGHTTP2
273
    nghttp2_option* options_;
274
#endif
275
    http2::adapter::OgHttp2Adapter::Options og_options_;
276
  };
277

            
278
  class ClientHttp2Options : public Http2Options {
279
  public:
280
    ClientHttp2Options(const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
281
                       uint32_t max_headers_kb);
282
  };
283

            
284
  /**
285
   * Base class for client and server side streams.
286
   */
287
  struct StreamImpl : public virtual StreamEncoder,
288
                      public LinkedObject<StreamImpl>,
289
                      public Event::DeferredDeletable,
290
                      public Http::MultiplexedStreamImplBase,
291
                      public ScopeTrackedObject {
292
    enum class HeadersState {
293
      Request,
294
      Response,
295
      Headers, // Signifies additional headers after the initial request/response set.
296
    };
297

            
298
    StreamImpl(ConnectionImpl& parent, uint32_t buffer_limit);
299

            
300
    // Http::MultiplexedStreamImplBase
301
    void destroy() override;
302
    void onPendingFlushTimer() override;
303
    CodecEventCallbacks*
304
150064
    registerCodecEventCallbacks(CodecEventCallbacks* codec_callbacks) override {
305
150064
      extend_stream_lifetime_flag_ = true;
306
150064
      return MultiplexedStreamImplBase::registerCodecEventCallbacks(codec_callbacks);
307
150064
    }
308

            
309
52316
    StreamImpl* base() { return this; }
310
    void resetStreamWorker(StreamResetReason reason);
311
    static std::vector<http2::adapter::Header> buildHeaders(const HeaderMap& headers);
312
    virtual Status onBeginHeaders() PURE;
313
    virtual void advanceHeadersState() PURE;
314
    virtual HeadersState headersState() const PURE;
315
    void saveHeader(HeaderString&& name, HeaderString&& value);
316
    void encodeHeadersBase(const HeaderMap& headers, bool end_stream);
317
    virtual void submitHeaders(const HeaderMap& headers, bool end_stream) PURE;
318
    void encodeTrailersBase(const HeaderMap& headers);
319
    void submitTrailers(const HeaderMap& trailers);
320
    // Returns true if the stream should defer the local reset stream until after the next call to
321
    // sendPendingFrames so pending outbound frames have one final chance to be flushed. If we
322
    // submit a reset, nghttp2 will cancel outbound frames that have not yet been sent.
323
    virtual bool useDeferredReset() const PURE;
324
    virtual StreamDecoder* decoder() PURE;
325
    virtual HeaderMap& headers() PURE;
326
    virtual void allocTrailers() PURE;
327
    virtual HeaderMapPtr cloneTrailers(const HeaderMap& trailers) PURE;
328

            
329
    // Http::StreamEncoder
330
    void encodeData(Buffer::Instance& data, bool end_stream) override;
331
1620614
    Stream& getStream() override { return *this; }
332
    void encodeMetadata(const MetadataMapVector& metadata_map_vector) override;
333
4
    Http1StreamEncoderOptionsOptRef http1StreamEncoderOptions() override { return absl::nullopt; }
334

            
335
    // Http::Stream
336
198735
    void addCallbacks(StreamCallbacks& callbacks) override { addCallbacksHelper(callbacks); }
337
163039
    void removeCallbacks(StreamCallbacks& callbacks) override { removeCallbacksHelper(callbacks); }
338
    void resetStream(StreamResetReason reason) override;
339
    void readDisable(bool disable) override;
340
74741
    uint32_t bufferLimit() const override { return pending_recv_data_->highWatermark(); }
341
19606
    const Network::ConnectionInfoProvider& connectionInfoProvider() override {
342
19606
      return parent_.connection_.connectionInfoProvider();
343
19606
    }
344
91348
    absl::string_view responseDetails() override { return details_; }
345
74727
    Buffer::BufferMemoryAccountSharedPtr account() const override { return buffer_memory_account_; }
346
    void setAccount(Buffer::BufferMemoryAccountSharedPtr account) override;
347
74747
    absl::optional<uint32_t> codecStreamId() const override {
348
74747
      if (stream_id_ == -1) {
349
74603
        return absl::nullopt;
350
74603
      }
351
144
      return stream_id_;
352
74747
    }
353

            
354
    // ScopeTrackedObject
355
    void dumpState(std::ostream& os, int indent_level) const override;
356

            
357
    // This code assumes that details is a static string, so that we
358
    // can avoid copying it.
359
13578
    void setDetails(absl::string_view details) {
360
13578
      if (details_.empty()) {
361
13435
        details_ = details;
362
13435
      }
363
13578
    }
364

            
365
148842
    void setWriteBufferWatermarks(uint32_t high_watermark) {
366
148842
      pending_recv_data_->setWatermarks(high_watermark);
367
148842
      pending_send_data_->setWatermarks(high_watermark);
368
148842
    }
369

            
370
    // If the receive buffer encounters watermark callbacks, enable/disable reads on this stream.
371
    void pendingRecvBufferHighWatermark();
372
    void pendingRecvBufferLowWatermark();
373

            
374
    // If the send buffer encounters watermark callbacks, propagate this information to the streams.
375
    // The router and connection manager will propagate them on as appropriate.
376
    void pendingSendBufferHighWatermark();
377
    void pendingSendBufferLowWatermark();
378

            
379
    // Does any necessary WebSocket/Upgrade conversion, then passes the headers
380
    // to the decoder_.
381
    virtual void decodeHeaders() PURE;
382
    virtual void decodeTrailers() PURE;
383
    bool maybeDeferDecodeTrailers();
384
    // Consumes any decoded data, buffering if backed up.
385
    void decodeData();
386

            
387
    // Get MetadataEncoder for this stream.
388
    NewMetadataEncoder& getMetadataEncoder();
389
    // Get MetadataDecoder for this stream.
390
    MetadataDecoder& getMetadataDecoder();
391
    // Callback function for MetadataDecoder.
392
    void onMetadataDecoded(MetadataMapPtr&& metadata_map_ptr);
393

            
394
2378118
    bool buffersOverrun() const { return read_disable_count_ > 0; }
395
671311
    bool shouldAllowPeerAdditionalStreamWindow() const {
396
671340
      return !buffersOverrun() && !pending_recv_data_->highWatermarkTriggered();
397
671311
    }
398

            
399
    void encodeDataHelper(Buffer::Instance& data, bool end_stream,
400
                          bool skip_encoding_empty_trailers);
401
    // Called from either process_buffered_data_callback_.
402
    void processBufferedData();
403

            
404
    // Called when the frame with END_STREAM is sent for this stream.
405
82831
    void onEndStreamEncoded() {
406
82831
      if (codec_callbacks_) {
407
28873
        codec_callbacks_->onCodecEncodeComplete();
408
28873
      }
409
82831
    }
410
6042
    void onResetEncoded(uint32_t error_code) {
411
6042
      if (codec_callbacks_ && error_code != 0) {
412
        // TODO(wbpcode): this ensure that onCodecLowLevelReset is only called once. But
413
        // we should replace this with a better design later.
414
        // See https://github.com/envoyproxy/envoy/issues/42264 for why we need this.
415
290
        if (!codec_low_level_reset_is_called_) {
416
272
          codec_low_level_reset_is_called_ = true;
417
272
          codec_callbacks_->onCodecLowLevelReset();
418
272
        }
419
290
      }
420
6042
    }
421

            
422
94404
    const StreamInfo::BytesMeterSharedPtr& bytesMeter() override { return bytes_meter_; }
423
    ConnectionImpl& parent_;
424
    int32_t stream_id_{-1};
425
    uint32_t unconsumed_bytes_{0};
426
    uint32_t read_disable_count_{0};
427
    StreamInfo::BytesMeterSharedPtr bytes_meter_{std::make_shared<StreamInfo::BytesMeter>()};
428

            
429
    Buffer::BufferMemoryAccountSharedPtr buffer_memory_account_;
430
    // This buffer may accumulate data and be drained in scheduleProcessingOfBufferedData.
431
    // See source/docs/flow_control.md for more information.
432
    Buffer::InstancePtr pending_recv_data_;
433
    Buffer::InstancePtr pending_send_data_;
434
    HeaderMapPtr pending_trailers_to_encode_;
435
    std::unique_ptr<MetadataDecoder> metadata_decoder_;
436
    std::unique_ptr<NewMetadataEncoder> metadata_encoder_;
437
    absl::optional<StreamResetReason> deferred_reset_;
438
    // Holds the reset reason for this stream. Useful if we have buffered data
439
    // to determine whether we should continue processing that data.
440
    absl::optional<StreamResetReason> reset_reason_;
441
    HeaderString cookies_;
442
    bool local_end_stream_sent_ : 1;
443
    bool remote_end_stream_ : 1;
444
    bool remote_rst_ : 1;
445
    bool data_deferred_ : 1;
446
    bool received_noninformational_headers_ : 1;
447
    bool pending_receive_buffer_high_watermark_called_ : 1;
448
    bool pending_send_buffer_high_watermark_called_ : 1;
449
    bool reset_due_to_messaging_error_ : 1;
450
    // Latch whether this stream is operating with this flag.
451
    bool extend_stream_lifetime_flag_ : 1;
452
    absl::string_view details_;
453

            
454
    /**
455
     * Tracks buffering that may occur for a stream if it is backed up.
456
     */
457
    struct BufferedStreamManager {
458
      bool body_buffered_{false};
459
      bool trailers_buffered_{false};
460

            
461
      // We received a call to onStreamClose for the stream, but deferred it
462
      // as the stream had pending data to process and the stream was not reset.
463
      bool buffered_on_stream_close_{false};
464

            
465
      // Segment size for processing body data. Defaults to the value of high
466
      // watermark of the *pending_recv_data_* buffer.
467
      // If 0, we will process all buffered data.
468
      uint32_t defer_processing_segment_size_{0};
469

            
470
654647
      bool decodeAsChunks() const { return defer_processing_segment_size_ > 0; }
471
560652
      bool hasBufferedBodyOrTrailers() const { return body_buffered_ || trailers_buffered_; }
472
    };
473

            
474
    BufferedStreamManager stream_manager_;
475
    Event::SchedulableCallbackPtr process_buffered_data_callback_;
476

            
477
  protected:
478
    // Http::MultiplexedStreamImplBase
479
19019
    bool hasPendingData() override {
480
19019
      return pending_send_data_->length() > 0 || pending_trailers_to_encode_ != nullptr;
481
19019
    }
482
455843
    bool continueProcessingBufferedData() const {
483
      // We should stop processing buffered data if either
484
      // 1) Buffers become overrun
485
      // 2) The stream ends up getting reset
486
      // Both of these can end up changing as a result of processing buffered data.
487
455843
      return !buffersOverrun() && !reset_reason_.has_value();
488
455843
    }
489

            
490
    // Avoid inversion in the case where we saw trailers, acquiring the
491
    // remote_end_stream_ being set to true, but the trailers ended up being
492
    // buffered.
493
    // All buffered body must be consumed before we send end stream.
494
791151
    bool sendEndStream() const {
495
791151
      return remote_end_stream_ && !stream_manager_.trailers_buffered_ &&
496
791151
             !stream_manager_.body_buffered_;
497
791151
    }
498

            
499
    // Schedules a callback either in the current or next iteration to process
500
    // buffered data.
501
    void scheduleProcessingOfBufferedData(bool schedule_next_iteration);
502

            
503
    // Marks data consumed by the stream, granting the peer additional stream
504
    // window.
505
    void grantPeerAdditionalStreamWindow();
506
  };
507

            
508
  using StreamImplPtr = std::unique_ptr<StreamImpl>;
509

            
510
  /**
511
   * Client side stream (request).
512
   */
513
  struct ClientStreamImpl : public StreamImpl, public RequestEncoder {
514
    ClientStreamImpl(ConnectionImpl& parent, uint32_t buffer_limit,
515
                     ResponseDecoder& response_decoder)
516
52957
        : StreamImpl(parent, buffer_limit), response_decoder_(response_decoder),
517
52957
          headers_or_trailers_(
518
52957
              ResponseHeaderMapImpl::create(parent_.max_headers_kb_, parent_.max_headers_count_)) {}
519

            
520
    // Http::MultiplexedStreamImplBase
521
    // Client streams do not need a flush timer because we currently assume that any failure
522
    // to flush would be covered by a request/stream/etc. timeout.
523
    void setFlushTimeout(std::chrono::milliseconds /*timeout*/) override {}
524
2
    CodecEventCallbacks* registerCodecEventCallbacks(CodecEventCallbacks*) override {
525
2
      ENVOY_BUG(false, "CodecEventCallbacks for HTTP2 client stream unimplemented.");
526
2
      return nullptr;
527
2
    }
528
    // StreamImpl
529
    void submitHeaders(const HeaderMap& headers, bool end_stream) override;
530
    Status onBeginHeaders() override;
531
    void advanceHeadersState() override;
532
42473
    HeadersState headersState() const override { return headers_state_; }
533
    // Do not use deferred reset on upstream connections.
534
12359
    bool useDeferredReset() const override { return false; }
535
292844
    StreamDecoder* decoder() override { return &response_decoder_; }
536
    void decodeHeaders() override;
537
    void decodeTrailers() override;
538
463712
    HeaderMap& headers() override {
539
463712
      if (absl::holds_alternative<ResponseHeaderMapPtr>(headers_or_trailers_)) {
540
460139
        return *absl::get<ResponseHeaderMapPtr>(headers_or_trailers_);
541
460139
      } else {
542
3573
        return *absl::get<ResponseTrailerMapPtr>(headers_or_trailers_);
543
3573
      }
544
463712
    }
545
1016
    void allocTrailers() override {
546
      // If we are waiting for informational headers, make a new response header map, otherwise
547
      // we are about to receive trailers. The codec makes sure this is the only valid sequence.
548
1016
      if (received_noninformational_headers_) {
549
867
        headers_or_trailers_.emplace<ResponseTrailerMapPtr>(
550
867
            ResponseTrailerMapImpl::create(parent_.max_headers_kb_, parent_.max_headers_count_));
551
955
      } else {
552
149
        headers_or_trailers_.emplace<ResponseHeaderMapPtr>(
553
149
            ResponseHeaderMapImpl::create(parent_.max_headers_kb_, parent_.max_headers_count_));
554
149
      }
555
1016
    }
556
10
    HeaderMapPtr cloneTrailers(const HeaderMap& trailers) override {
557
10
      return createHeaderMap<RequestTrailerMapImpl>(trailers);
558
10
    }
559

            
560
    // RequestEncoder
561
    Status encodeHeaders(const RequestHeaderMap& headers, bool end_stream) override;
562
597
    void encodeTrailers(const RequestTrailerMap& trailers) override {
563
597
      encodeTrailersBase(trailers);
564
597
    }
565
169
    void enableTcpTunneling() override {}
566

            
567
    // ScopeTrackedObject
568
    void dumpState(std::ostream& os, int indent_level) const override;
569

            
570
    ResponseDecoder& response_decoder_;
571
    absl::variant<ResponseHeaderMapPtr, ResponseTrailerMapPtr> headers_or_trailers_;
572
    std::string upgrade_type_;
573
    HeadersState headers_state_ = HeadersState::Response;
574
  };
575

            
576
  using ClientStreamImplPtr = std::unique_ptr<ClientStreamImpl>;
577

            
578
  /**
579
   * Server side stream (response).
580
   */
581
  struct ServerStreamImpl : public StreamImpl, public ResponseEncoder {
582
    ServerStreamImpl(ConnectionImpl& parent, uint32_t buffer_limit)
583
95882
        : StreamImpl(parent, buffer_limit),
584
95882
          headers_or_trailers_(
585
95882
              RequestHeaderMapImpl::create(parent_.max_headers_kb_, parent_.max_headers_count_)) {}
586

            
587
    // StreamImpl
588
    void destroy() override;
589
    void submitHeaders(const HeaderMap& headers, bool end_stream) override;
590
    Status onBeginHeaders() override;
591
    void advanceHeadersState() override;
592
95708
    HeadersState headersState() const override { return headers_state_; }
593
    // Enable deferred reset on downstream connections so outbound HTTP internal error replies are
594
    // written out before force resetting the stream, assuming there is enough H2 connection flow
595
    // control window is available.
596
1152
    bool useDeferredReset() const override { return true; }
597
364119
    StreamDecoder* decoder() override { return request_decoder_handle_->get().ptr(); }
598
    void decodeHeaders() override;
599
    void decodeTrailers() override;
600
1818465
    HeaderMap& headers() override {
601
1818465
      if (absl::holds_alternative<RequestHeaderMapSharedPtr>(headers_or_trailers_)) {
602
1572710
        return *absl::get<RequestHeaderMapSharedPtr>(headers_or_trailers_);
603
1810499
      } else {
604
245755
        return *absl::get<RequestTrailerMapPtr>(headers_or_trailers_);
605
245755
      }
606
1818465
    }
607
713
    void allocTrailers() override {
608
713
      headers_or_trailers_.emplace<RequestTrailerMapPtr>(
609
713
          RequestTrailerMapImpl::create(parent_.max_headers_kb_, parent_.max_headers_count_));
610
713
    }
611
12
    HeaderMapPtr cloneTrailers(const HeaderMap& trailers) override {
612
12
      return createHeaderMap<ResponseTrailerMapImpl>(trailers);
613
12
    }
614
    void resetStream(StreamResetReason reason) override;
615

            
616
    // ResponseEncoder
617
    void encode1xxHeaders(const ResponseHeaderMap& headers) override;
618
    void encodeHeaders(const ResponseHeaderMap& headers, bool end_stream) override;
619
6025
    void encodeTrailers(const ResponseTrailerMap& trailers) override {
620
6025
      encodeTrailersBase(trailers);
621
6025
    }
622
96007
    void setRequestDecoder(Http::RequestDecoder& decoder) override {
623
96007
      request_decoder_handle_ = decoder.getRequestDecoderHandle();
624
96007
    }
625
    void setDeferredLoggingHeadersAndTrailers(Http::RequestHeaderMapConstSharedPtr,
626
                                              Http::ResponseHeaderMapConstSharedPtr,
627
                                              Http::ResponseTrailerMapConstSharedPtr,
628
                                              StreamInfo::StreamInfo&) override {}
629

            
630
    // ScopeTrackedObject
631
    void dumpState(std::ostream& os, int indent_level) const override;
632

            
633
    absl::variant<RequestHeaderMapSharedPtr, RequestTrailerMapPtr> headers_or_trailers_;
634

            
635
8
    bool streamErrorOnInvalidHttpMessage() const override {
636
8
      return parent_.stream_error_on_invalid_http_messaging_;
637
8
    }
638

            
639
  private:
640
    RequestDecoderHandlePtr request_decoder_handle_;
641
    HeadersState headers_state_ = HeadersState::Request;
642
  };
643

            
644
  using ServerStreamImplPtr = std::unique_ptr<ServerStreamImpl>;
645

            
646
29634
  ConnectionImpl* base() { return this; }
647
  // NOTE: Always use non debug nullptr checks against the return value of this function. There are
648
  // edge cases (such as for METADATA frames) where nghttp2 will issue a callback for a stream_id
649
  // that is not associated with an existing stream.
650
  const StreamImpl* getStream(int32_t stream_id) const;
651
  StreamImpl* getStream(int32_t stream_id);
652
  // Same as getStream, but without the ASSERT.
653
  const StreamImpl* getStreamUnchecked(int32_t stream_id) const;
654
  StreamImpl* getStreamUnchecked(int32_t stream_id);
655
  int saveHeader(int32_t stream_id, HeaderString&& name, HeaderString&& value);
656

            
657
  /**
658
   * Copies any frames pending internally by nghttp2 into outbound buffer.
659
   * The `sendPendingFrames()` can be called in 3 different contexts:
660
   * 1. dispatching_ == true, aka the dispatching context. The `sendPendingFrames()` is no-op and
661
   *    always returns success to avoid reentering nghttp2 library.
662
   * 2. Server codec only. dispatching_ == false.
663
   *    The `sendPendingFrames()` returns the status of the protocol constraint checks. Outbound
664
   *    frame accounting is performed.
665
   * 3. dispatching_ == false. The `sendPendingFrames()` always returns success. No outbound
666
   *    frame accounting.
667
   *
668
   * TODO(yanavlasov): harmonize behavior for cases 2, 3.
669
   */
670
  Status sendPendingFrames();
671

            
672
  /**
673
   * Call the sendPendingFrames() method and schedule disconnect callback when
674
   * sendPendingFrames() returns an error.
675
   * Return true if the disconnect callback has been scheduled.
676
   */
677
  bool sendPendingFramesAndHandleError();
678
  void sendSettings(const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
679
                    bool disable_push);
680
  void sendSettingsHelper(const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
681
                          bool disable_push);
682
  // Callback triggered when the peer's SETTINGS frame is received.
683
28006
  virtual void onSettings(absl::Span<const http2::adapter::Http2Setting> settings) {
684
28006
    ReceivedSettingsImpl received_settings(settings);
685
28006
    callbacks().onSettings(received_settings);
686
28006
  }
687

            
688
  /**
689
   * Check if header name contains underscore character.
690
   * Underscore character is allowed in header names by the RFC-7230 and this check is implemented
691
   * as a security measure due to systems that treat '_' and '-' as interchangeable.
692
   * The ServerConnectionImpl may drop header or reject request based on the
693
   * `common_http_protocol_options.headers_with_underscores_action` configuration option in the
694
   * HttpConnectionManager.
695
   */
696
154571
  virtual absl::optional<int> checkHeaderNameForUnderscores(absl::string_view /* header_name */) {
697
154571
    return absl::nullopt;
698
154571
  }
699

            
700
  /**
701
   * Save `status` into codec_callback_status_.
702
   * Return codec callback return code corresponding to `status`.
703
   */
704
  int setAndCheckCodecCallbackStatus(Status&& status);
705

            
706
  /**
707
   * Callback for terminating connection when protocol constrain has been violated
708
   * outside of the dispatch context.
709
   */
710
  void scheduleProtocolConstraintViolationCallback();
711
  void onProtocolConstraintViolation();
712

            
713
  // Whether to use the new HTTP/2 library.
714
  bool use_oghttp2_library_;
715

            
716
  // If deferred processing, the streams will be in LRU order based on when the
717
  // stream encoded to the http2 connection. The LRU property is used when
718
  // raising low watermark on the http2 connection to prioritize how streams get
719
  // notified, prefering those that haven't recently written.
720
  std::list<StreamImplPtr> active_streams_;
721

            
722
  // Tracks the stream id of the current stream we're processing.
723
  // This should only be set while we're in the context of dispatching to nghttp2.
724
  absl::optional<int32_t> current_stream_id_;
725
  std::unique_ptr<http2::adapter::Http2VisitorInterface> visitor_;
726
  std::unique_ptr<http2::adapter::Http2Adapter> adapter_;
727

            
728
  CodecStats& stats_;
729
  Network::Connection& connection_;
730
  const uint32_t max_headers_kb_;
731
  const uint32_t max_headers_count_;
732
  uint32_t per_stream_buffer_limit_;
733
  bool allow_metadata_;
734
  uint64_t max_metadata_size_;
735
  const bool stream_error_on_invalid_http_messaging_;
736

            
737
  // Status for any errors encountered by the nghttp2 callbacks.
738
  // nghttp2 library uses single return code to indicate callback failure and
739
  // `codec_callback_status_` is used to save right error information returned by a callback. The
740
  // `codec_callback_status_` is valid iff nghttp call returned NGHTTP2_ERR_CALLBACK_FAILURE.
741
  Status codec_callback_status_;
742

            
743
  // Set if the type of frame that is about to be sent is PING or SETTINGS with the ACK flag set, or
744
  // RST_STREAM.
745
  bool is_outbound_flood_monitored_control_frame_ = 0;
746
  ProtocolConstraints protocol_constraints_;
747

            
748
  // For the flood mitigation to work the onSend callback must be called once for each outbound
749
  // frame. This is what the nghttp2 library is doing, however this is not documented. The
750
  // Http2FloodMitigationTest.* tests in test/integration/http2_integration_test.cc will break if
751
  // this changes in the future. Also it is important that onSend does not do partial writes, as the
752
  // nghttp2 library will keep calling this callback to write the rest of the frame.
753
  ssize_t onSend(const uint8_t* data, size_t length);
754

            
755
  // Called when a stream encodes to the http2 connection which enables us to
756
  // keep the active_streams list in LRU if deferred processing.
757
543330
  void updateActiveStreamsOnEncode(StreamImpl& stream) {
758
543330
    LinkedList::moveIntoList(stream.removeFromList(active_streams_), active_streams_);
759
543330
  }
760

            
761
  // dumpState helper method.
762
  virtual void dumpStreams(std::ostream& os, int indent_level) const;
763

            
764
  // Send a keepalive ping, and set the idle timer for ping timeout.
765
  void sendKeepalive();
766

            
767
4
  const MonotonicTime& lastReceivedDataTime() { return last_received_data_time_; }
768

            
769
private:
770
  friend class Http2CodecImplTestFixture;
771

            
772
  virtual ConnectionCallbacks& callbacks() PURE;
773
  virtual Status onBeginHeaders(int32_t stream_id) PURE;
774
  int onData(int32_t stream_id, const uint8_t* data, size_t len);
775
  Status onBeforeFrameReceived(int32_t stream_id, size_t length, uint8_t type, uint8_t flags);
776
  Status onPing(uint64_t opaque_data, bool is_ack);
777
  Status onBeginData(int32_t stream_id, size_t length, uint8_t flags, size_t padding);
778
  Status onGoAway(uint32_t error_code);
779
  Status onHeaders(int32_t stream_id, size_t length, uint8_t flags);
780
  Status onRstStream(int32_t stream_id, uint32_t error_code);
781
  int onBeforeFrameSend(int32_t stream_id, size_t length, uint8_t type, uint8_t flags);
782
  int onFrameSend(int32_t stream_id, size_t length, uint8_t type, uint8_t flags,
783
                  uint32_t error_code);
784
  int onError(absl::string_view error);
785
  virtual int onHeader(int32_t stream_id, HeaderString&& name, HeaderString&& value) PURE;
786
  int onInvalidFrame(int32_t stream_id, int error_code);
787
  // Pass through invoking with the actual stream.
788
  Status onStreamClose(int32_t stream_id, uint32_t error_code);
789
  // Should be invoked directly in buffered onStreamClose scenarios
790
  // where nghttp2 might have already forgotten about the stream.
791
  Status onStreamClose(StreamImpl* stream, uint32_t error_code);
792
  int onMetadataReceived(int32_t stream_id, const uint8_t* data, size_t len);
793
  int onMetadataFrameComplete(int32_t stream_id, bool end_metadata);
794

            
795
  // Adds buffer fragment for a new outbound frame to the supplied Buffer::OwnedImpl.
796
  void addOutboundFrameFragment(Buffer::OwnedImpl& output, const uint8_t* data, size_t length);
797
  Status trackInboundFrames(int32_t stream_id, size_t length, uint8_t type, uint8_t flags,
798
                            uint32_t padding_length);
799
  void onKeepaliveResponse();
800
  void onKeepaliveResponseTimeout();
801
  bool slowContainsStreamId(int32_t stream_id) const;
802
  virtual StreamResetReason getMessagingErrorResetReason() const PURE;
803

            
804
  // Tracks the current slice we're processing in the dispatch loop.
805
  const Buffer::RawSlice* current_slice_ = nullptr;
806
  // Streams that are pending deferred reset. Using an ordered map provides determinism in the rare
807
  // case where there are multiple streams waiting for deferred reset. The stream id is also used to
808
  // remove streams from the map when they are closed in order to avoid calls to resetStreamWorker
809
  // after the stream has been removed from the active list.
810
  std::map<int32_t, StreamImpl*> pending_deferred_reset_streams_;
811
  bool dispatching_ : 1;
812
  bool raised_goaway_ : 1;
813
  Event::SchedulableCallbackPtr protocol_constraint_violation_callback_;
814
  Random::RandomGenerator& random_;
815
  MonotonicTime last_received_data_time_;
816
  Event::TimerPtr keepalive_send_timer_;
817
  Event::TimerPtr keepalive_timeout_timer_;
818
  std::chrono::milliseconds keepalive_interval_;
819
  std::chrono::milliseconds keepalive_timeout_;
820
  uint32_t keepalive_interval_jitter_percent_;
821
};
822

            
823
/**
824
 * HTTP/2 client connection codec.
825
 */
826
class ClientConnectionImpl : public ClientConnection, public ConnectionImpl {
827
public:
828
  using SessionFactory = Http2SessionFactory;
829
  ClientConnectionImpl(Network::Connection& connection, ConnectionCallbacks& callbacks,
830
                       CodecStats& stats, Random::RandomGenerator& random_generator,
831
                       const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
832
                       const uint32_t max_response_headers_kb,
833
                       const uint32_t max_response_headers_count,
834
                       SessionFactory& http2_session_factory);
835

            
836
  // Http::ClientConnection
837
  RequestEncoder& newStream(ResponseDecoder& response_decoder) override;
838

            
839
private:
840
  // ConnectionImpl
841
13398
  ConnectionCallbacks& callbacks() override { return callbacks_; }
842
  Status onBeginHeaders(int32_t stream_id) override;
843
  int onHeader(int32_t stream_id, HeaderString&& name, HeaderString&& value) override;
844
  void dumpStreams(std::ostream& os, int indent_level) const override;
845
  StreamResetReason getMessagingErrorResetReason() const override;
846
  Http::ConnectionCallbacks& callbacks_;
847
  std::chrono::milliseconds idle_session_requires_ping_interval_;
848
};
849

            
850
/**
851
 * HTTP/2 server connection codec.
852
 */
853
class ServerConnectionImpl : public ServerConnection, public ConnectionImpl {
854
public:
855
  ServerConnectionImpl(Network::Connection& connection, ServerConnectionCallbacks& callbacks,
856
                       CodecStats& stats, Random::RandomGenerator& random_generator,
857
                       const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
858
                       const uint32_t max_request_headers_kb,
859
                       const uint32_t max_request_headers_count,
860
                       envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
861
                           headers_with_underscores_action,
862
                       Server::OverloadManager& overload_manager);
863

            
864
private:
865
  // ConnectionImpl
866
14762
  ConnectionCallbacks& callbacks() override { return callbacks_; }
867
  Status onBeginHeaders(int32_t stream_id) override;
868
  int onHeader(int32_t stream_id, HeaderString&& name, HeaderString&& value) override;
869
  absl::optional<int> checkHeaderNameForUnderscores(absl::string_view header_name) override;
870
285
  StreamResetReason getMessagingErrorResetReason() const override {
871
285
    return StreamResetReason::LocalReset;
872
285
  }
873

            
874
  // Http::Connection
875
  // The reason for overriding the dispatch method is to do flood mitigation only when
876
  // processing data from downstream client. Doing flood mitigation when processing upstream
877
  // responses makes clean-up tricky, which needs to be improved (see comments for the
878
  // ClientConnectionImpl::checkProtocolConstraintsStatus method). The dispatch method on the
879
  // ServerConnectionImpl objects is called only when processing data from the downstream client in
880
  // the ConnectionManagerImpl::onData method.
881
  Http::Status dispatch(Buffer::Instance& data) override;
882

            
883
  ServerConnectionCallbacks& callbacks_;
884

            
885
  // The action to take when a request header name contains underscore characters.
886
  envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction
887
      headers_with_underscores_action_;
888
  Server::LoadShedPoint* should_send_go_away_on_dispatch_{nullptr};
889
  Server::LoadShedPoint* should_send_go_away_and_close_on_dispatch_{nullptr};
890
  bool sent_go_away_on_dispatch_{false};
891
};
892

            
893
} // namespace Http2
894
} // namespace Http
895
} // namespace Envoy