1
#pragma once
2

            
3
#include <string>
4

            
5
#include "envoy/network/listener.h"
6

            
7
#include "source/common/http/session_idle_list.h"
8
#include "source/common/quic/envoy_quic_connection_debug_visitor_factory_interface.h"
9
#include "source/common/quic/envoy_quic_server_crypto_stream_factory.h"
10
#include "source/common/quic/envoy_quic_server_session.h"
11
#include "source/common/quic/quic_stat_names.h"
12
#include "source/server/listener_stats.h"
13

            
14
#include "quiche/quic/core/quic_dispatcher.h"
15
#include "quiche/quic/core/quic_utils.h"
16

            
17
namespace Envoy {
18
namespace Quic {
19

            
20
class EnvoyQuicDispatcherTest;
21

            
22
2203
#define QUIC_DISPATCHER_STATS(COUNTER) COUNTER(stateless_reset_packets_sent)
23

            
24
struct QuicDispatcherStats {
25
  QUIC_DISPATCHER_STATS(GENERATE_COUNTER_STRUCT)
26
};
27

            
28
// Dummy implementation only used by Google Quic.
29
class EnvoyQuicCryptoServerStreamHelper : public quic::QuicCryptoServerStreamBase::Helper {
30
public:
31
  // quic::QuicCryptoServerStream::Helper
32
  bool CanAcceptClientHello(const quic::CryptoHandshakeMessage& /*message*/,
33
                            const quic::QuicSocketAddress& /*client_address*/,
34
                            const quic::QuicSocketAddress& /*peer_address*/,
35
                            const quic::QuicSocketAddress& /*self_address*/,
36
1
                            std::string* /*error_details*/) const override {
37
1
    IS_ENVOY_BUG("Unexpected call to CanAcceptClientHello");
38
1
    return false;
39
1
  }
40
};
41

            
42
class EnvoyQuicTimeWaitListManager : public quic::QuicTimeWaitListManager {
43
public:
44
  EnvoyQuicTimeWaitListManager(quic::QuicPacketWriter* writer, Visitor* visitor,
45
                               const quic::QuicClock* clock, quic::QuicAlarmFactory* alarm_factory,
46
                               QuicDispatcherStats& stats);
47

            
48
  void SendPublicReset(const quic::QuicSocketAddress& self_address,
49
                       const quic::QuicSocketAddress& peer_address,
50
                       quic::QuicConnectionId connection_id, bool ietf_quic,
51
                       size_t received_packet_length) override;
52

            
53
private:
54
  QuicDispatcherStats& stats_;
55
};
56

            
57
class EnvoyQuicDispatcher : public quic::QuicDispatcher {
58
public:
59
  EnvoyQuicDispatcher(
60
      const quic::QuicCryptoServerConfig* crypto_config, const quic::QuicConfig& quic_config,
61
      quic::QuicVersionManager* version_manager,
62
      std::unique_ptr<quic::QuicConnectionHelperInterface> helper,
63
      std::unique_ptr<quic::QuicAlarmFactory> alarm_factory,
64
      uint8_t expected_server_connection_id_length, Network::ConnectionHandler& connection_handler,
65
      Network::ListenerConfig& listener_config, Server::ListenerStats& listener_stats,
66
      Server::PerHandlerListenerStats& per_worker_stats, Event::Dispatcher& dispatcher,
67
      Network::Socket& listen_socket, QuicStatNames& quic_stat_names,
68
      EnvoyQuicCryptoServerStreamFactoryInterface& crypto_server_stream_factory,
69
      quic::ConnectionIdGeneratorInterface& generator,
70
      EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory,
71
      std::unique_ptr<Http::SessionIdleList> session_idle_list);
72

            
73
  // quic::QuicDispatcher
74
  void OnConnectionClosed(quic::QuicConnectionId connection_id, quic::QuicErrorCode error,
75
                          const std::string& error_details,
76
                          quic::ConnectionCloseSource source) override;
77
  quic::QuicTimeWaitListManager* CreateQuicTimeWaitListManager() override;
78

            
79
  void closeConnectionsWithFilterChain(const Network::FilterChain* filter_chain);
80

            
81
  void updateListenerConfig(Network::ListenerConfig& new_listener_config);
82

            
83
  // Similar to quic::QuicDispatcher's ProcessPacket, but returns a bool.
84
  // @return false if the packet failed to dispatch, true if it succeeded.
85
  bool processPacket(const quic::QuicSocketAddress& self_address,
86
                     const quic::QuicSocketAddress& peer_address,
87
                     const quic::QuicReceivedPacket& packet);
88

            
89
  void closeIdleQuicConnections(bool is_saturated);
90

            
91
protected:
92
  // quic::QuicDispatcher
93
  std::unique_ptr<quic::QuicSession> CreateQuicSession(
94
      quic::QuicConnectionId server_connection_id, const quic::QuicSocketAddress& self_address,
95
      const quic::QuicSocketAddress& peer_address, absl::string_view alpn,
96
      const quic::ParsedQuicVersion& version, const quic::ParsedClientHello& parsed_chlo,
97
      quic::ConnectionIdGeneratorInterface& connection_id_generator) override;
98

            
99
  // quic::QuicDispatcher
100
  // Sets current_packet_dispatch_success_ to false for processPacket's return value,
101
  // then calls the parent class implementation.
102
  bool OnFailedToDispatchPacket(const quic::ReceivedPacketInfo& received_packet_info) override;
103

            
104
private:
105
  friend class EnvoyQuicDispatcherTest;
106
6
  Http::SessionIdleListInterface* idle_session_list() { return session_idle_list_.get(); }
107

            
108
  Network::ConnectionHandler& connection_handler_;
109
  Network::ListenerConfig* listener_config_{nullptr};
110
  Server::ListenerStats& listener_stats_;
111
  Server::PerHandlerListenerStats& per_worker_stats_;
112
  Event::Dispatcher& dispatcher_;
113
  Network::Socket& listen_socket_;
114
  QuicStatNames& quic_stat_names_;
115
  EnvoyQuicCryptoServerStreamFactoryInterface& crypto_server_stream_factory_;
116
  FilterChainToConnectionMap connections_by_filter_chain_;
117
  QuicDispatcherStats quic_stats_;
118
  QuicConnectionStats connection_stats_;
119
  bool current_packet_dispatch_success_;
120
  EnvoyQuicConnectionDebugVisitorFactoryInterfaceOptRef debug_visitor_factory_;
121
  // session_idle_list_, when non-null, tracks and kills sessions which are not
122
  // doing any work. Session is added to this list when it has no active
123
  // streams, and it is removed from this list when a new stream is created.
124
  std::unique_ptr<Http::SessionIdleListInterface> session_idle_list_;
125
};
126

            
127
} // namespace Quic
128
} // namespace Envoy