blob: 6ca7ea0506a4ceee677c1d94d661de5693357854 [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:
33 explicit QuicControlFrameManager(QuicSession* session);
34 QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
35 QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
36 ~QuicControlFrameManager();
37
38 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
39 // immediately.
40 void WriteOrBufferRstStream(QuicControlFrameId id,
41 QuicRstStreamErrorCode error,
42 QuicStreamOffset bytes_written);
43
44 // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
45 // immediately.
46 void WriteOrBufferGoAway(QuicErrorCode error,
47 QuicStreamId last_good_stream_id,
vasilvvc48c8712019-03-11 13:38:16 -070048 const std::string& reason);
QUICHE teama6ef0a62019-03-07 20:34:33 -050049
50 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
51 // immediately.
52 void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
53
54 // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
55 // immediately.
56 void WriteOrBufferBlocked(QuicStreamId id);
57
fkastenholz3c4eabf2019-04-22 07:49:59 -070058 // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 // sent immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070060 void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050061
fkastenholz3c4eabf2019-04-22 07:49:59 -070062 // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
QUICHE teama6ef0a62019-03-07 20:34:33 -050063 // immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070064 void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050065
66 // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
67 // can not be sent immediately.
68 void WriteOrBufferStopSending(uint16_t code, QuicStreamId stream_id);
69
fayang01062942020-01-22 07:23:23 -080070 // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
71 // be sent immediately.
72 void WriteOrBufferHandshakeDone();
73
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 // Sends a PING_FRAME. Do not send PING if there is buffered frames.
75 void WritePing();
76
77 // Called when |frame| gets acked. Returns true if |frame| gets acked for the
78 // first time, return false otherwise.
79 bool OnControlFrameAcked(const QuicFrame& frame);
80
81 // Called when |frame| is considered as lost.
82 void OnControlFrameLost(const QuicFrame& frame);
83
84 // Called by the session when the connection becomes writable.
85 void OnCanWrite();
86
87 // Retransmit |frame| if it is still outstanding. Returns false if the frame
88 // does not get retransmitted because the connection is blocked. Otherwise,
89 // returns true.
90 bool RetransmitControlFrame(const QuicFrame& frame);
91
92 // Returns true if |frame| is outstanding and waiting to be acked. Returns
93 // false otherwise.
94 bool IsControlFrameOutstanding(const QuicFrame& frame) const;
95
96 // Returns true if there is any lost control frames waiting to be
97 // retransmitted.
98 bool HasPendingRetransmission() const;
99
100 // Returns true if there are any lost or new control frames waiting to be
101 // sent.
102 bool WillingToWrite() const;
103
104 private:
105 friend class test::QuicControlFrameManagerPeer;
106
107 // Tries to write buffered control frames to the peer.
108 void WriteBufferedFrames();
109
110 // Called when |frame| is sent for the first time or gets retransmitted.
111 void OnControlFrameSent(const QuicFrame& frame);
112
113 // Writes pending retransmissions if any.
114 void WritePendingRetransmission();
115
116 // Called when frame with |id| gets acked. Returns true if |id| gets acked for
117 // the first time, return false otherwise.
118 bool OnControlFrameIdAcked(QuicControlFrameId id);
119
120 // Retrieves the next pending retransmission. This must only be called when
121 // there are pending retransmissions.
122 QuicFrame NextPendingRetransmission() const;
123
124 // Returns true if there are buffered frames waiting to be sent for the first
125 // time.
126 bool HasBufferedFrames() const;
127
128 // Writes or buffers a control frame. Frame is buffered if there already
129 // are frames waiting to be sent. If no others waiting, will try to send the
130 // frame.
131 void WriteOrBufferQuicFrame(QuicFrame frame);
132
wuba750aab2020-02-10 06:43:15 -0800133 QuicCircularDeque<QuicFrame> control_frames_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134
135 // Id of latest saved control frame. 0 if no control frame has been saved.
136 QuicControlFrameId last_control_frame_id_;
137
138 // The control frame at the 0th index of control_frames_.
139 QuicControlFrameId least_unacked_;
140
141 // ID of the least unsent control frame.
142 QuicControlFrameId least_unsent_;
143
144 // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
145 // is not used here.
146 // Lost control frames waiting to be retransmitted.
147 QuicLinkedHashMap<QuicControlFrameId, bool> pending_retransmissions_;
148
149 // Pointer to the owning QuicSession object.
150 QuicSession* session_;
151
152 // Last sent window update frame for each stream.
153 QuicSmallMap<QuicStreamId, QuicControlFrameId, 10> window_update_frames_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154};
155
156} // namespace quic
157
158#endif // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_