Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/event/dispatcher.h" 4 : 5 : #include "source/common/network/utility.h" 6 : #include "source/common/quic/envoy_quic_packet_writer.h" 7 : #include "source/common/quic/envoy_quic_utils.h" 8 : #include "source/common/quic/quic_network_connection.h" 9 : 10 : #include "quiche/quic/core/quic_connection.h" 11 : 12 : namespace Envoy { 13 : namespace Quic { 14 : 15 : // Limits the max number of sockets created. 16 : constexpr uint8_t kMaxNumSocketSwitches = 5; 17 : 18 : class PacketsToReadDelegate { 19 : public: 20 0 : virtual ~PacketsToReadDelegate() = default; 21 : 22 : virtual size_t numPacketsExpectedPerEventLoop() const PURE; 23 : }; 24 : 25 : // A client QuicConnection instance managing its own file events. 26 : class EnvoyQuicClientConnection : public quic::QuicConnection, 27 : public QuicNetworkConnection, 28 : public Network::UdpPacketProcessor { 29 : public: 30 : // A connection socket will be created with given |local_addr|. If binding 31 : // port not provided in |local_addr|, pick up a random port. 32 : EnvoyQuicClientConnection(const quic::QuicConnectionId& server_connection_id, 33 : Network::Address::InstanceConstSharedPtr& initial_peer_address, 34 : quic::QuicConnectionHelperInterface& helper, 35 : quic::QuicAlarmFactory& alarm_factory, 36 : const quic::ParsedQuicVersionVector& supported_versions, 37 : Network::Address::InstanceConstSharedPtr local_addr, 38 : Event::Dispatcher& dispatcher, 39 : const Network::ConnectionSocket::OptionsSharedPtr& options, 40 : quic::ConnectionIdGeneratorInterface& generator); 41 : 42 : EnvoyQuicClientConnection(const quic::QuicConnectionId& server_connection_id, 43 : quic::QuicConnectionHelperInterface& helper, 44 : quic::QuicAlarmFactory& alarm_factory, quic::QuicPacketWriter* writer, 45 : bool owns_writer, 46 : const quic::ParsedQuicVersionVector& supported_versions, 47 : Event::Dispatcher& dispatcher, 48 : Network::ConnectionSocketPtr&& connection_socket, 49 : quic::ConnectionIdGeneratorInterface& generator); 50 : 51 : // Network::UdpPacketProcessor 52 : void processPacket(Network::Address::InstanceConstSharedPtr local_address, 53 : Network::Address::InstanceConstSharedPtr peer_address, 54 : Buffer::InstancePtr buffer, MonotonicTime receive_time) override; 55 : uint64_t maxDatagramSize() const override; 56 0 : void onDatagramsDropped(uint32_t) override { 57 0 : // TODO(mattklein123): Emit a stat for this. 58 0 : } 59 0 : size_t numPacketsExpectedPerEventLoop() const override { 60 0 : if (delegate_.has_value()) { 61 0 : return delegate_->numPacketsExpectedPerEventLoop(); 62 0 : } 63 0 : return DEFAULT_PACKETS_TO_READ_PER_CONNECTION; 64 0 : } 65 : 66 : // Register file event and apply socket options. 67 : void setUpConnectionSocket(Network::ConnectionSocket& connection_socket, 68 : OptRef<PacketsToReadDelegate> delegate); 69 : 70 : // Switch underlying socket with the given one. This is used in connection migration. 71 : void switchConnectionSocket(Network::ConnectionSocketPtr&& connection_socket); 72 : 73 : // quic::QuicConnection 74 : // Potentially trigger migration. 75 : void OnPathDegradingDetected() override; 76 : void OnCanWrite() override; 77 : 78 : // Called when port migration probing succeeds. Attempts to migrate this connection onto the new 79 : // socket extracted from context. 80 : void onPathValidationSuccess(std::unique_ptr<quic::QuicPathValidationContext> context); 81 : 82 : // Called when port migration probing fails. The probing socket from context will go out of scope 83 : // and be destructed. 84 : void onPathValidationFailure(std::unique_ptr<quic::QuicPathValidationContext> context); 85 : 86 : void setNumPtosForPortMigration(uint32_t num_ptos_for_path_degrading); 87 : 88 : // Probes the given peer address. If the probing succeeds, start sending packets to this address 89 : // instead. 90 : void 91 : probeAndMigrateToServerPreferredAddress(const quic::QuicSocketAddress& server_preferred_address); 92 : 93 : private: 94 : // Holds all components needed for a QUIC connection probing/migration. 95 : class EnvoyQuicPathValidationContext : public quic::QuicPathValidationContext { 96 : public: 97 : EnvoyQuicPathValidationContext(const quic::QuicSocketAddress& self_address, 98 : const quic::QuicSocketAddress& peer_address, 99 : std::unique_ptr<EnvoyQuicPacketWriter> writer, 100 : std::unique_ptr<Network::ConnectionSocket> probing_socket); 101 : 102 : ~EnvoyQuicPathValidationContext() override; 103 : 104 : quic::QuicPacketWriter* WriterToUse() override; 105 : 106 : EnvoyQuicPacketWriter* releaseWriter(); 107 : 108 : Network::ConnectionSocket& probingSocket(); 109 : 110 : std::unique_ptr<Network::ConnectionSocket> releaseSocket(); 111 : 112 : private: 113 : std::unique_ptr<EnvoyQuicPacketWriter> writer_; 114 : Network::ConnectionSocketPtr socket_; 115 : }; 116 : 117 : // Receives notifications from the Quiche layer on path validation results. 118 : class EnvoyPathValidationResultDelegate : public quic::QuicPathValidator::ResultDelegate { 119 : public: 120 : explicit EnvoyPathValidationResultDelegate(EnvoyQuicClientConnection& connection); 121 : 122 : void OnPathValidationSuccess(std::unique_ptr<quic::QuicPathValidationContext> context, 123 : quic::QuicTime start_time) override; 124 : 125 : void OnPathValidationFailure(std::unique_ptr<quic::QuicPathValidationContext> context) override; 126 : 127 : private: 128 : EnvoyQuicClientConnection& connection_; 129 : }; 130 : EnvoyQuicClientConnection(const quic::QuicConnectionId& server_connection_id, 131 : quic::QuicConnectionHelperInterface& helper, 132 : quic::QuicAlarmFactory& alarm_factory, 133 : const quic::ParsedQuicVersionVector& supported_versions, 134 : Event::Dispatcher& dispatcher, 135 : Network::ConnectionSocketPtr&& connection_socket, 136 : quic::ConnectionIdGeneratorInterface& generator); 137 : 138 : void onFileEvent(uint32_t events, Network::ConnectionSocket& connection_socket); 139 : 140 : void maybeMigratePort(); 141 : 142 : void probeWithNewPort(const quic::QuicSocketAddress& peer_address, 143 : quic::PathValidationReason reason); 144 : 145 : OptRef<PacketsToReadDelegate> delegate_; 146 : uint32_t packets_dropped_{0}; 147 : Event::Dispatcher& dispatcher_; 148 : bool migrate_port_on_path_degrading_{false}; 149 : uint8_t num_socket_switches_{0}; 150 : }; 151 : 152 : } // namespace Quic 153 : } // namespace Envoy