Line data Source code
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 : 11 : namespace Envoy { 12 : namespace Quic { 13 : 14 : // A subclass to implement the extra QUIC listener filter interfaces. 15 : class QuicListenerFilterWrapper 16 : : public Network::GenericListenerFilterImplBase<Network::QuicListenerFilter> { 17 : public: 18 : QuicListenerFilterWrapper(const Network::ListenerFilterMatcherSharedPtr& matcher, 19 : Network::QuicListenerFilterPtr listener_filter) 20 : : Network::GenericListenerFilterImplBase<Network::QuicListenerFilter>( 21 0 : std::move(matcher), std::move(listener_filter)) {} 22 : 23 : // Network::QuicListenerFilter 24 0 : Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override { 25 0 : if (isDisabled(cb)) { 26 0 : on_accept_by_passed_ = true; 27 0 : } 28 0 : return Network::GenericListenerFilterImplBase<Network::QuicListenerFilter>::onAccept(cb); 29 0 : } 30 : bool isCompatibleWithServerPreferredAddress( 31 0 : const quic::QuicSocketAddress& server_preferred_address) const override { 32 0 : if (on_accept_by_passed_) { 33 0 : return true; 34 0 : } 35 0 : return listener_filter_->isCompatibleWithServerPreferredAddress(server_preferred_address); 36 0 : } 37 : Network::FilterStatus onPeerAddressChanged(const quic::QuicSocketAddress& new_address, 38 0 : Network::Connection& connection) override { 39 0 : if (on_accept_by_passed_) { 40 0 : return Network::FilterStatus::Continue; 41 0 : } 42 0 : return listener_filter_->onPeerAddressChanged(new_address, connection); 43 0 : } 44 : 45 : private: 46 : bool on_accept_by_passed_{false}; 47 : }; 48 : 49 : // An object created on the stack during QUIC connection creation to apply listener filters, if 50 : // there is any, within the call stack. 51 : class QuicListenerFilterManagerImpl : public Network::QuicListenerFilterManager, 52 : public Network::ListenerFilterCallbacks { 53 : public: 54 : QuicListenerFilterManagerImpl(Event::Dispatcher& dispatcher, Network::ConnectionSocket& socket, 55 : StreamInfo::StreamInfo& stream_info) 56 0 : : socket_(socket), stream_info_(stream_info), dispatcher_(dispatcher) {} 57 : 58 : // Network::ListenerFilterCallbacks 59 0 : Network::ConnectionSocket& socket() override { return socket_; } 60 0 : Event::Dispatcher& dispatcher() override { return dispatcher_; } 61 0 : void continueFilterChain(bool /*success*/) override { IS_ENVOY_BUG("Should not be used."); } 62 0 : void setDynamicMetadata(const std::string& name, const ProtobufWkt::Struct& value) override { 63 0 : stream_info_.setDynamicMetadata(name, value); 64 0 : } 65 0 : envoy::config::core::v3::Metadata& dynamicMetadata() override { 66 0 : return stream_info_.dynamicMetadata(); 67 0 : }; 68 0 : const envoy::config::core::v3::Metadata& dynamicMetadata() const override { 69 0 : return stream_info_.dynamicMetadata(); 70 0 : }; 71 0 : StreamInfo::FilterState& filterState() override { return *stream_info_.filterState().get(); } 72 : 73 : // Network::QuicListenerFilterManager 74 : void addFilter(const Network::ListenerFilterMatcherSharedPtr& listener_filter_matcher, 75 0 : Network::QuicListenerFilterPtr&& filter) override { 76 0 : accept_filters_.emplace_back( 77 0 : std::make_unique<QuicListenerFilterWrapper>(listener_filter_matcher, std::move(filter))); 78 0 : } 79 : bool shouldAdvertiseServerPreferredAddress( 80 0 : const quic::QuicSocketAddress& server_preferred_address) const override { 81 0 : for (const auto& accept_filter : accept_filters_) { 82 0 : if (!accept_filter->isCompatibleWithServerPreferredAddress(server_preferred_address)) { 83 0 : return false; 84 0 : } 85 0 : } 86 0 : return true; 87 0 : } 88 : void onPeerAddressChanged(const quic::QuicSocketAddress& new_address, 89 0 : Network::Connection& connection) override { 90 0 : for (auto& accept_filter : accept_filters_) { 91 0 : Network::FilterStatus status = accept_filter->onPeerAddressChanged(new_address, connection); 92 0 : if (status == Network::FilterStatus::StopIteration || 93 0 : connection.state() != Network::Connection::State::Open) { 94 0 : return; 95 0 : } 96 0 : } 97 0 : } 98 0 : void startFilterChain() { 99 0 : for (auto& accept_filter : accept_filters_) { 100 0 : Network::FilterStatus status = accept_filter->onAccept(*this); 101 0 : if (status == Network::FilterStatus::StopIteration || !socket().ioHandle().isOpen()) { 102 0 : break; 103 0 : } 104 0 : } 105 0 : } 106 : 107 : private: 108 : Network::ConnectionSocket& socket_; 109 : StreamInfo::StreamInfo& stream_info_; 110 : Event::Dispatcher& dispatcher_; 111 : std::list<Network::QuicListenerFilterPtr> accept_filters_; 112 : }; 113 : 114 : class EnvoyQuicServerConnection : public quic::QuicConnection, public QuicNetworkConnection { 115 : public: 116 : EnvoyQuicServerConnection(const quic::QuicConnectionId& server_connection_id, 117 : quic::QuicSocketAddress initial_self_address, 118 : quic::QuicSocketAddress initial_peer_address, 119 : quic::QuicConnectionHelperInterface& helper, 120 : quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer, 121 : bool owns_writer, 122 : const quic::ParsedQuicVersionVector& supported_versions, 123 : Network::ConnectionSocketPtr connection_socket, 124 : quic::ConnectionIdGeneratorInterface& generator, 125 : std::unique_ptr<QuicListenerFilterManagerImpl> listener_filter_manager); 126 : 127 : // quic::QuicConnection 128 : // Overridden to set connection_socket_ with initialized self address and retrieve filter chain. 129 : bool OnPacketHeader(const quic::QuicPacketHeader& header) override; 130 : void OnCanWrite() override; 131 : 132 0 : bool actuallyDeferSend() const { return defer_send_in_response_to_packets(); } 133 : 134 : protected: 135 : void OnEffectivePeerMigrationValidated(bool is_migration_linkable) override; 136 : 137 : private: 138 : std::unique_ptr<QuicListenerFilterManagerImpl> listener_filter_manager_; 139 : }; 140 : 141 : // An implementation that issues connection IDs with stable first 4 types. 142 : class EnvoyQuicSelfIssuedConnectionIdManager : public quic::QuicSelfIssuedConnectionIdManager { 143 : public: 144 : using QuicSelfIssuedConnectionIdManager::QuicSelfIssuedConnectionIdManager; 145 : }; 146 : 147 : } // namespace Quic 148 : } // namespace Envoy