blob: 39e768c9ed5ab55eec02549110dade6779db0df5 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_control_frame_manager.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
vasilvv872e7a32019-03-12 16:42:44 -07007#include <string>
8
vasilvv9edb31e2020-12-03 19:32:58 -08009#include "absl/strings/str_cat.h"
QUICHE team5be974e2020-12-29 18:35:24 -050010#include "quic/core/frames/quic_ack_frequency_frame.h"
11#include "quic/core/frames/quic_frame.h"
haoyuewange1c03212021-01-07 09:15:08 -080012#include "quic/core/frames/quic_new_connection_id_frame.h"
13#include "quic/core/frames/quic_retire_connection_id_frame.h"
QUICHE team5be974e2020-12-29 18:35:24 -050014#include "quic/core/quic_constants.h"
15#include "quic/core/quic_session.h"
16#include "quic/core/quic_types.h"
haoyuewange1c03212021-01-07 09:15:08 -080017#include "quic/core/quic_utils.h"
QUICHE team5be974e2020-12-29 18:35:24 -050018#include "quic/platform/api/quic_bug_tracker.h"
19#include "quic/platform/api/quic_flag_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020
21namespace quic {
22
fayang83d7e3e2019-07-31 14:45:19 -070023namespace {
24
25// The maximum number of buffered control frames which are waiting to be ACKed
26// or sent for the first time.
27const size_t kMaxNumControlFrames = 1000;
28
29} // namespace
30
QUICHE teama6ef0a62019-03-07 20:34:33 -050031QuicControlFrameManager::QuicControlFrameManager(QuicSession* session)
32 : last_control_frame_id_(kInvalidControlFrameId),
33 least_unacked_(1),
34 least_unsent_(1),
renjietang8ccbf792020-07-15 16:28:09 -070035 delegate_(session) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050036
37QuicControlFrameManager::~QuicControlFrameManager() {
38 while (!control_frames_.empty()) {
39 DeleteFrame(&control_frames_.front());
40 control_frames_.pop_front();
41 }
42}
43
44void QuicControlFrameManager::WriteOrBufferQuicFrame(QuicFrame frame) {
45 const bool had_buffered_frames = HasBufferedFrames();
46 control_frames_.emplace_back(frame);
fayangb4f3bc02019-11-04 09:20:12 -080047 if (control_frames_.size() > kMaxNumControlFrames) {
renjietang8ccbf792020-07-15 16:28:09 -070048 delegate_->OnControlFrameManagerError(
fayang83d7e3e2019-07-31 14:45:19 -070049 QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES,
vasilvv9edb31e2020-12-03 19:32:58 -080050 absl::StrCat("More than ", kMaxNumControlFrames,
51 "buffered control frames, least_unacked: ", least_unacked_,
52 ", least_unsent_: ", least_unsent_));
fayang83d7e3e2019-07-31 14:45:19 -070053 return;
54 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050055 if (had_buffered_frames) {
56 return;
57 }
58 WriteBufferedFrames();
59}
60
61void QuicControlFrameManager::WriteOrBufferRstStream(
vasilvv9d05f4a2021-09-21 18:19:03 -070062 QuicStreamId id, QuicResetStreamError error,
QUICHE teama6ef0a62019-03-07 20:34:33 -050063 QuicStreamOffset bytes_written) {
64 QUIC_DVLOG(1) << "Writing RST_STREAM_FRAME";
65 WriteOrBufferQuicFrame((QuicFrame(new QuicRstStreamFrame(
66 ++last_control_frame_id_, id, error, bytes_written))));
67}
68
69void QuicControlFrameManager::WriteOrBufferGoAway(
vasilvvfef8b492021-09-14 06:08:53 -070070 QuicErrorCode error, QuicStreamId last_good_stream_id,
vasilvvc48c8712019-03-11 13:38:16 -070071 const std::string& reason) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 QUIC_DVLOG(1) << "Writing GOAWAY_FRAME";
73 WriteOrBufferQuicFrame(QuicFrame(new QuicGoAwayFrame(
74 ++last_control_frame_id_, error, last_good_stream_id, reason)));
75}
76
77void QuicControlFrameManager::WriteOrBufferWindowUpdate(
vasilvvfef8b492021-09-14 06:08:53 -070078 QuicStreamId id, QuicStreamOffset byte_offset) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 QUIC_DVLOG(1) << "Writing WINDOW_UPDATE_FRAME";
80 WriteOrBufferQuicFrame(QuicFrame(
81 new QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
82}
83
84void QuicControlFrameManager::WriteOrBufferBlocked(QuicStreamId id) {
85 QUIC_DVLOG(1) << "Writing BLOCKED_FRAME";
86 WriteOrBufferQuicFrame(
87 QuicFrame(new QuicBlockedFrame(++last_control_frame_id_, id)));
88}
89
fkastenholz3c4eabf2019-04-22 07:49:59 -070090void QuicControlFrameManager::WriteOrBufferStreamsBlocked(QuicStreamCount count,
91 bool unidirectional) {
92 QUIC_DVLOG(1) << "Writing STREAMS_BLOCKED Frame";
93 QUIC_CODE_COUNT(quic_streams_blocked_transmits);
94 WriteOrBufferQuicFrame(QuicFrame(QuicStreamsBlockedFrame(
95 ++last_control_frame_id_, count, unidirectional)));
QUICHE teama6ef0a62019-03-07 20:34:33 -050096}
97
fkastenholz3c4eabf2019-04-22 07:49:59 -070098void QuicControlFrameManager::WriteOrBufferMaxStreams(QuicStreamCount count,
99 bool unidirectional) {
100 QUIC_DVLOG(1) << "Writing MAX_STREAMS Frame";
101 QUIC_CODE_COUNT(quic_max_streams_transmits);
102 WriteOrBufferQuicFrame(QuicFrame(
103 QuicMaxStreamsFrame(++last_control_frame_id_, count, unidirectional)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104}
105
bnc187eea32020-09-02 12:16:15 -0700106void QuicControlFrameManager::WriteOrBufferStopSending(
vasilvv9d05f4a2021-09-21 18:19:03 -0700107 QuicResetStreamError error, QuicStreamId stream_id) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
109 WriteOrBufferQuicFrame(QuicFrame(
vasilvv9d05f4a2021-09-21 18:19:03 -0700110 new QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500111}
112
fayang01062942020-01-22 07:23:23 -0800113void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
114 QUIC_DVLOG(1) << "Writing HANDSHAKE_DONE";
115 WriteOrBufferQuicFrame(
116 QuicFrame(QuicHandshakeDoneFrame(++last_control_frame_id_)));
117}
118
haoyuewang5b0f14f2020-09-18 14:31:54 -0700119void QuicControlFrameManager::WriteOrBufferAckFrequency(
haoyuewangc921f8d2020-10-14 18:06:52 -0700120 const QuicAckFrequencyFrame& ack_frequency_frame) {
haoyuewang5b0f14f2020-09-18 14:31:54 -0700121 QUIC_DVLOG(1) << "Writing ACK_FREQUENCY frame";
122 QuicControlFrameId control_frame_id = ++last_control_frame_id_;
haoyuewangc921f8d2020-10-14 18:06:52 -0700123 // Using the control_frame_id for sequence_number here leaves gaps in
124 // sequence_number.
125 WriteOrBufferQuicFrame(
126 QuicFrame(new QuicAckFrequencyFrame(control_frame_id,
127 /*sequence_number=*/control_frame_id,
128 ack_frequency_frame.packet_tolerance,
129 ack_frequency_frame.max_ack_delay)));
haoyuewang5b0f14f2020-09-18 14:31:54 -0700130}
131
haoyuewange1c03212021-01-07 09:15:08 -0800132void QuicControlFrameManager::WriteOrBufferNewConnectionId(
vasilvvfef8b492021-09-14 06:08:53 -0700133 const QuicConnectionId& connection_id, uint64_t sequence_number,
haoyuewange1c03212021-01-07 09:15:08 -0800134 uint64_t retire_prior_to,
bnc1ccd0bc2021-04-07 10:20:17 -0700135 const StatelessResetToken& stateless_reset_token) {
haoyuewange1c03212021-01-07 09:15:08 -0800136 QUIC_DVLOG(1) << "Writing NEW_CONNECTION_ID frame";
137 WriteOrBufferQuicFrame(QuicFrame(new QuicNewConnectionIdFrame(
138 ++last_control_frame_id_, connection_id, sequence_number,
139 stateless_reset_token, retire_prior_to)));
140}
141
142void QuicControlFrameManager::WriteOrBufferRetireConnectionId(
143 uint64_t sequence_number) {
144 QUIC_DVLOG(1) << "Writing RETIRE_CONNECTION_ID frame";
145 WriteOrBufferQuicFrame(QuicFrame(new QuicRetireConnectionIdFrame(
146 ++last_control_frame_id_, sequence_number)));
147}
148
fayang133b8682020-12-08 05:50:33 -0800149void QuicControlFrameManager::WriteOrBufferNewToken(absl::string_view token) {
150 QUIC_DVLOG(1) << "Writing NEW_TOKEN frame";
151 WriteOrBufferQuicFrame(
152 QuicFrame(new QuicNewTokenFrame(++last_control_frame_id_, token)));
153}
154
QUICHE teama6ef0a62019-03-07 20:34:33 -0500155void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
156 QuicControlFrameId id = GetControlFrameId(frame);
157 if (id == kInvalidControlFrameId) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700158 QUIC_BUG(quic_bug_12727_1)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 << "Send or retransmit a control frame with invalid control frame id";
160 return;
161 }
162 if (frame.type == WINDOW_UPDATE_FRAME) {
163 QuicStreamId stream_id = frame.window_update_frame->stream_id;
bnc20dcfc82021-06-10 07:13:46 -0700164 if (window_update_frames_.contains(stream_id) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165 id > window_update_frames_[stream_id]) {
166 // Consider the older window update of the same stream as acked.
167 OnControlFrameIdAcked(window_update_frames_[stream_id]);
168 }
169 window_update_frames_[stream_id] = id;
170 }
bnc20dcfc82021-06-10 07:13:46 -0700171 if (pending_retransmissions_.contains(id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500172 // This is retransmitted control frame.
173 pending_retransmissions_.erase(id);
174 return;
175 }
176 if (id > least_unsent_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700177 QUIC_BUG(quic_bug_10517_1)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800178 << "Try to send control frames out of order, id: " << id
179 << " least_unsent: " << least_unsent_;
renjietang8ccbf792020-07-15 16:28:09 -0700180 delegate_->OnControlFrameManagerError(
181 QUIC_INTERNAL_ERROR, "Try to send control frames out of order");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 return;
183 }
184 ++least_unsent_;
185}
186
187bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
188 QuicControlFrameId id = GetControlFrameId(frame);
189 if (!OnControlFrameIdAcked(id)) {
190 return false;
191 }
192 if (frame.type == WINDOW_UPDATE_FRAME) {
193 QuicStreamId stream_id = frame.window_update_frame->stream_id;
bnc20dcfc82021-06-10 07:13:46 -0700194 if (window_update_frames_.contains(stream_id) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195 window_update_frames_[stream_id] == id) {
196 window_update_frames_.erase(stream_id);
197 }
198 }
199 return true;
200}
201
202void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
203 QuicControlFrameId id = GetControlFrameId(frame);
204 if (id == kInvalidControlFrameId) {
205 // Frame does not have a valid control frame ID, ignore it.
206 return;
207 }
208 if (id >= least_unsent_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700209 QUIC_BUG(quic_bug_10517_2) << "Try to mark unsent control frame as lost";
renjietang8ccbf792020-07-15 16:28:09 -0700210 delegate_->OnControlFrameManagerError(
211 QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212 return;
213 }
214 if (id < least_unacked_ ||
215 GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
216 kInvalidControlFrameId) {
217 // This frame has already been acked.
218 return;
219 }
bnc20dcfc82021-06-10 07:13:46 -0700220 if (!pending_retransmissions_.contains(id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500221 pending_retransmissions_[id] = true;
QUICHE teamd6d05e52021-03-16 14:22:01 -0700222 QUIC_BUG_IF(quic_bug_12727_2,
223 pending_retransmissions_.size() > control_frames_.size())
fayang83d7e3e2019-07-31 14:45:19 -0700224 << "least_unacked_: " << least_unacked_
225 << ", least_unsent_: " << least_unsent_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226 }
227}
228
229bool QuicControlFrameManager::IsControlFrameOutstanding(
230 const QuicFrame& frame) const {
231 QuicControlFrameId id = GetControlFrameId(frame);
232 if (id == kInvalidControlFrameId) {
233 // Frame without a control frame ID should not be retransmitted.
234 return false;
235 }
236 // Consider this frame is outstanding if it does not get acked.
237 return id < least_unacked_ + control_frames_.size() && id >= least_unacked_ &&
238 GetControlFrameId(control_frames_.at(id - least_unacked_)) !=
239 kInvalidControlFrameId;
240}
241
242bool QuicControlFrameManager::HasPendingRetransmission() const {
243 return !pending_retransmissions_.empty();
244}
245
246bool QuicControlFrameManager::WillingToWrite() const {
247 return HasPendingRetransmission() || HasBufferedFrames();
248}
249
250QuicFrame QuicControlFrameManager::NextPendingRetransmission() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700251 QUIC_BUG_IF(quic_bug_12727_3, pending_retransmissions_.empty())
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 << "Unexpected call to NextPendingRetransmission() with empty pending "
253 << "retransmission list.";
254 QuicControlFrameId id = pending_retransmissions_.begin()->first;
255 return control_frames_.at(id - least_unacked_);
256}
257
258void QuicControlFrameManager::OnCanWrite() {
259 if (HasPendingRetransmission()) {
260 // Exit early to allow streams to write pending retransmissions if any.
261 WritePendingRetransmission();
262 return;
263 }
264 WriteBufferedFrames();
265}
266
renjietang4d992bf2020-03-03 13:01:55 -0800267bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame,
268 TransmissionType type) {
vasilvvf8035162021-02-01 14:49:14 -0800269 QUICHE_DCHECK(type == PTO_RETRANSMISSION || type == RTO_RETRANSMISSION ||
270 type == TLP_RETRANSMISSION || type == PROBING_RETRANSMISSION);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271 QuicControlFrameId id = GetControlFrameId(frame);
272 if (id == kInvalidControlFrameId) {
273 // Frame does not have a valid control frame ID, ignore it. Returns true
274 // to allow writing following frames.
275 return true;
276 }
277 if (id >= least_unsent_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700278 QUIC_BUG(quic_bug_10517_3) << "Try to retransmit unsent control frame";
renjietang8ccbf792020-07-15 16:28:09 -0700279 delegate_->OnControlFrameManagerError(
280 QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 return false;
282 }
283 if (id < least_unacked_ ||
284 GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
285 kInvalidControlFrameId) {
286 // This frame has already been acked.
287 return true;
288 }
289 QuicFrame copy = CopyRetransmittableControlFrame(frame);
290 QUIC_DVLOG(1) << "control frame manager is forced to retransmit frame: "
291 << frame;
renjietang8ccbf792020-07-15 16:28:09 -0700292 if (delegate_->WriteControlFrame(copy, type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293 return true;
294 }
295 DeleteFrame(&copy);
296 return false;
297}
298
299void QuicControlFrameManager::WriteBufferedFrames() {
300 while (HasBufferedFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 QuicFrame frame_to_send =
302 control_frames_.at(least_unsent_ - least_unacked_);
303 QuicFrame copy = CopyRetransmittableControlFrame(frame_to_send);
renjietang8ccbf792020-07-15 16:28:09 -0700304 if (!delegate_->WriteControlFrame(copy, NOT_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500305 // Connection is write blocked.
306 DeleteFrame(&copy);
307 break;
308 }
309 OnControlFrameSent(frame_to_send);
310 }
311}
312
313void QuicControlFrameManager::WritePendingRetransmission() {
314 while (HasPendingRetransmission()) {
315 QuicFrame pending = NextPendingRetransmission();
316 QuicFrame copy = CopyRetransmittableControlFrame(pending);
renjietang8ccbf792020-07-15 16:28:09 -0700317 if (!delegate_->WriteControlFrame(copy, LOSS_RETRANSMISSION)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500318 // Connection is write blocked.
319 DeleteFrame(&copy);
320 break;
321 }
322 OnControlFrameSent(pending);
323 }
324}
325
326bool QuicControlFrameManager::OnControlFrameIdAcked(QuicControlFrameId id) {
327 if (id == kInvalidControlFrameId) {
328 // Frame does not have a valid control frame ID, ignore it.
329 return false;
330 }
331 if (id >= least_unsent_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700332 QUIC_BUG(quic_bug_10517_4) << "Try to ack unsent control frame";
renjietang8ccbf792020-07-15 16:28:09 -0700333 delegate_->OnControlFrameManagerError(QUIC_INTERNAL_ERROR,
334 "Try to ack unsent control frame");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500335 return false;
336 }
337 if (id < least_unacked_ ||
338 GetControlFrameId(control_frames_.at(id - least_unacked_)) ==
339 kInvalidControlFrameId) {
340 // This frame has already been acked.
341 return false;
342 }
343
344 // Set control frame ID of acked frames to 0.
345 SetControlFrameId(kInvalidControlFrameId,
346 &control_frames_.at(id - least_unacked_));
347 // Remove acked control frames from pending retransmissions.
348 pending_retransmissions_.erase(id);
349 // Clean up control frames queue and increment least_unacked_.
350 while (!control_frames_.empty() &&
351 GetControlFrameId(control_frames_.front()) == kInvalidControlFrameId) {
352 DeleteFrame(&control_frames_.front());
353 control_frames_.pop_front();
354 ++least_unacked_;
355 }
356 return true;
357}
358
359bool QuicControlFrameManager::HasBufferedFrames() const {
360 return least_unsent_ < least_unacked_ + control_frames_.size();
361}
362
363} // namespace quic