1 // Copyright (c) 2012 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 // QuicPeerIssuedConnectionIdManager handles the states associated with receving 6 // and retiring peer issued connection Ids. 7 // QuicSelfIssuedConnectionIdManager handles the states associated with 8 // connection Ids issued by the current end point. 9 10 #ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_ 11 #define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_ 12 13 #include <cstddef> 14 #include <memory> 15 16 #include "absl/types/optional.h" 17 #include "quiche/quic/core/connection_id_generator.h" 18 #include "quiche/quic/core/frames/quic_new_connection_id_frame.h" 19 #include "quiche/quic/core/frames/quic_retire_connection_id_frame.h" 20 #include "quiche/quic/core/quic_alarm.h" 21 #include "quiche/quic/core/quic_alarm_factory.h" 22 #include "quiche/quic/core/quic_clock.h" 23 #include "quiche/quic/core/quic_connection_id.h" 24 #include "quiche/quic/core/quic_interval_set.h" 25 #include "quiche/quic/core/quic_types.h" 26 #include "quiche/quic/platform/api/quic_export.h" 27 28 namespace quic { 29 30 namespace test { 31 class QuicConnectionIdManagerPeer; 32 } // namespace test 33 34 struct QUIC_EXPORT_PRIVATE QuicConnectionIdData { 35 QuicConnectionIdData(const QuicConnectionId& connection_id, 36 uint64_t sequence_number, 37 const StatelessResetToken& stateless_reset_token); 38 39 QuicConnectionId connection_id; 40 uint64_t sequence_number; 41 StatelessResetToken stateless_reset_token; 42 }; 43 44 // Used by QuicSelfIssuedConnectionIdManager 45 // and QuicPeerIssuedConnectionIdManager. 46 class QUIC_EXPORT_PRIVATE QuicConnectionIdManagerVisitorInterface { 47 public: 48 virtual ~QuicConnectionIdManagerVisitorInterface() = default; 49 virtual void OnPeerIssuedConnectionIdRetired() = 0; 50 virtual bool SendNewConnectionId(const QuicNewConnectionIdFrame& frame) = 0; 51 virtual bool MaybeReserveConnectionId( 52 const QuicConnectionId& connection_id) = 0; 53 virtual void OnSelfIssuedConnectionIdRetired( 54 const QuicConnectionId& connection_id) = 0; 55 }; 56 57 class QUIC_EXPORT_PRIVATE QuicPeerIssuedConnectionIdManager { 58 public: 59 // QuicPeerIssuedConnectionIdManager should be instantiated only when a peer 60 // issued-non empty connection ID is received. 61 QuicPeerIssuedConnectionIdManager( 62 size_t active_connection_id_limit, 63 const QuicConnectionId& initial_peer_issued_connection_id, 64 const QuicClock* clock, QuicAlarmFactory* alarm_factory, 65 QuicConnectionIdManagerVisitorInterface* visitor, 66 QuicConnectionContext* context); 67 68 ~QuicPeerIssuedConnectionIdManager(); 69 70 QuicErrorCode OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame, 71 std::string* error_detail); 72 HasUnusedConnectionId()73 bool HasUnusedConnectionId() const { 74 return !unused_connection_id_data_.empty(); 75 } 76 77 // Returns the data associated with an unused connection Id. After the call, 78 // the Id is marked as used. Returns nullptr if there is no unused connection 79 // Id. 80 const QuicConnectionIdData* ConsumeOneUnusedConnectionId(); 81 82 // Add each active connection Id that is no longer on path to the pending 83 // retirement connection Id list. 84 void MaybeRetireUnusedConnectionIds( 85 const std::vector<QuicConnectionId>& active_connection_ids_on_path); 86 87 bool IsConnectionIdActive(const QuicConnectionId& cid) const; 88 89 // Get the sequence numbers of all the connection Ids pending retirement when 90 // it is safe to retires these Ids. 91 std::vector<uint64_t> ConsumeToBeRetiredConnectionIdSequenceNumbers(); 92 93 // If old_connection_id is still tracked by QuicPeerIssuedConnectionIdManager, 94 // replace it with new_connection_id. Otherwise, this is a no-op. 95 void ReplaceConnectionId(const QuicConnectionId& old_connection_id, 96 const QuicConnectionId& new_connection_id); 97 98 private: 99 friend class test::QuicConnectionIdManagerPeer; 100 101 // Add the connection Id to the pending retirement connection Id list and 102 // schedule an alarm if needed. 103 void PrepareToRetireActiveConnectionId(const QuicConnectionId& cid); 104 105 bool IsConnectionIdNew(const QuicNewConnectionIdFrame& frame); 106 107 void PrepareToRetireConnectionIdPriorTo( 108 uint64_t retire_prior_to, 109 std::vector<QuicConnectionIdData>* cid_data_vector); 110 111 size_t active_connection_id_limit_; 112 const QuicClock* clock_; 113 std::unique_ptr<QuicAlarm> retire_connection_id_alarm_; 114 std::vector<QuicConnectionIdData> active_connection_id_data_; 115 std::vector<QuicConnectionIdData> unused_connection_id_data_; 116 std::vector<QuicConnectionIdData> to_be_retired_connection_id_data_; 117 // Track sequence numbers of recent NEW_CONNECTION_ID frames received from 118 // the peer. 119 QuicIntervalSet<uint64_t> recent_new_connection_id_sequence_numbers_; 120 uint64_t max_new_connection_id_frame_retire_prior_to_ = 0u; 121 }; 122 123 class QUIC_EXPORT_PRIVATE QuicSelfIssuedConnectionIdManager { 124 public: 125 QuicSelfIssuedConnectionIdManager( 126 size_t active_connection_id_limit, 127 const QuicConnectionId& initial_connection_id, const QuicClock* clock, 128 QuicAlarmFactory* alarm_factory, 129 QuicConnectionIdManagerVisitorInterface* visitor, 130 QuicConnectionContext* context, 131 ConnectionIdGeneratorInterface& generator); 132 133 virtual ~QuicSelfIssuedConnectionIdManager(); 134 135 absl::optional<QuicNewConnectionIdFrame> 136 MaybeIssueNewConnectionIdForPreferredAddress(); 137 138 QuicErrorCode OnRetireConnectionIdFrame( 139 const QuicRetireConnectionIdFrame& frame, QuicTime::Delta pto_delay, 140 std::string* error_detail); 141 142 std::vector<QuicConnectionId> GetUnretiredConnectionIds() const; 143 144 QuicConnectionId GetOneActiveConnectionId() const; 145 146 // Called when the retire_connection_id alarm_ fires. Removes the to be 147 // retired connection ID locally. 148 void RetireConnectionId(); 149 150 // Sends new connection IDs if more can be sent. 151 void MaybeSendNewConnectionIds(); 152 153 // The two functions are called on the client side to associate a client 154 // connection ID with a new probing/migration path when client uses 155 // non-empty connection ID. 156 bool HasConnectionIdToConsume() const; 157 absl::optional<QuicConnectionId> ConsumeOneConnectionId(); 158 159 // Returns true if the given connection ID is issued by the 160 // QuicSelfIssuedConnectionIdManager and not retired locally yet. Called to 161 // tell if a received packet has a valid connection ID. 162 bool IsConnectionIdInUse(const QuicConnectionId& cid) const; 163 164 private: 165 friend class test::QuicConnectionIdManagerPeer; 166 167 // Issue a new connection ID. Can return nullopt. 168 absl::optional<QuicNewConnectionIdFrame> MaybeIssueNewConnectionId(); 169 170 // This should be set to the min of: 171 // (1) # of active connection IDs that peer can maintain. 172 // (2) maximum # of active connection IDs self plans to issue. 173 size_t active_connection_id_limit_; 174 const QuicClock* clock_; 175 QuicConnectionIdManagerVisitorInterface* visitor_; 176 // This tracks connection IDs issued to the peer but not retired by the peer. 177 // Each pair is a connection ID and its sequence number. 178 std::vector<std::pair<QuicConnectionId, uint64_t>> active_connection_ids_; 179 // This tracks connection IDs retired by the peer but has not been retired 180 // locally. Each pair is a connection ID and the time by which it should be 181 // retired. 182 std::vector<std::pair<QuicConnectionId, QuicTime>> 183 to_be_retired_connection_ids_; 184 // An alarm that fires when a connection ID should be retired. 185 std::unique_ptr<QuicAlarm> retire_connection_id_alarm_; 186 // State of the last issued connection Id. 187 QuicConnectionId last_connection_id_; 188 uint64_t next_connection_id_sequence_number_; 189 // The sequence number of last connection ID consumed. 190 uint64_t last_connection_id_consumed_by_self_sequence_number_; 191 192 ConnectionIdGeneratorInterface& connection_id_generator_; 193 }; 194 195 } // namespace quic 196 197 #endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_MANAGER_H_ 198