1
#pragma once
2

            
3
#include "envoy/http/http_server_properties_cache.h"
4

            
5
#include "source/common/quic/envoy_quic_client_connection.h"
6
#include "source/common/quic/envoy_quic_client_crypto_stream_factory.h"
7
#include "source/common/quic/envoy_quic_client_stream.h"
8
#include "source/common/quic/envoy_quic_network_observer_registry_factory.h"
9
#include "source/common/quic/quic_filter_manager_connection_impl.h"
10
#include "source/common/quic/quic_network_connectivity_observer.h"
11
#include "source/common/quic/quic_stat_names.h"
12
#include "source/common/quic/quic_transport_socket_factory.h"
13

            
14
#include "quiche/quic/core/http/quic_spdy_client_session.h"
15

            
16
namespace Envoy {
17
namespace Quic {
18

            
19
// Act as a Network::ClientConnection to ClientCodec.
20
// TODO(danzh) This class doesn't need to inherit Network::FilterManager
21
// interface but need all other Network::Connection implementation in
22
// QuicFilterManagerConnectionImpl. Refactor QuicFilterManagerConnectionImpl to
23
// move FilterManager interface to EnvoyQuicServerSession.
24
class EnvoyQuicClientSession : public QuicFilterManagerConnectionImpl,
25
                               public quic::QuicSpdyClientSession,
26
                               public Network::ClientConnection,
27
                               public PacketsToReadDelegate {
28
public:
29
  EnvoyQuicClientSession(
30
      const quic::QuicConfig& config, const quic::ParsedQuicVersionVector& supported_versions,
31
      std::unique_ptr<EnvoyQuicClientConnection> connection,
32
      quic::QuicForceBlockablePacketWriter* absl_nullable writer,
33
      EnvoyQuicClientConnection::EnvoyQuicMigrationHelper* absl_nullable migration_helper,
34
      const quic::QuicConnectionMigrationConfig& migration_config,
35
      const quic::QuicServerId& server_id,
36
      std::shared_ptr<quic::QuicCryptoClientConfig> crypto_config, Event::Dispatcher& dispatcher,
37
      uint32_t send_buffer_limit,
38
      EnvoyQuicCryptoClientStreamFactoryInterface& crypto_stream_factory,
39
      QuicStatNames& quic_stat_names, OptRef<Http::HttpServerPropertiesCache> rtt_cache,
40
      Stats::Scope& scope,
41
      const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
42
      OptRef<Network::UpstreamTransportSocketFactory> transport_socket_factory);
43

            
44
  ~EnvoyQuicClientSession() override;
45

            
46
  // Called by QuicHttpClientConnectionImpl before creating data streams.
47
3057
  void setHttpConnectionCallbacks(Http::ConnectionCallbacks& callbacks) {
48
3057
    http_connection_callbacks_ = &callbacks;
49
3057
  }
50

            
51
  // Network::Connection
52
  absl::string_view requestedServerName() const override;
53
  void dumpState(std::ostream&, int) const override {
54
    // TODO(kbaichoo): Implement dumpState for H3.
55
  }
56

            
57
  // Network::ClientConnection
58
  // Set up socket and start handshake.
59
  void connect() override;
60

            
61
4
  bool setSocketOption(Envoy::Network::SocketOptionName, absl::Span<uint8_t>) override {
62
4
    return false;
63
4
  }
64

            
65
  // quic::QuicSession
66
  void OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame,
67
                          quic::ConnectionCloseSource source) override;
68
  void Initialize() override;
69
  void OnCanWrite() override;
70
  void OnHttp3GoAway(uint64_t stream_id) override;
71
  void OnTlsHandshakeComplete() override;
72
  void OnRstStream(const quic::QuicRstStreamFrame& frame) override;
73
  void OnNewEncryptionKeyAvailable(quic::EncryptionLevel level,
74
                                   std::unique_ptr<quic::QuicEncrypter> encrypter) override;
75

            
76
  // quic::QuicClientSessionWithMigration
77
  void StartDraining() override;
78

            
79
415184
  quic::HttpDatagramSupport LocalHttpDatagramSupport() override { return http_datagram_support_; }
80
  std::vector<std::string> GetAlpnsToOffer() const override;
81
  void OnConfigNegotiated() override;
82

            
83
  // quic::QuicSpdyClientSessionBase
84
  bool ShouldKeepConnectionAlive() const override;
85
  // quic::ProofHandler
86
  void OnProofVerifyDetailsAvailable(const quic::ProofVerifyDetails& verify_details) override;
87

            
88
  // PacketsToReadDelegate
89
12
  size_t numPacketsExpectedPerEventLoop() const override {
90
    // Do one round of reading per active stream, or to see if there's a new active stream.
91
12
    return std::max<size_t>(1, GetNumActiveStreams()) * Network::NUM_DATAGRAMS_PER_RECEIVE;
92
12
  }
93

            
94
  // QuicFilterManagerConnectionImpl
95
  void setHttp3Options(const envoy::config::core::v3::Http3ProtocolOptions& http3_options) override;
96

            
97
  // Notify any registered connection pool when new streams are available.
98
  void OnCanCreateNewOutgoingStream(bool) override;
99

            
100
  void OnServerPreferredAddressAvailable(
101
      const quic::QuicSocketAddress& server_preferred_address) override;
102

            
103
  // Register this session to the given registry for receiving network change events.
104
  void registerNetworkObserver(EnvoyQuicNetworkObserverRegistry& registry);
105

            
106
  const quic::TransportParameters::ParameterMap& received_custom_transport_parameters() {
107
    return received_custom_transport_parameters_;
108
  }
109
1
  const absl::optional<quic::QuicSocketAddress>& received_ipv6_alternate_server_address() {
110
1
    return received_ipv6_alternate_server_address_;
111
1
  }
112
9
  const absl::optional<quic::QuicSocketAddress>& received_ipv4_alternate_server_address() {
113
9
    return received_ipv4_alternate_server_address_;
114
9
  }
115

            
116
  using quic::QuicSpdyClientSession::PerformActionOnActiveStreams;
117

            
118
protected:
119
  // quic::QuicSpdyClientSession
120
  std::unique_ptr<quic::QuicSpdyClientStream> CreateClientStream() override;
121
  // quic::QuicSpdySession
122
  quic::QuicSpdyStream* CreateIncomingStream(quic::QuicStreamId id) override;
123
  quic::QuicSpdyStream* CreateIncomingStream(quic::PendingStream* pending) override;
124
  std::unique_ptr<quic::QuicCryptoClientStreamBase> CreateQuicCryptoStream() override;
125
4028
  bool ShouldCreateOutgoingBidirectionalStream() override {
126
4028
    ASSERT(quic::QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream());
127
    // Prefer creating an "invalid" stream outside of current stream bounds to
128
    // crashing when dereferencing a nullptr in QuicHttpClientConnectionImpl::newStream
129
4028
    return true;
130
4028
  }
131
  // QuicFilterManagerConnectionImpl
132
  bool hasDataToWrite() override;
133
  // Used by base class to access quic connection after initialization.
134
  const quic::QuicConnection* quicConnection() const override;
135
  quic::QuicConnection* quicConnection() override;
136

            
137
private:
138
  uint64_t streamsAvailable();
139

            
140
  // These callbacks are owned by network filters and quic session should outlive
141
  // them.
142
  Http::ConnectionCallbacks* http_connection_callbacks_{nullptr};
143
  std::shared_ptr<quic::QuicCryptoClientConfig> crypto_config_;
144
  EnvoyQuicCryptoClientStreamFactoryInterface& crypto_stream_factory_;
145
  OptRef<Http::HttpServerPropertiesCache> rtt_cache_;
146
  bool disable_keepalive_{false};
147
  Network::TransportSocketOptionsConstSharedPtr transport_socket_options_;
148
  OptRef<QuicTransportSocketFactoryBase> transport_socket_factory_;
149
  std::vector<std::string> configured_alpns_;
150
  quic::HttpDatagramSupport http_datagram_support_ = quic::HttpDatagramSupport::kNone;
151
  const bool session_handles_migration_;
152
  QuicNetworkConnectivityObserverPtr network_connectivity_observer_;
153
  OptRef<EnvoyQuicNetworkObserverRegistry> registry_;
154
  quic::TransportParameters::ParameterMap received_custom_transport_parameters_;
155
  absl::optional<quic::QuicSocketAddress> received_ipv6_alternate_server_address_;
156
  absl::optional<quic::QuicSocketAddress> received_ipv4_alternate_server_address_;
157
};
158

            
159
} // namespace Quic
160
} // namespace Envoy