blob: c25329c5fc816fd80b6009a2bd2f51efc6f57f36 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quic/core/uber_received_packet_manager.h"
#include "quic/core/quic_types.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_bug_tracker.h"
namespace quic {
UberReceivedPacketManager::UberReceivedPacketManager(QuicConnectionStats* stats)
: supports_multiple_packet_number_spaces_(false) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.set_connection_stats(stats);
}
}
UberReceivedPacketManager::~UberReceivedPacketManager() {}
void UberReceivedPacketManager::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.SetFromConfig(config, perspective);
}
}
bool UberReceivedPacketManager::IsAwaitingPacket(
EncryptionLevel decrypted_packet_level,
QuicPacketNumber packet_number) const {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].IsAwaitingPacket(packet_number);
}
return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
decrypted_packet_level)]
.IsAwaitingPacket(packet_number);
}
const QuicFrame UberReceivedPacketManager::GetUpdatedAckFrame(
PacketNumberSpace packet_number_space,
QuicTime approximate_now) {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].GetUpdatedAckFrame(approximate_now);
}
return received_packet_managers_[packet_number_space].GetUpdatedAckFrame(
approximate_now);
}
void UberReceivedPacketManager::RecordPacketReceived(
EncryptionLevel decrypted_packet_level,
const QuicPacketHeader& header,
QuicTime receipt_time) {
if (!supports_multiple_packet_number_spaces_) {
received_packet_managers_[0].RecordPacketReceived(header, receipt_time);
return;
}
received_packet_managers_[QuicUtils::GetPacketNumberSpace(
decrypted_packet_level)]
.RecordPacketReceived(header, receipt_time);
}
void UberReceivedPacketManager::DontWaitForPacketsBefore(
EncryptionLevel decrypted_packet_level,
QuicPacketNumber least_unacked) {
if (!supports_multiple_packet_number_spaces_) {
received_packet_managers_[0].DontWaitForPacketsBefore(least_unacked);
return;
}
received_packet_managers_[QuicUtils::GetPacketNumberSpace(
decrypted_packet_level)]
.DontWaitForPacketsBefore(least_unacked);
}
void UberReceivedPacketManager::MaybeUpdateAckTimeout(
bool should_last_packet_instigate_acks,
EncryptionLevel decrypted_packet_level,
QuicPacketNumber last_received_packet_number,
QuicTime now,
const RttStats* rtt_stats) {
if (!supports_multiple_packet_number_spaces_) {
received_packet_managers_[0].MaybeUpdateAckTimeout(
should_last_packet_instigate_acks, last_received_packet_number, now,
rtt_stats);
return;
}
received_packet_managers_[QuicUtils::GetPacketNumberSpace(
decrypted_packet_level)]
.MaybeUpdateAckTimeout(should_last_packet_instigate_acks,
last_received_packet_number, now, rtt_stats);
}
void UberReceivedPacketManager::ResetAckStates(
EncryptionLevel encryption_level) {
if (!supports_multiple_packet_number_spaces_) {
received_packet_managers_[0].ResetAckStates();
return;
}
received_packet_managers_[QuicUtils::GetPacketNumberSpace(encryption_level)]
.ResetAckStates();
if (encryption_level == ENCRYPTION_INITIAL) {
// After one Initial ACK is sent, the others should be sent 'immediately'.
received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
kAlarmGranularity);
}
}
void UberReceivedPacketManager::EnableMultiplePacketNumberSpacesSupport(
Perspective perspective) {
if (supports_multiple_packet_number_spaces_) {
QUIC_BUG(quic_bug_10495_1)
<< "Multiple packet number spaces has already been enabled";
return;
}
if (received_packet_managers_[0].GetLargestObserved().IsInitialized()) {
QUIC_BUG(quic_bug_10495_2)
<< "Try to enable multiple packet number spaces support after any "
"packet has been received.";
return;
}
// In IETF QUIC, the peer is expected to acknowledge packets in Initial and
// Handshake packets with minimal delay.
if (perspective == Perspective::IS_CLIENT) {
// Delay the first server ACK, because server ACKs are padded to
// full size and count towards the amplification limit.
received_packet_managers_[INITIAL_DATA].set_local_max_ack_delay(
kAlarmGranularity);
}
received_packet_managers_[HANDSHAKE_DATA].set_local_max_ack_delay(
kAlarmGranularity);
supports_multiple_packet_number_spaces_ = true;
}
bool UberReceivedPacketManager::IsAckFrameUpdated() const {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].ack_frame_updated();
}
for (const auto& received_packet_manager : received_packet_managers_) {
if (received_packet_manager.ack_frame_updated()) {
return true;
}
}
return false;
}
QuicPacketNumber UberReceivedPacketManager::GetLargestObserved(
EncryptionLevel decrypted_packet_level) const {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].GetLargestObserved();
}
return received_packet_managers_[QuicUtils::GetPacketNumberSpace(
decrypted_packet_level)]
.GetLargestObserved();
}
QuicTime UberReceivedPacketManager::GetAckTimeout(
PacketNumberSpace packet_number_space) const {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].ack_timeout();
}
return received_packet_managers_[packet_number_space].ack_timeout();
}
QuicTime UberReceivedPacketManager::GetEarliestAckTimeout() const {
QuicTime ack_timeout = QuicTime::Zero();
// Returns the earliest non-zero ack timeout.
for (const auto& received_packet_manager : received_packet_managers_) {
const QuicTime timeout = received_packet_manager.ack_timeout();
if (!ack_timeout.IsInitialized()) {
ack_timeout = timeout;
continue;
}
if (timeout.IsInitialized()) {
ack_timeout = std::min(ack_timeout, timeout);
}
}
return ack_timeout;
}
bool UberReceivedPacketManager::IsAckFrameEmpty(
PacketNumberSpace packet_number_space) const {
if (!supports_multiple_packet_number_spaces_) {
return received_packet_managers_[0].IsAckFrameEmpty();
}
return received_packet_managers_[packet_number_space].IsAckFrameEmpty();
}
QuicPacketNumber UberReceivedPacketManager::peer_least_packet_awaiting_ack()
const {
QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
return received_packet_managers_[0].peer_least_packet_awaiting_ack();
}
size_t UberReceivedPacketManager::min_received_before_ack_decimation() const {
return received_packet_managers_[0].min_received_before_ack_decimation();
}
void UberReceivedPacketManager::set_min_received_before_ack_decimation(
size_t new_value) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.set_min_received_before_ack_decimation(new_value);
}
}
void UberReceivedPacketManager::set_ack_frequency(size_t new_value) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.set_ack_frequency(new_value);
}
}
const QuicAckFrame& UberReceivedPacketManager::ack_frame() const {
QUICHE_DCHECK(!supports_multiple_packet_number_spaces_);
return received_packet_managers_[0].ack_frame();
}
const QuicAckFrame& UberReceivedPacketManager::GetAckFrame(
PacketNumberSpace packet_number_space) const {
QUICHE_DCHECK(supports_multiple_packet_number_spaces_);
return received_packet_managers_[packet_number_space].ack_frame();
}
void UberReceivedPacketManager::set_max_ack_ranges(size_t max_ack_ranges) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.set_max_ack_ranges(max_ack_ranges);
}
}
void UberReceivedPacketManager::set_save_timestamps(bool save_timestamps) {
for (auto& received_packet_manager : received_packet_managers_) {
received_packet_manager.set_save_timestamps(
save_timestamps, supports_multiple_packet_number_spaces_);
}
}
void UberReceivedPacketManager::OnAckFrequencyFrame(
const QuicAckFrequencyFrame& frame) {
if (!supports_multiple_packet_number_spaces_) {
QUIC_BUG(quic_bug_10495_3)
<< "Received AckFrequencyFrame when multiple packet number spaces "
"is not supported";
return;
}
received_packet_managers_[APPLICATION_DATA].OnAckFrequencyFrame(frame);
}
} // namespace quic