1 // Copyright (c) 2022 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ 6 #define QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ 7 8 #include "quiche/quic/core/quic_alarm.h" 9 #include "quiche/quic/core/quic_alarm_factory.h" 10 #include "quiche/quic/core/quic_constants.h" 11 #include "quiche/quic/core/quic_one_block_arena.h" 12 #include "quiche/quic/core/quic_time.h" 13 #include "quiche/quic/platform/api/quic_export.h" 14 15 namespace quic { 16 17 namespace test { 18 class QuicConnectionPeer; 19 class QuicPingManagerPeer; 20 } // namespace test 21 22 // QuicPingManager manages an alarm that has two modes: 23 // 1) keep-alive. When alarm fires, send packet to extend idle timeout to keep 24 // connection alive. 25 // 2) retransmittable-on-wire. When alarm fires, send packets to detect path 26 // degrading (used in IP/port migrations). 27 class QUICHE_EXPORT QuicPingManager { 28 public: 29 // Interface that get notified when |alarm_| fires. 30 class QUICHE_EXPORT Delegate { 31 public: ~Delegate()32 virtual ~Delegate() {} 33 34 // Called when alarm fires in keep-alive mode. 35 virtual void OnKeepAliveTimeout() = 0; 36 // Called when alarm fires in retransmittable-on-wire mode. 37 virtual void OnRetransmittableOnWireTimeout() = 0; 38 }; 39 40 QuicPingManager(Perspective perspective, Delegate* delegate, 41 QuicConnectionArena* arena, QuicAlarmFactory* alarm_factory, 42 QuicConnectionContext* context); 43 44 // Called to set |alarm_|. 45 void SetAlarm(QuicTime now, bool should_keep_alive, 46 bool has_in_flight_packets); 47 48 // Called when |alarm_| fires. 49 void OnAlarm(); 50 51 // Called to stop |alarm_| permanently. 52 void Stop(); 53 set_keep_alive_timeout(QuicTime::Delta keep_alive_timeout)54 void set_keep_alive_timeout(QuicTime::Delta keep_alive_timeout) { 55 QUICHE_DCHECK(!alarm_->IsSet()); 56 keep_alive_timeout_ = keep_alive_timeout; 57 } 58 set_initial_retransmittable_on_wire_timeout(QuicTime::Delta retransmittable_on_wire_timeout)59 void set_initial_retransmittable_on_wire_timeout( 60 QuicTime::Delta retransmittable_on_wire_timeout) { 61 QUICHE_DCHECK(!alarm_->IsSet()); 62 initial_retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout; 63 } 64 reset_consecutive_retransmittable_on_wire_count()65 void reset_consecutive_retransmittable_on_wire_count() { 66 consecutive_retransmittable_on_wire_count_ = 0; 67 } 68 69 private: 70 friend class test::QuicConnectionPeer; 71 friend class test::QuicPingManagerPeer; 72 73 // Update |retransmittable_on_wire_deadline_| and |keep_alive_deadline_|. 74 void UpdateDeadlines(QuicTime now, bool should_keep_alive, 75 bool has_in_flight_packets); 76 77 // Get earliest deadline of |retransmittable_on_wire_deadline_| and 78 // |keep_alive_deadline_|. Returns 0 if both deadlines are not initialized. 79 QuicTime GetEarliestDeadline() const; 80 81 Perspective perspective_; 82 83 Delegate* delegate_; // Not owned. 84 85 // Initial timeout for how long the wire can have no retransmittable packets. 86 QuicTime::Delta initial_retransmittable_on_wire_timeout_ = 87 QuicTime::Delta::Infinite(); 88 89 // Indicates how many consecutive retransmittable-on-wire has been armed 90 // (since last reset). 91 int consecutive_retransmittable_on_wire_count_ = 0; 92 93 // Indicates how many retransmittable-on-wire has been armed in total. 94 int retransmittable_on_wire_count_ = 0; 95 96 QuicTime::Delta keep_alive_timeout_ = 97 QuicTime::Delta::FromSeconds(kPingTimeoutSecs); 98 99 QuicTime retransmittable_on_wire_deadline_ = QuicTime::Zero(); 100 101 QuicTime keep_alive_deadline_ = QuicTime::Zero(); 102 103 QuicArenaScopedPtr<QuicAlarm> alarm_; 104 }; 105 106 } // namespace quic 107 108 #endif // QUICHE_QUIC_CORE_QUIC_PING_MANAGER_H_ 109