#include "quiche/quic/core/quic_dispatcher.h"
#include <openssl/ssl.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <list>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/chlo_extractor.h"
#include "quiche/quic/core/connection_id_generator.h"
#include "quiche/quic/core/crypto/crypto_handshake_message.h"
#include "quiche/quic/core/crypto/crypto_protocol.h"
#include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
#include "quiche/quic/core/frames/quic_connection_close_frame.h"
#include "quiche/quic/core/frames/quic_frame.h"
#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
#include "quiche/quic/core/frames/quic_stop_sending_frame.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_blocked_writer_interface.h"
#include "quiche/quic/core/quic_buffered_packet_store.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_connection_id.h"
#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/core/quic_crypto_server_stream_base.h"
#include "quiche/quic/core/quic_data_writer.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_packet_creator.h"
#include "quiche/quic/core/quic_packet_number.h"
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_stream_frame_data_producer.h"
#include "quiche/quic/core/quic_stream_send_buffer.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_time_wait_list_manager.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_version_manager.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/core/tls_chlo_extractor.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_stack_trace.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/print_elements.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_text_utils.h"
namespace quic {
BufferedPacket;
BufferedPacketList;
EnqueuePacketResult;
namespace {
const QuicPacketLength kMinClientInitialPacketLength = …;
class DeleteSessionsAlarm : public QuicAlarm::DelegateWithoutContext { … };
class ClearStatelessResetAddressesAlarm
: public QuicAlarm::DelegateWithoutContext { … };
class StatelessConnectionTerminator { … };
class ChloAlpnSniExtractor : public ChloExtractor::Delegate { … };
}
QuicDispatcher::QuicDispatcher(
const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
QuicVersionManager* version_manager,
std::unique_ptr<QuicConnectionHelperInterface> helper,
std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
std::unique_ptr<QuicAlarmFactory> alarm_factory,
uint8_t expected_server_connection_id_length,
ConnectionIdGeneratorInterface& connection_id_generator)
: … { … }
QuicDispatcher::~QuicDispatcher() { … }
void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) { … }
void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
const QuicReceivedPacket& packet) { … }
namespace {
constexpr bool IsSourceUdpPortBlocked(uint16_t port) { … }
}
bool QuicDispatcher::MaybeDispatchPacket(
const ReceivedPacketInfo& packet_info) { … }
void QuicDispatcher::ProcessHeader(ReceivedPacketInfo* packet_info) { … }
QuicDispatcher::ExtractChloResult
QuicDispatcher::TryExtractChloOrBufferEarlyPacket(
const ReceivedPacketInfo& packet_info) { … }
std::string QuicDispatcher::SelectAlpn(const std::vector<std::string>& alpns) { … }
QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
const ReceivedPacketInfo& packet_info) { … }
void QuicDispatcher::CleanUpSession(QuicConnectionId server_connection_id,
QuicConnection* connection,
QuicErrorCode ,
const std::string& ,
ConnectionCloseSource ) { … }
void QuicDispatcher::StartAcceptingNewConnections() { … }
void QuicDispatcher::StopAcceptingNewConnections() { … }
void QuicDispatcher::PerformActionOnActiveSessions(
quiche::UnretainedCallback<void(QuicSession*)> operation) const { … }
std::vector<std::shared_ptr<QuicSession>> QuicDispatcher::GetSessionsSnapshot()
const { … }
std::unique_ptr<QuicPerPacketContext> QuicDispatcher::GetPerPacketContext()
const { … }
void QuicDispatcher::DeleteSessions() { … }
void QuicDispatcher::ClearStatelessResetAddresses() { … }
void QuicDispatcher::OnCanWrite() { … }
bool QuicDispatcher::HasPendingWrites() const { … }
void QuicDispatcher::Shutdown() { … }
void QuicDispatcher::OnConnectionClosed(QuicConnectionId server_connection_id,
QuicErrorCode error,
const std::string& error_details,
ConnectionCloseSource source) { … }
void QuicDispatcher::OnWriteBlocked(
QuicBlockedWriterInterface* blocked_writer) { … }
void QuicDispatcher::OnRstStreamReceived(const QuicRstStreamFrame& ) { … }
void QuicDispatcher::OnStopSendingReceived(
const QuicStopSendingFrame& ) { … }
bool QuicDispatcher::TryAddNewConnectionId(
const QuicConnectionId& server_connection_id,
const QuicConnectionId& new_connection_id) { … }
void QuicDispatcher::OnConnectionIdRetired(
const QuicConnectionId& server_connection_id) { … }
void QuicDispatcher::OnConnectionAddedToTimeWaitList(
QuicConnectionId server_connection_id) { … }
void QuicDispatcher::StatelesslyTerminateConnection(
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
QuicConnectionId server_connection_id, PacketHeaderFormat format,
bool version_flag, bool use_length_prefix, ParsedQuicVersion version,
QuicErrorCode error_code, const std::string& error_details,
QuicTimeWaitListManager::TimeWaitAction action) { … }
void QuicDispatcher::StatelesslyTerminateConnection(
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
QuicConnectionId server_connection_id, PacketHeaderFormat format,
bool version_flag, bool use_length_prefix, ParsedQuicVersion version,
QuicErrorCode error_code, const std::string& error_details,
QuicTimeWaitListManager::TimeWaitAction action,
const std::optional<QuicConnectionId>& replaced_connection_id,
QuicPacketNumber last_sent_packet_number) { … }
bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
const ReceivedPacketInfo& ) { … }
void QuicDispatcher::OnExpiredPackets(
QuicConnectionId server_connection_id,
BufferedPacketList early_arrived_packets) { … }
void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) { … }
bool QuicDispatcher::HasChlosBuffered() const { … }
bool QuicDispatcher::HasBufferedPackets(QuicConnectionId server_connection_id) { … }
void QuicDispatcher::OnBufferPacketFailure(
EnqueuePacketResult result, QuicConnectionId server_connection_id) { … }
QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { … }
void QuicDispatcher::ProcessChlo(ParsedClientHello parsed_chlo,
ReceivedPacketInfo* packet_info) { … }
void QuicDispatcher::SetLastError(QuicErrorCode error) { … }
bool QuicDispatcher::OnFailedToDispatchPacket(
const ReceivedPacketInfo& ) { … }
const ParsedQuicVersionVector& QuicDispatcher::GetSupportedVersions() { … }
void QuicDispatcher::DeliverPacketsToSession(
const std::list<BufferedPacket>& packets, QuicSession* session) { … }
bool QuicDispatcher::IsSupportedVersion(const ParsedQuicVersion version) { … }
bool QuicDispatcher::IsServerConnectionIdTooShort(
QuicConnectionId connection_id) const { … }
std::shared_ptr<QuicSession> QuicDispatcher::CreateSessionFromChlo(
const QuicConnectionId original_connection_id,
const std::optional<QuicConnectionId>& replaced_connection_id,
const ParsedClientHello& parsed_chlo, const ParsedQuicVersion version,
const QuicSocketAddress self_address, const QuicSocketAddress peer_address,
ConnectionIdGeneratorInterface* connection_id_generator,
absl::Span<const DispatcherSentPacket> dispatcher_sent_packets) { … }
QuicDispatcher::HandleCidCollisionResult
QuicDispatcher::HandleConnectionIdCollision(
const QuicConnectionId& original_connection_id,
const QuicConnectionId& replaced_connection_id,
const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address, ParsedQuicVersion version,
const ParsedClientHello* parsed_chlo) { … }
void QuicDispatcher::MaybeResetPacketsWithNoVersion(
const ReceivedPacketInfo& packet_info) { … }
void QuicDispatcher::MaybeSendVersionNegotiationPacket(
const ReceivedPacketInfo& packet_info) { … }
size_t QuicDispatcher::NumSessions() const { … }
}