#include "quiche/quic/core/quic_session.h"
#include <algorithm>
#include <cstdint>
#include <limits>
#include <memory>
#include <optional>
#include <ostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/frames/quic_ack_frequency_frame.h"
#include "quiche/quic/core/frames/quic_window_update_frame.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_connection_context.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_flow_controller.h"
#include "quiche/quic/core/quic_stream_priority.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/core/quic_write_blocked_list.h"
#include "quiche/quic/core/web_transport_write_blocked_list.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_server_stats.h"
#include "quiche/quic/platform/api/quic_stack_trace.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/quiche_text_utils.h"
namespace quic {
namespace {
class ClosedStreamsCleanUpDelegate : public QuicAlarm::Delegate { … };
class StreamCountResetAlarmDelegate : public QuicAlarm::Delegate { … };
std::unique_ptr<QuicWriteBlockedListInterface> CreateWriteBlockedList(
QuicPriorityType priority_type) { … }
}
#define ENDPOINT …
QuicSession::QuicSession(
QuicConnection* connection, Visitor* owner, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
QuicStreamCount num_expected_unidirectional_static_streams)
: … { … }
QuicSession::QuicSession(
QuicConnection* connection, Visitor* owner, const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
QuicStreamCount num_expected_unidirectional_static_streams,
std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer,
QuicPriorityType priority_type)
: … { … }
void QuicSession::Initialize() { … }
QuicSession::~QuicSession() { … }
PendingStream* QuicSession::PendingStreamOnStreamFrame(
const QuicStreamFrame& frame) { … }
bool QuicSession::MaybeProcessPendingStream(PendingStream* pending) { … }
void QuicSession::PendingStreamOnWindowUpdateFrame(
const QuicWindowUpdateFrame& frame) { … }
void QuicSession::PendingStreamOnStopSendingFrame(
const QuicStopSendingFrame& frame) { … }
void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { … }
void QuicSession::OnCryptoFrame(const QuicCryptoFrame& frame) { … }
void QuicSession::OnStopSendingFrame(const QuicStopSendingFrame& frame) { … }
void QuicSession::OnPacketDecrypted(EncryptionLevel level) { … }
void QuicSession::OnOneRttPacketAcknowledged() { … }
void QuicSession::OnHandshakePacketSent() { … }
std::unique_ptr<QuicDecrypter>
QuicSession::AdvanceKeysAndCreateCurrentOneRttDecrypter() { … }
std::unique_ptr<QuicEncrypter> QuicSession::CreateCurrentOneRttEncrypter() { … }
void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) { … }
void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { … }
void QuicSession::OnGoAway(const QuicGoAwayFrame& ) { … }
void QuicSession::OnMessageReceived(absl::string_view message) { … }
void QuicSession::OnHandshakeDoneReceived() { … }
void QuicSession::OnNewTokenReceived(absl::string_view token) { … }
void QuicSession::RecordConnectionCloseAtServer(QuicErrorCode error,
ConnectionCloseSource source) { … }
void QuicSession::OnConnectionClosed(const QuicConnectionCloseFrame& frame,
ConnectionCloseSource source) { … }
void QuicSession::OnWriteBlocked() { … }
void QuicSession::OnSuccessfulVersionNegotiation(
const ParsedQuicVersion& ) { … }
void QuicSession::OnPacketReceived(const QuicSocketAddress& ,
const QuicSocketAddress& peer_address,
bool is_connectivity_probe) { … }
void QuicSession::OnPathDegrading() { … }
void QuicSession::OnForwardProgressMadeAfterPathDegrading() { … }
bool QuicSession::AllowSelfAddressChange() const { … }
void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { … }
void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) { … }
bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
uint64_t previous_bytes_written,
bool previous_fin_sent) { … }
bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const { … }
void QuicSession::OnCanWrite() { … }
bool QuicSession::WillingAndAbleToWrite() const { … }
std::string QuicSession::GetStreamsInfoForLogging() const { … }
bool QuicSession::HasPendingHandshake() const { … }
void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
const QuicReceivedPacket& packet) { … }
std::string QuicSession::on_closed_frame_string() const { … }
QuicConsumedData QuicSession::WritevData(QuicStreamId id, size_t write_length,
QuicStreamOffset offset,
StreamSendingState state,
TransmissionType type,
EncryptionLevel level) { … }
size_t QuicSession::SendCryptoData(EncryptionLevel level, size_t write_length,
QuicStreamOffset offset,
TransmissionType type) { … }
void QuicSession::OnControlFrameManagerError(QuicErrorCode error_code,
std::string error_details) { … }
bool QuicSession::WriteControlFrame(const QuicFrame& frame,
TransmissionType type) { … }
void QuicSession::ResetStream(QuicStreamId id, QuicRstStreamErrorCode error) { … }
void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
QuicResetStreamError error,
QuicStreamOffset bytes_written) { … }
void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
QuicResetStreamError error) { … }
void QuicSession::SendGoAway(QuicErrorCode error_code,
const std::string& reason) { … }
void QuicSession::SendBlocked(QuicStreamId id, QuicStreamOffset byte_offset) { … }
void QuicSession::SendWindowUpdate(QuicStreamId id,
QuicStreamOffset byte_offset) { … }
void QuicSession::OnStreamError(QuicErrorCode error_code,
std::string error_details) { … }
void QuicSession::OnStreamError(QuicErrorCode error_code,
QuicIetfTransportErrorCodes ietf_error,
std::string error_details) { … }
bool QuicSession::CanSendMaxStreams() { … }
void QuicSession::SendMaxStreams(QuicStreamCount stream_count,
bool unidirectional) { … }
void QuicSession::InsertLocallyClosedStreamsHighestOffset(
const QuicStreamId id, QuicStreamOffset offset) { … }
void QuicSession::OnStreamClosed(QuicStreamId stream_id) { … }
void QuicSession::ClosePendingStream(QuicStreamId stream_id) { … }
bool QuicSession::ShouldProcessFrameByPendingStream(QuicFrameType type,
QuicStreamId id) const { … }
void QuicSession::OnFinalByteOffsetReceived(
QuicStreamId stream_id, QuicStreamOffset final_byte_offset) { … }
bool QuicSession::IsEncryptionEstablished() const { … }
bool QuicSession::OneRttKeysAvailable() const { … }
void QuicSession::OnConfigNegotiated() { … }
std::optional<std::string> QuicSession::OnAlpsData(const uint8_t* ,
size_t ) { … }
void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) { … }
void QuicSession::HandleFrameOnNonexistentOutgoingStream(
QuicStreamId stream_id) { … }
void QuicSession::HandleRstOnValidNonexistentStream(
const QuicRstStreamFrame& frame) { … }
void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { … }
void QuicSession::OnNewStreamUnidirectionalFlowControlWindow(
QuicStreamOffset new_window) { … }
void QuicSession::OnNewStreamOutgoingBidirectionalFlowControlWindow(
QuicStreamOffset new_window) { … }
void QuicSession::OnNewStreamIncomingBidirectionalFlowControlWindow(
QuicStreamOffset new_window) { … }
void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { … }
bool QuicSession::OnNewDecryptionKeyAvailable(
EncryptionLevel level, std::unique_ptr<QuicDecrypter> decrypter,
bool set_alternative_decrypter, bool latch_once_used) { … }
void QuicSession::OnNewEncryptionKeyAvailable(
EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) { … }
void QuicSession::SetDefaultEncryptionLevel(EncryptionLevel level) { … }
void QuicSession::OnTlsHandshakeComplete() { … }
bool QuicSession::MaybeSendAddressToken() { … }
void QuicSession::DiscardOldDecryptionKey(EncryptionLevel level) { … }
void QuicSession::DiscardOldEncryptionKey(EncryptionLevel level) { … }
void QuicSession::NeuterHandshakeData() { … }
void QuicSession::OnZeroRttRejected(int reason) { … }
bool QuicSession::FillTransportParameters(TransportParameters* params) { … }
QuicErrorCode QuicSession::ProcessTransportParameters(
const TransportParameters& params, bool is_resumption,
std::string* error_details) { … }
void QuicSession::OnHandshakeCallbackDone() { … }
bool QuicSession::PacketFlusherAttached() const { … }
void QuicSession::OnEncryptedClientHelloSent(
absl::string_view client_hello) const { … }
void QuicSession::OnEncryptedClientHelloReceived(
absl::string_view client_hello) const { … }
void QuicSession::OnCryptoHandshakeMessageSent(
const CryptoHandshakeMessage& ) { … }
void QuicSession::OnCryptoHandshakeMessageReceived(
const CryptoHandshakeMessage& ) { … }
void QuicSession::RegisterStreamPriority(QuicStreamId id, bool is_static,
const QuicStreamPriority& priority) { … }
void QuicSession::UnregisterStreamPriority(QuicStreamId id) { … }
void QuicSession::UpdateStreamPriority(QuicStreamId id,
const QuicStreamPriority& new_priority) { … }
void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) { … }
QuicStreamId QuicSession::GetNextOutgoingBidirectionalStreamId() { … }
QuicStreamId QuicSession::GetNextOutgoingUnidirectionalStreamId() { … }
bool QuicSession::CanOpenNextOutgoingBidirectionalStream() { … }
bool QuicSession::CanOpenNextOutgoingUnidirectionalStream() { … }
QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams()
const { … }
QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) { … }
void QuicSession::StreamDraining(QuicStreamId stream_id, bool unidirectional) { … }
bool QuicSession::MaybeIncreaseLargestPeerStreamId(
const QuicStreamId stream_id) { … }
bool QuicSession::ShouldYield(QuicStreamId stream_id) { … }
PendingStream* QuicSession::GetOrCreatePendingStream(QuicStreamId stream_id) { … }
void QuicSession::set_largest_peer_created_stream_id(
QuicStreamId largest_peer_created_stream_id) { … }
QuicStreamId QuicSession::GetLargestPeerCreatedStreamId(
bool unidirectional) const { … }
void QuicSession::DeleteConnection() { … }
bool QuicSession::MaybeSetStreamPriority(QuicStreamId stream_id,
const QuicStreamPriority& priority) { … }
bool QuicSession::IsClosedStream(QuicStreamId id) { … }
bool QuicSession::IsOpenStream(QuicStreamId id) { … }
bool QuicSession::IsStaticStream(QuicStreamId id) const { … }
size_t QuicSession::GetNumActiveStreams() const { … }
void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) { … }
bool QuicSession::HasDataToWrite() const { … }
void QuicSession::OnAckNeedsRetransmittableFrame() { … }
void QuicSession::SendAckFrequency(const QuicAckFrequencyFrame& frame) { … }
void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) { … }
void QuicSession::SendRetireConnectionId(uint64_t sequence_number) { … }
bool QuicSession::MaybeReserveConnectionId(
const QuicConnectionId& server_connection_id) { … }
void QuicSession::OnServerConnectionIdRetired(
const QuicConnectionId& server_connection_id) { … }
bool QuicSession::IsConnectionFlowControlBlocked() const { … }
bool QuicSession::IsStreamFlowControlBlocked() { … }
size_t QuicSession::MaxAvailableBidirectionalStreams() const { … }
size_t QuicSession::MaxAvailableUnidirectionalStreams() const { … }
bool QuicSession::IsIncomingStream(QuicStreamId id) const { … }
void QuicSession::MaybeCloseZombieStream(QuicStreamId id) { … }
QuicStream* QuicSession::GetStream(QuicStreamId id) const { … }
QuicStream* QuicSession::GetActiveStream(QuicStreamId id) const { … }
bool QuicSession::OnFrameAcked(const QuicFrame& frame,
QuicTime::Delta ack_delay_time,
QuicTime receive_timestamp) { … }
void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) { … }
void QuicSession::OnFrameLost(const QuicFrame& frame) { … }
bool QuicSession::RetransmitFrames(const QuicFrames& frames,
TransmissionType type) { … }
bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const { … }
bool QuicSession::HasUnackedCryptoData() const { … }
bool QuicSession::HasUnackedStreamData() const { … }
HandshakeState QuicSession::GetHandshakeState() const { … }
QuicByteCount QuicSession::GetFlowControlSendWindowSize(QuicStreamId id) { … }
WriteStreamDataResult QuicSession::WriteStreamData(QuicStreamId id,
QuicStreamOffset offset,
QuicByteCount data_length,
QuicDataWriter* writer) { … }
bool QuicSession::WriteCryptoData(EncryptionLevel level,
QuicStreamOffset offset,
QuicByteCount data_length,
QuicDataWriter* writer) { … }
StatelessResetToken QuicSession::GetStatelessResetToken() const { … }
bool QuicSession::CanWriteStreamData() const { … }
bool QuicSession::RetransmitLostData() { … }
void QuicSession::NeuterUnencryptedData() { … }
void QuicSession::SetTransmissionType(TransmissionType type) { … }
MessageResult QuicSession::SendMessage(
absl::Span<quiche::QuicheMemSlice> message) { … }
MessageResult QuicSession::SendMessage(quiche::QuicheMemSlice message) { … }
MessageResult QuicSession::SendMessage(
absl::Span<quiche::QuicheMemSlice> message, bool flush) { … }
void QuicSession::OnMessageAcked(QuicMessageId message_id,
QuicTime ) { … }
void QuicSession::OnMessageLost(QuicMessageId message_id) { … }
void QuicSession::CleanUpClosedStreams() { … }
QuicPacketLength QuicSession::GetCurrentLargestMessagePayload() const { … }
QuicPacketLength QuicSession::GetGuaranteedLargestMessagePayload() const { … }
QuicStreamId QuicSession::next_outgoing_bidirectional_stream_id() const { … }
QuicStreamId QuicSession::next_outgoing_unidirectional_stream_id() const { … }
bool QuicSession::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) { … }
bool QuicSession::OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) { … }
size_t QuicSession::max_open_incoming_bidirectional_streams() const { … }
size_t QuicSession::max_open_incoming_unidirectional_streams() const { … }
std::vector<absl::string_view>::const_iterator QuicSession::SelectAlpn(
const std::vector<absl::string_view>& alpns) const { … }
void QuicSession::OnAlpnSelected(absl::string_view alpn) { … }
void QuicSession::NeuterCryptoDataOfEncryptionLevel(EncryptionLevel level) { … }
void QuicSession::PerformActionOnActiveStreams(
quiche::UnretainedCallback<bool(QuicStream*)> action) { … }
void QuicSession::PerformActionOnActiveStreams(
quiche::UnretainedCallback<bool(QuicStream*)> action) const { … }
EncryptionLevel QuicSession::GetEncryptionLevelToSendApplicationData() const { … }
void QuicSession::ProcessAllPendingStreams() { … }
void QuicSession::ValidatePath(
std::unique_ptr<QuicPathValidationContext> context,
std::unique_ptr<QuicPathValidator::ResultDelegate> result_delegate,
PathValidationReason reason) { … }
bool QuicSession::HasPendingPathValidation() const { … }
bool QuicSession::MigratePath(const QuicSocketAddress& self_address,
const QuicSocketAddress& peer_address,
QuicPacketWriter* writer, bool owns_writer) { … }
bool QuicSession::ValidateToken(absl::string_view token) { … }
void QuicSession::OnServerPreferredAddressAvailable(
const QuicSocketAddress& server_preferred_address) { … }
QuicStream* QuicSession::ProcessPendingStream(PendingStream* pending) { … }
bool QuicSession::ExceedsPerLoopStreamLimit() const { … }
void QuicSession::OnStreamCountReset() { … }
#undef ENDPOINT
}