blob: d79b679c98479c4c87664e5e1232d2f115b04fa9 [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
5#ifndef QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
6#define QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
7
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
9
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
danzhbf4836c2020-02-11 20:29:15 -080011#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080012#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050013
14namespace quic {
15
16class QuicSession;
17
18namespace test {
19class QuicControlFrameManagerPeer;
20} // namespace test
21
22// Control frame manager contains a list of sent control frames with valid
23// control frame IDs. Control frames without valid control frame IDs include:
24// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
25// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
26// APPLICATION_CLOSE frames.
27// New control frames are added to the tail of the list when they are added to
28// the generator. Control frames are removed from the head of the list when they
29// get acked. Control frame manager also keeps track of lost control frames
30// which need to be retransmitted.
31class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
32 public:
renjietang8ccbf792020-07-15 16:28:09 -070033 class QUIC_EXPORT_PRIVATE DelegateInterface {
34 public:
35 virtual ~DelegateInterface() = default;
36
37 // Notifies the delegate of errors.
38 virtual void OnControlFrameManagerError(QuicErrorCode error_code,
39 std::string error_details) = 0;
40
41 virtual bool WriteControlFrame(const QuicFrame& frame,
42 TransmissionType type) = 0;
43 };
44
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 explicit QuicControlFrameManager(QuicSession* session);
46 QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
47 QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
48 ~QuicControlFrameManager();
49
50 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
51 // immediately.
52 void WriteOrBufferRstStream(QuicControlFrameId id,
53 QuicRstStreamErrorCode error,
54 QuicStreamOffset bytes_written);
55
56 // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
57 // immediately.
58 void WriteOrBufferGoAway(QuicErrorCode error,
59 QuicStreamId last_good_stream_id,
vasilvvc48c8712019-03-11 13:38:16 -070060 const std::string& reason);
QUICHE teama6ef0a62019-03-07 20:34:33 -050061
62 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
63 // immediately.
64 void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
65
66 // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
67 // immediately.
68 void WriteOrBufferBlocked(QuicStreamId id);
69
fkastenholz3c4eabf2019-04-22 07:49:59 -070070 // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 // sent immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070072 void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050073
fkastenholz3c4eabf2019-04-22 07:49:59 -070074 // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
QUICHE teama6ef0a62019-03-07 20:34:33 -050075 // immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070076 void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050077
78 // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
79 // can not be sent immediately.
bnc187eea32020-09-02 12:16:15 -070080 void WriteOrBufferStopSending(QuicRstStreamErrorCode code,
81 QuicStreamId stream_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -050082
fayang01062942020-01-22 07:23:23 -080083 // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
84 // be sent immediately.
85 void WriteOrBufferHandshakeDone();
86
haoyuewang5b0f14f2020-09-18 14:31:54 -070087 // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
88 // sent immediately.
89 void WriteOrBufferAckFrequency(uint64_t packet_tolerance,
90 QuicTime::Delta max_ack_delay);
91
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 // Sends a PING_FRAME. Do not send PING if there is buffered frames.
93 void WritePing();
94
95 // Called when |frame| gets acked. Returns true if |frame| gets acked for the
96 // first time, return false otherwise.
97 bool OnControlFrameAcked(const QuicFrame& frame);
98
99 // Called when |frame| is considered as lost.
100 void OnControlFrameLost(const QuicFrame& frame);
101
102 // Called by the session when the connection becomes writable.
103 void OnCanWrite();
104
105 // Retransmit |frame| if it is still outstanding. Returns false if the frame
106 // does not get retransmitted because the connection is blocked. Otherwise,
107 // returns true.
renjietang4d992bf2020-03-03 13:01:55 -0800108 bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109
110 // Returns true if |frame| is outstanding and waiting to be acked. Returns
111 // false otherwise.
112 bool IsControlFrameOutstanding(const QuicFrame& frame) const;
113
114 // Returns true if there is any lost control frames waiting to be
115 // retransmitted.
116 bool HasPendingRetransmission() const;
117
118 // Returns true if there are any lost or new control frames waiting to be
119 // sent.
120 bool WillingToWrite() const;
121
122 private:
123 friend class test::QuicControlFrameManagerPeer;
124
125 // Tries to write buffered control frames to the peer.
126 void WriteBufferedFrames();
127
128 // Called when |frame| is sent for the first time or gets retransmitted.
129 void OnControlFrameSent(const QuicFrame& frame);
130
131 // Writes pending retransmissions if any.
132 void WritePendingRetransmission();
133
134 // Called when frame with |id| gets acked. Returns true if |id| gets acked for
135 // the first time, return false otherwise.
136 bool OnControlFrameIdAcked(QuicControlFrameId id);
137
138 // Retrieves the next pending retransmission. This must only be called when
139 // there are pending retransmissions.
140 QuicFrame NextPendingRetransmission() const;
141
142 // Returns true if there are buffered frames waiting to be sent for the first
143 // time.
144 bool HasBufferedFrames() const;
145
146 // Writes or buffers a control frame. Frame is buffered if there already
147 // are frames waiting to be sent. If no others waiting, will try to send the
148 // frame.
149 void WriteOrBufferQuicFrame(QuicFrame frame);
150
wuba750aab2020-02-10 06:43:15 -0800151 QuicCircularDeque<QuicFrame> control_frames_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152
153 // Id of latest saved control frame. 0 if no control frame has been saved.
154 QuicControlFrameId last_control_frame_id_;
155
156 // The control frame at the 0th index of control_frames_.
157 QuicControlFrameId least_unacked_;
158
159 // ID of the least unsent control frame.
160 QuicControlFrameId least_unsent_;
161
162 // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
163 // is not used here.
164 // Lost control frames waiting to be retransmitted.
165 QuicLinkedHashMap<QuicControlFrameId, bool> pending_retransmissions_;
166
renjietang8ccbf792020-07-15 16:28:09 -0700167 DelegateInterface* delegate_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500168
169 // Last sent window update frame for each stream.
170 QuicSmallMap<QuicStreamId, QuicControlFrameId, 10> window_update_frames_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171};
172
173} // namespace quic
174
175#endif // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_