blob: fcd29d888e2ef120ba70235f914c21c0538d31cd [file] [log] [blame]
// Copyright 2024 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 "quiche/quic/core/quic_connection_alarms.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_connection_context.h"
#include "quiche/common/platform/api/quiche_logging.h"
namespace quic {
namespace {
// Base class of all alarms owned by a QuicConnection.
class QuicConnectionAlarmDelegate : public QuicAlarm::Delegate {
public:
explicit QuicConnectionAlarmDelegate(QuicConnection* connection)
: connection_(connection) {}
QuicConnectionAlarmDelegate(const QuicConnectionAlarmDelegate&) = delete;
QuicConnectionAlarmDelegate& operator=(const QuicConnectionAlarmDelegate&) =
delete;
QuicConnectionContext* GetConnectionContext() override {
return (connection_ == nullptr) ? nullptr : connection_->context();
}
protected:
QuicConnection* connection_;
};
// An alarm that is scheduled to send an ack if a timeout occurs.
class AckAlarmDelegate : public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->ack_frame_updated());
QUICHE_DCHECK(connection_->connected());
QuicConnection::ScopedPacketFlusher flusher(connection_);
if (connection_->SupportsMultiplePacketNumberSpaces()) {
connection_->SendAllPendingAcks();
} else {
connection_->SendAck();
}
}
};
// This alarm will be scheduled any time a data-bearing packet is sent out.
// When the alarm goes off, the connection checks to see if the oldest packets
// have been acked, and retransmit them if they have not.
class RetransmissionAlarmDelegate : public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
connection_->OnRetransmissionTimeout();
}
};
// An alarm that is scheduled when the SentPacketManager requires a delay
// before sending packets and fires when the packet may be sent.
class SendAlarmDelegate : public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
connection_->OnSendAlarm();
}
};
class MtuDiscoveryAlarmDelegate : public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
connection_->DiscoverMtu();
}
};
class ProcessUndecryptablePacketsAlarmDelegate
: public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
QuicConnection::ScopedPacketFlusher flusher(connection_);
connection_->MaybeProcessUndecryptablePackets();
}
};
class DiscardPreviousOneRttKeysAlarmDelegate
: public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
connection_->DiscardPreviousOneRttKeys();
}
};
class DiscardZeroRttDecryptionKeysAlarmDelegate
: public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
QUIC_DLOG(INFO) << "0-RTT discard alarm fired";
connection_->RemoveDecrypter(ENCRYPTION_ZERO_RTT);
connection_->RetireOriginalDestinationConnectionId();
}
};
class MultiPortProbingAlarmDelegate : public QuicConnectionAlarmDelegate {
public:
using QuicConnectionAlarmDelegate::QuicConnectionAlarmDelegate;
void OnAlarm() override {
QUICHE_DCHECK(connection_->connected());
QUIC_DLOG(INFO) << "Alternative path probing alarm fired";
connection_->MaybeProbeMultiPortPath();
}
};
} // namespace
QuicConnectionAlarms::QuicConnectionAlarms(QuicConnection* connection,
QuicAlarmFactory& alarm_factory,
QuicConnectionArena& arena)
: ack_alarm_(alarm_factory.CreateAlarm(
arena.New<AckAlarmDelegate>(connection), &arena)),
retransmission_alarm_(alarm_factory.CreateAlarm(
arena.New<RetransmissionAlarmDelegate>(connection), &arena)),
send_alarm_(alarm_factory.CreateAlarm(
arena.New<SendAlarmDelegate>(connection), &arena)),
mtu_discovery_alarm_(alarm_factory.CreateAlarm(
arena.New<MtuDiscoveryAlarmDelegate>(connection), &arena)),
process_undecryptable_packets_alarm_(alarm_factory.CreateAlarm(
arena.New<ProcessUndecryptablePacketsAlarmDelegate>(connection),
&arena)),
discard_previous_one_rtt_keys_alarm_(alarm_factory.CreateAlarm(
arena.New<DiscardPreviousOneRttKeysAlarmDelegate>(connection),
&arena)),
discard_zero_rtt_decryption_keys_alarm_(alarm_factory.CreateAlarm(
arena.New<DiscardZeroRttDecryptionKeysAlarmDelegate>(connection),
&arena)),
multi_port_probing_alarm_(alarm_factory.CreateAlarm(
arena.New<MultiPortProbingAlarmDelegate>(connection), &arena)) {}
} // namespace quic