| // Copyright (c) 2022 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. | |
| #ifndef QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ | |
| #define QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ | |
| #include "quiche/quic/core/quic_alarm.h" | |
| #include "quiche/quic/core/quic_alarm_factory.h" | |
| #include "quiche/quic/core/quic_constants.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" | |
| namespace quic { | |
| namespace test { | |
| class QuicConnectionPeer; | |
| class QuicPingManagerPeer; | |
| } // namespace test | |
| // QuicPingManager manages an alarm that has two modes: | |
| // 1) keep-alive. When alarm fires, send packet to extend idle timeout to keep | |
| // connection alive. | |
| // 2) retransmittable-on-wire. When alarm fires, send packets to detect path | |
| // degrading (used in IP/port migrations). | |
| class QUIC_EXPORT_PRIVATE QuicPingManager { | |
| public: | |
| // Interface that get notified when |alarm_| fires. | |
| class QUIC_EXPORT_PRIVATE Delegate { | |
| public: | |
| virtual ~Delegate() {} | |
| // Called when alarm fires in keep-alive mode. | |
| virtual void OnKeepAliveTimeout() = 0; | |
| // Called when alarm fires in retransmittable-on-wire mode. | |
| virtual void OnRetransmittableOnWireTimeout() = 0; | |
| }; | |
| QuicPingManager(Perspective perspective, Delegate* delegate, | |
| QuicConnectionArena* arena, QuicAlarmFactory* alarm_factory, | |
| QuicConnectionContext* context); | |
| // Called to set |alarm_|. | |
| void SetAlarm(QuicTime now, bool should_keep_alive, | |
| bool has_in_flight_packets); | |
| // Called when |alarm_| fires. | |
| void OnAlarm(); | |
| // Called to stop |alarm_| permanently. | |
| void Stop(); | |
| void set_keep_alive_timeout(QuicTime::Delta keep_alive_timeout) { | |
| QUICHE_DCHECK(!alarm_->IsSet()); | |
| keep_alive_timeout_ = keep_alive_timeout; | |
| } | |
| void set_initial_retransmittable_on_wire_timeout( | |
| QuicTime::Delta retransmittable_on_wire_timeout) { | |
| QUICHE_DCHECK(!alarm_->IsSet()); | |
| initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout; | |
| } | |
| void reset_consecutive_retransmittable_on_wire_count() { | |
| consecutive_retransmittable_on_wire_count_ = 0; | |
| } | |
| private: | |
| friend class test::QuicConnectionPeer; | |
| friend class test::QuicPingManagerPeer; | |
| // Update |retransmittable_on_wire_deadline_| and |keep_alive_deadline_|. | |
| void UpdateDeadlines(QuicTime now, bool should_keep_alive, | |
| bool has_in_flight_packets); | |
| // Get earliest deadline of |retransmittable_on_wire_deadline_| and | |
| // |keep_alive_deadline_|. Returns 0 if both deadlines are not initialized. | |
| QuicTime GetEarliestDeadline() const; | |
| Perspective perspective_; | |
| Delegate* delegate_; // Not owned. | |
| // Initial timeout for how long the wire can have no retransmittable packets. | |
| QuicTime::Delta initial_retransmittable_on_wire_timeout_ = | |
| QuicTime::Delta::Infinite(); | |
| // Indicates how many consecutive retransmittable-on-wire has been armed | |
| // (since last reset). | |
| int consecutive_retransmittable_on_wire_count_ = 0; | |
| // Indicates how many retransmittable-on-wire has been armed in total. | |
| int retransmittable_on_wire_count_ = 0; | |
| QuicTime::Delta keep_alive_timeout_ = | |
| QuicTime::Delta::FromSeconds(kPingTimeoutSecs); | |
| QuicTime retransmittable_on_wire_deadline_ = QuicTime::Zero(); | |
| QuicTime keep_alive_deadline_ = QuicTime::Zero(); | |
| QuicArenaScopedPtr<QuicAlarm> alarm_; | |
| }; | |
| } // namespace quic | |
| #endif // QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ |