1
#pragma once
2

            
3
#include "envoy/network/listener.h"
4

            
5
#include "source/common/network/generic_listener_filter_impl_base.h"
6
#include "source/common/quic/envoy_quic_utils.h"
7
#include "source/common/quic/quic_network_connection.h"
8

            
9
#include "quiche/quic/core/quic_connection.h"
10
#include "quiche/quic/core/quic_packets.h"
11

            
12
namespace Envoy {
13
namespace Quic {
14

            
15
// A subclass to implement the extra QUIC listener filter interfaces.
16
class QuicListenerFilterWrapper
17
    : public Network::GenericListenerFilterImplBase<Network::QuicListenerFilter> {
18
public:
19
  QuicListenerFilterWrapper(const Network::ListenerFilterMatcherSharedPtr& matcher,
20
                            Network::QuicListenerFilterPtr listener_filter)
21
16
      : Network::GenericListenerFilterImplBase<Network::QuicListenerFilter>(
22
16
            std::move(matcher), std::move(listener_filter)) {}
23

            
24
  // Network::QuicListenerFilter
25
16
  Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override {
26
16
    if (isDisabled(cb)) {
27
8
      on_accept_by_passed_ = true;
28
8
    }
29
16
    return Network::GenericListenerFilterImplBase<Network::QuicListenerFilter>::onAccept(cb);
30
16
  }
31
  bool isCompatibleWithServerPreferredAddress(
32
18
      const quic::QuicSocketAddress& server_preferred_address) const override {
33
18
    if (on_accept_by_passed_) {
34
16
      return true;
35
16
    }
36
2
    return listener_filter_->isCompatibleWithServerPreferredAddress(server_preferred_address);
37
18
  }
38
  Network::FilterStatus onPeerAddressChanged(const quic::QuicSocketAddress& new_address,
39
12
                                             Network::Connection& connection) override {
40
12
    if (on_accept_by_passed_) {
41
8
      return Network::FilterStatus::Continue;
42
8
    }
43
4
    return listener_filter_->onPeerAddressChanged(new_address, connection);
44
12
  }
45
16
  Network::FilterStatus onFirstPacketReceived(const quic::QuicReceivedPacket& packet) override {
46
16
    if (on_accept_by_passed_) {
47
8
      return Network::FilterStatus::Continue;
48
8
    }
49
8
    return listener_filter_->onFirstPacketReceived(packet);
50
16
  }
51

            
52
private:
53
  bool on_accept_by_passed_{false};
54
};
55

            
56
// An object created on the stack during QUIC connection creation to apply listener filters, if
57
// there is any, within the call stack.
58
class QuicListenerFilterManagerImpl : public Network::QuicListenerFilterManager,
59
                                      public Network::ListenerFilterCallbacks {
60
public:
61
  QuicListenerFilterManagerImpl(Event::Dispatcher& dispatcher, Network::ConnectionSocket& socket,
62
                                StreamInfo::StreamInfo& stream_info)
63
2971
      : socket_(socket), stream_info_(stream_info), dispatcher_(dispatcher) {}
64

            
65
  // Network::ListenerFilterCallbacks
66
16
  Network::ConnectionSocket& socket() override { return socket_; }
67
8
  Event::Dispatcher& dispatcher() override { return dispatcher_; }
68
  void continueFilterChain(bool /*success*/) override { IS_ENVOY_BUG("Should not be used."); }
69
  void useOriginalDst(bool /*use_original_dst*/) override { IS_ENVOY_BUG("Should not be used."); }
70
  void setDynamicMetadata(const std::string& name, const Protobuf::Struct& value) override {
71
    stream_info_.setDynamicMetadata(name, value);
72
  }
73
  void setDynamicTypedMetadata(const std::string& name, const Protobuf::Any& value) override {
74
    stream_info_.setDynamicTypedMetadata(name, value);
75
  }
76
  envoy::config::core::v3::Metadata& dynamicMetadata() override {
77
    return stream_info_.dynamicMetadata();
78
  };
79
  const envoy::config::core::v3::Metadata& dynamicMetadata() const override {
80
    return stream_info_.dynamicMetadata();
81
  };
82
16
  StreamInfo::FilterState& filterState() override { return *stream_info_.filterState().get(); }
83
  StreamInfo::StreamInfo& streamInfo() override { return stream_info_; }
84

            
85
  // Network::QuicListenerFilterManager
86
  void addFilter(const Network::ListenerFilterMatcherSharedPtr& listener_filter_matcher,
87
16
                 Network::QuicListenerFilterPtr&& filter) override {
88
16
    accept_filters_.emplace_back(
89
16
        std::make_unique<QuicListenerFilterWrapper>(listener_filter_matcher, std::move(filter)));
90
16
  }
91
  bool shouldAdvertiseServerPreferredAddress(
92
18
      const quic::QuicSocketAddress& server_preferred_address) const override {
93
18
    for (const Network::QuicListenerFilterPtr& accept_filter : accept_filters_) {
94
18
      if (!accept_filter->isCompatibleWithServerPreferredAddress(server_preferred_address)) {
95
2
        return false;
96
2
      }
97
18
    }
98
16
    return true;
99
18
  }
100
  void onPeerAddressChanged(const quic::QuicSocketAddress& new_address,
101
23
                            Network::Connection& connection) override {
102
23
    for (Network::QuicListenerFilterPtr& accept_filter : accept_filters_) {
103
12
      Network::FilterStatus status = accept_filter->onPeerAddressChanged(new_address, connection);
104
12
      if (status == Network::FilterStatus::StopIteration ||
105
12
          connection.state() != Network::Connection::State::Open) {
106
2
        return;
107
2
      }
108
12
    }
109
23
  }
110
2968
  void startFilterChain() {
111
2968
    for (Network::QuicListenerFilterPtr& accept_filter : accept_filters_) {
112
16
      Network::FilterStatus status = accept_filter->onAccept(*this);
113
16
      if (status == Network::FilterStatus::StopIteration || !socket().ioHandle().isOpen()) {
114
        break;
115
      }
116
16
    }
117
2968
  }
118
2971
  void onFirstPacketReceived(const quic::QuicReceivedPacket& packet) override {
119
2971
    for (Network::QuicListenerFilterPtr& accept_filter : accept_filters_) {
120
16
      Network::FilterStatus status = accept_filter->onFirstPacketReceived(packet);
121
16
      if (status == Network::FilterStatus::StopIteration) {
122
        return;
123
      }
124
16
    }
125
2971
  }
126

            
127
private:
128
  Network::ConnectionSocket& socket_;
129
  StreamInfo::StreamInfo& stream_info_;
130
  Event::Dispatcher& dispatcher_;
131
  std::list<Network::QuicListenerFilterPtr> accept_filters_;
132
};
133

            
134
class EnvoyQuicServerConnection : public quic::QuicConnection, public QuicNetworkConnection {
135
public:
136
  // Creates a new `EnvoyQuicServerConnection`. `writer` is owned by the caller and must
137
  // outlive the connection.
138
  EnvoyQuicServerConnection(const quic::QuicConnectionId& server_connection_id,
139
                            quic::QuicSocketAddress initial_self_address,
140
                            quic::QuicSocketAddress initial_peer_address,
141
                            quic::QuicConnectionHelperInterface& helper,
142
                            quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer,
143
                            const quic::ParsedQuicVersionVector& supported_versions,
144
                            Network::ConnectionSocketPtr connection_socket,
145
                            quic::ConnectionIdGeneratorInterface& generator,
146
                            std::unique_ptr<QuicListenerFilterManagerImpl> listener_filter_manager);
147

            
148
  // quic::QuicConnection
149
  // Overridden to set connection_socket_ with initialized self address and retrieve filter chain.
150
  bool OnPacketHeader(const quic::QuicPacketHeader& header) override;
151
  void OnCanWrite() override;
152
  void ProcessUdpPacket(const quic::QuicSocketAddress& self_address,
153
                        const quic::QuicSocketAddress& peer_address,
154
                        const quic::QuicReceivedPacket& packet) override;
155

            
156
1
  bool actuallyDeferSend() const { return defer_send_in_response_to_packets(); }
157

            
158
protected:
159
  void OnEffectivePeerMigrationValidated(bool is_migration_linkable) override;
160

            
161
private:
162
  // Called when a packet is written to the packet writer.
163
  void OnWritePacketDone(size_t packet_size, const quic::WriteResult& result);
164
  std::unique_ptr<QuicListenerFilterManagerImpl> listener_filter_manager_;
165
  bool first_packet_received_ = false;
166
};
167

            
168
// An implementation that issues connection IDs with stable first 4 types.
169
class EnvoyQuicSelfIssuedConnectionIdManager : public quic::QuicSelfIssuedConnectionIdManager {
170
public:
171
  using QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager;
172
};
173

            
174
} // namespace Quic
175
} // namespace Envoy