blob: ca431482545216f5f0c3c7003e89685d1b24a31d [file] [log] [blame]
// Copyright (c) 2020 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_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_one_block_arena.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/quic/platform/api/quic_flags.h"
namespace quic {
namespace test {
class QuicConnectionPeer;
class QuicIdleNetworkDetectorTestPeer;
} // namespace test
// QuicIdleNetworkDetector detects handshake timeout and idle network timeout.
// Handshake timeout detection is disabled after handshake completes. Idle
// network deadline is extended by network activity (e.g., sending or receiving
// packets).
class QUIC_EXPORT_PRIVATE QuicIdleNetworkDetector {
class QUIC_EXPORT_PRIVATE Delegate {
virtual ~Delegate() {}
// Called when handshake times out.
virtual void OnHandshakeTimeout() = 0;
// Called when idle network has been detected.
virtual void OnIdleNetworkDetected() = 0;
// Called when bandwidth update alarms.
virtual void OnBandwidthUpdateTimeout() = 0;
QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
QuicConnectionArena* arena,
QuicAlarmFactory* alarm_factory,
QuicConnectionContext* context);
void OnAlarm();
// Called to set handshake_timeout_ and idle_network_timeout_.
void SetTimeouts(QuicTime::Delta handshake_timeout,
QuicTime::Delta idle_network_timeout);
// Stop the detection once and for all.
void StopDetection();
// Called when a packet gets sent.
void OnPacketSent(QuicTime now, QuicTime::Delta pto_delay);
// Called when a packet gets received.
void OnPacketReceived(QuicTime now);
void enable_shorter_idle_timeout_on_sent_packet() {
shorter_idle_timeout_on_sent_packet_ = true;
QuicTime::Delta handshake_timeout() const { return handshake_timeout_; }
QuicTime time_of_last_received_packet() const {
return time_of_last_received_packet_;
QuicTime last_network_activity_time() const {
return std::max(time_of_last_received_packet_,
QuicTime::Delta idle_network_timeout() const { return idle_network_timeout_; }
QuicTime::Delta bandwidth_update_timeout() const {
return bandwidth_update_timeout_;
QuicTime GetIdleNetworkDeadline() const;
friend class test::QuicConnectionPeer;
friend class test::QuicIdleNetworkDetectorTestPeer;
void SetAlarm();
void MaybeSetAlarmOnSentPacket(QuicTime::Delta pto_delay);
QuicTime GetBandwidthUpdateDeadline() const;
Delegate* delegate_; // Not owned.
// Start time of the detector, handshake deadline = start_time_ +
// handshake_timeout_.
const QuicTime start_time_;
// Handshake timeout. Infinite means handshake has completed.
QuicTime::Delta handshake_timeout_;
// Time that last packet is received for this connection. Initialized to
// start_time_.
QuicTime time_of_last_received_packet_;
// Time that the first packet gets sent after the received packet. idle
// network deadline = std::max(time_of_last_received_packet_,
// time_of_first_packet_sent_after_receiving_) + idle_network_timeout_.
// Initialized to 0.
QuicTime time_of_first_packet_sent_after_receiving_;
// Idle network timeout. Infinite means no idle network timeout.
QuicTime::Delta idle_network_timeout_;
// Bandwidth update timeout. Infinite means no bandwidth update timeout.
QuicTime::Delta bandwidth_update_timeout_;
QuicArenaScopedPtr<QuicAlarm> alarm_;
bool shorter_idle_timeout_on_sent_packet_ = false;
// Whether |StopDetection| has been called.
bool stopped_ = false;
} // namespace quic