20 : active_cid_limit_(active_cid_limit)
44 uint64_t retire_prior_to,
45 const std::array<uint8_t, 16>& reset_token)
49 if (retire_prior_to > sequence)
52 "retire_prior_to exceeds sequence number",
53 "connection_id_manager");
57 auto it = find_by_sequence(sequence);
58 if (it != peer_cids_.end())
63 if (it->cid == cid && it->stateless_reset_token == reset_token)
69 "Duplicate sequence number with different CID",
70 "connection_id_manager");
74 auto active_count = count_active_cids();
75 if (active_count >= active_cid_limit_)
78 "Active connection ID limit exceeded",
79 "connection_id_manager");
89 peer_cids_.push_back(entry);
92 if (retire_prior_to > largest_retire_prior_to_)
94 retire_cids_prior_to(retire_prior_to);
95 largest_retire_prior_to_ = retire_prior_to;
114 for (
size_t i = 0; i < peer_cids_.size(); ++i)
116 if (i != active_index_ && !peer_cids_[i].retired)
119 if (active_index_ < peer_cids_.size())
121 auto old_seq = peer_cids_[active_index_].sequence_number;
122 (void)retire_peer_cid(old_seq);
131 "No available connection ID for rotation",
132 "connection_id_manager");
138 for (
size_t i = 0; i <
peer_cids_.size(); ++i)
149 const std::array<uint8_t, 16>& token)
const ->
bool
151 for (
const auto& entry : peer_cids_)
153 if (entry.stateless_reset_token == token)
169 if (!entry.retired && entry.sequence_number < prior_to)
171 entry.retired =
true;
182 for (
size_t i = 0; i <
peer_cids_.size(); ++i)
196 -> std::vector<retire_connection_id_frame>
198 return pending_retire_frames_;
208 auto it = find_by_sequence(sequence);
209 if (it == peer_cids_.end())
212 "Connection ID sequence not found",
213 "connection_id_manager");
223 pending_retire_frames_.push_back(
frame);
235 return std::any_of(peer_cids_.begin(), peer_cids_.end(),
237 { return entry.cid == cid && !entry.retired; });
245 -> std::vector<connection_id_entry>::iterator
247 return std::find_if(peer_cids_.begin(), peer_cids_.end(),
249 { return entry.sequence_number == sequence; });
254 return static_cast<size_t>(std::count_if(
auto get_pending_retire_frames() -> std::vector< retire_connection_id_frame >
Get pending RETIRE_CONNECTION_ID frames to send.
auto add_peer_cid(const connection_id &cid, uint64_t sequence, uint64_t retire_prior_to, const std::array< uint8_t, 16 > &reset_token) -> VoidResult
Add a new peer connection ID from NEW_CONNECTION_ID frame.
auto retire_peer_cid(uint64_t sequence) -> VoidResult
Mark a specific CID sequence as retired.
auto has_peer_cid(const connection_id &cid) const -> bool
Check if a given CID matches any stored peer CID.
auto rotate_peer_cid() -> VoidResult
Rotate to a new peer connection ID.
auto count_active_cids() const -> size_t
Count non-retired CIDs.
std::vector< connection_id_entry > peer_cids_
Peer connection IDs.
auto is_stateless_reset_token(const std::array< uint8_t, 16 > &token) const -> bool
Check if a stateless reset token matches any stored CID.
auto get_active_peer_cid() const -> const connection_id &
Get the currently active peer connection ID.
std::vector< retire_connection_id_frame > pending_retire_frames_
Pending RETIRE_CONNECTION_ID frames to send.
static const connection_id empty_cid_
Empty CID for error cases.
void set_initial_peer_cid(const connection_id &cid)
Set the initial peer connection ID (from Initial packet)
auto find_by_sequence(uint64_t sequence) -> std::vector< connection_id_entry >::iterator
Find an entry by sequence number.
auto available_peer_cids() const -> size_t
Get the number of available (non-retired, non-active) peer CIDs.
connection_id_manager(uint64_t active_cid_limit=8)
Construct a connection ID manager.
void retire_cids_prior_to(uint64_t prior_to)
Retire CIDs with sequence numbers less than the given value.
void clear_pending_retire_frames()
Clear the pending retire frames queue.
size_t active_index_
Index of the currently active peer CID.
QUIC Connection ID (RFC 9000 Section 5.1)
constexpr int no_available_cid
constexpr int invalid_retire_prior_to
constexpr int duplicate_sequence
constexpr int cid_not_found
constexpr int active_cid_limit_exceeded
std::variant< padding_frame, ping_frame, ack_frame, reset_stream_frame, stop_sending_frame, crypto_frame, new_token_frame, stream_frame, max_data_frame, max_stream_data_frame, max_streams_frame, data_blocked_frame, stream_data_blocked_frame, streams_blocked_frame, new_connection_id_frame, retire_connection_id_frame, path_challenge_frame, path_response_frame, connection_close_frame, handshake_done_frame > frame
Variant type holding any QUIC frame.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
Entry for storing a peer's connection ID with metadata.
std::array< uint8_t, 16 > stateless_reset_token
RETIRE_CONNECTION_ID frame (RFC 9000 Section 19.16)
uint64_t sequence_number
Sequence number of CID to retire.