blob: a4c26780d40396e66979cab70aa8c36ca9e25071 [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"
11#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012
13namespace quic {
14
15class QuicSession;
16
17namespace test {
18class QuicControlFrameManagerPeer;
19} // namespace test
20
21// Control frame manager contains a list of sent control frames with valid
22// control frame IDs. Control frames without valid control frame IDs include:
23// (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
24// STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
25// APPLICATION_CLOSE frames.
26// New control frames are added to the tail of the list when they are added to
27// the generator. Control frames are removed from the head of the list when they
28// get acked. Control frame manager also keeps track of lost control frames
29// which need to be retransmitted.
30class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
31 public:
32 explicit QuicControlFrameManager(QuicSession* session);
33 QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
34 QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
35 ~QuicControlFrameManager();
36
37 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
38 // immediately.
39 void WriteOrBufferRstStream(QuicControlFrameId id,
40 QuicRstStreamErrorCode error,
41 QuicStreamOffset bytes_written);
42
43 // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
44 // immediately.
45 void WriteOrBufferGoAway(QuicErrorCode error,
46 QuicStreamId last_good_stream_id,
vasilvvc48c8712019-03-11 13:38:16 -070047 const std::string& reason);
QUICHE teama6ef0a62019-03-07 20:34:33 -050048
49 // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
50 // immediately.
51 void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
52
53 // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
54 // immediately.
55 void WriteOrBufferBlocked(QuicStreamId id);
56
fkastenholz3c4eabf2019-04-22 07:49:59 -070057 // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 // sent immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070059 void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050060
fkastenholz3c4eabf2019-04-22 07:49:59 -070061 // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 // immediately.
fkastenholz3c4eabf2019-04-22 07:49:59 -070063 void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
QUICHE teama6ef0a62019-03-07 20:34:33 -050064
65 // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
66 // can not be sent immediately.
67 void WriteOrBufferStopSending(uint16_t code, QuicStreamId stream_id);
68
69 // Sends a PING_FRAME. Do not send PING if there is buffered frames.
70 void WritePing();
71
72 // Called when |frame| gets acked. Returns true if |frame| gets acked for the
73 // first time, return false otherwise.
74 bool OnControlFrameAcked(const QuicFrame& frame);
75
76 // Called when |frame| is considered as lost.
77 void OnControlFrameLost(const QuicFrame& frame);
78
79 // Called by the session when the connection becomes writable.
80 void OnCanWrite();
81
82 // Retransmit |frame| if it is still outstanding. Returns false if the frame
83 // does not get retransmitted because the connection is blocked. Otherwise,
84 // returns true.
85 bool RetransmitControlFrame(const QuicFrame& frame);
86
87 // Returns true if |frame| is outstanding and waiting to be acked. Returns
88 // false otherwise.
89 bool IsControlFrameOutstanding(const QuicFrame& frame) const;
90
91 // Returns true if there is any lost control frames waiting to be
92 // retransmitted.
93 bool HasPendingRetransmission() const;
94
95 // Returns true if there are any lost or new control frames waiting to be
96 // sent.
97 bool WillingToWrite() const;
98
99 private:
100 friend class test::QuicControlFrameManagerPeer;
101
102 // Tries to write buffered control frames to the peer.
103 void WriteBufferedFrames();
104
105 // Called when |frame| is sent for the first time or gets retransmitted.
106 void OnControlFrameSent(const QuicFrame& frame);
107
108 // Writes pending retransmissions if any.
109 void WritePendingRetransmission();
110
111 // Called when frame with |id| gets acked. Returns true if |id| gets acked for
112 // the first time, return false otherwise.
113 bool OnControlFrameIdAcked(QuicControlFrameId id);
114
115 // Retrieves the next pending retransmission. This must only be called when
116 // there are pending retransmissions.
117 QuicFrame NextPendingRetransmission() const;
118
119 // Returns true if there are buffered frames waiting to be sent for the first
120 // time.
121 bool HasBufferedFrames() const;
122
123 // Writes or buffers a control frame. Frame is buffered if there already
124 // are frames waiting to be sent. If no others waiting, will try to send the
125 // frame.
126 void WriteOrBufferQuicFrame(QuicFrame frame);
127
128 QuicDeque<QuicFrame> control_frames_;
129
130 // Id of latest saved control frame. 0 if no control frame has been saved.
131 QuicControlFrameId last_control_frame_id_;
132
133 // The control frame at the 0th index of control_frames_.
134 QuicControlFrameId least_unacked_;
135
136 // ID of the least unsent control frame.
137 QuicControlFrameId least_unsent_;
138
139 // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
140 // is not used here.
141 // Lost control frames waiting to be retransmitted.
142 QuicLinkedHashMap<QuicControlFrameId, bool> pending_retransmissions_;
143
144 // Pointer to the owning QuicSession object.
145 QuicSession* session_;
146
147 // Last sent window update frame for each stream.
148 QuicSmallMap<QuicStreamId, QuicControlFrameId, 10> window_update_frames_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149};
150
151} // namespace quic
152
153#endif // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_