1 // 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 
8 #include <string>
9 
10 #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
11 #include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
12 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
13 
14 namespace quic {
15 
16 class QuicSession;
17 
18 namespace test {
19 class 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.
31 class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
32  public:
33   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 
45   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,
60                            const std::string& reason);
61 
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 
70   // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
71   // sent immediately.
72   void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
73 
74   // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
75   // immediately.
76   void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
77 
78   // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
79   // can not be sent immediately.
80   void WriteOrBufferStopSending(QuicRstStreamErrorCode code,
81                                 QuicStreamId stream_id);
82 
83   // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
84   // be sent immediately.
85   void WriteOrBufferHandshakeDone();
86 
87   // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
88   // sent immediately.
89   void WriteOrBufferAckFrequency(
90       const QuicAckFrequencyFrame& ack_frequency_frame);
91 
92   // 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.
108   bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
109 
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 
151   QuicCircularDeque<QuicFrame> control_frames_;
152 
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 
167   DelegateInterface* delegate_;
168 
169   // Last sent window update frame for each stream.
170   QuicSmallMap<QuicStreamId, QuicControlFrameId, 10> window_update_frames_;
171 };
172 
173 }  // namespace quic
174 
175 #endif  // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
176