• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
9 #include <string>
10 
11 #include "absl/container/flat_hash_map.h"
12 #include "quiche/quic/core/frames/quic_frame.h"
13 #include "quiche/quic/core/quic_connection_id.h"
14 #include "quiche/quic/core/quic_error_codes.h"
15 #include "quiche/quic/core/quic_types.h"
16 #include "quiche/common/quiche_circular_deque.h"
17 #include "quiche/common/quiche_linked_hash_map.h"
18 
19 namespace quic {
20 
21 class QuicSession;
22 
23 namespace test {
24 class QuicControlFrameManagerPeer;
25 }  // namespace test
26 
27 // Control frame manager contains a list of sent control frames with valid
28 // control frame IDs. Control frames without valid control frame IDs include:
29 // (1) non-retransmittable frames (e.g., ACK_FRAME, PADDING_FRAME,
30 // STOP_WAITING_FRAME, etc.), (2) CONNECTION_CLOSE and IETF Quic
31 // APPLICATION_CLOSE frames.
32 // New control frames are added to the tail of the list when they are added to
33 // the generator. Control frames are removed from the head of the list when they
34 // get acked. Control frame manager also keeps track of lost control frames
35 // which need to be retransmitted.
36 class QUIC_EXPORT_PRIVATE QuicControlFrameManager {
37  public:
38   class QUIC_EXPORT_PRIVATE DelegateInterface {
39    public:
40     virtual ~DelegateInterface() = default;
41 
42     // Notifies the delegate of errors.
43     virtual void OnControlFrameManagerError(QuicErrorCode error_code,
44                                             std::string error_details) = 0;
45 
46     virtual bool WriteControlFrame(const QuicFrame& frame,
47                                    TransmissionType type) = 0;
48   };
49 
50   explicit QuicControlFrameManager(QuicSession* session);
51   QuicControlFrameManager(const QuicControlFrameManager& other) = delete;
52   QuicControlFrameManager(QuicControlFrameManager&& other) = delete;
53   ~QuicControlFrameManager();
54 
55   // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
56   // immediately.
57   void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error,
58                               QuicStreamOffset bytes_written);
59 
60   // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent
61   // immediately.
62   void WriteOrBufferGoAway(QuicErrorCode error,
63                            QuicStreamId last_good_stream_id,
64                            const std::string& reason);
65 
66   // Tries to send a WINDOW_UPDATE_FRAME. Buffers the frame if it cannot be sent
67   // immediately.
68   void WriteOrBufferWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
69 
70   // Tries to send a BLOCKED_FRAME. Buffers the frame if it cannot be sent
71   // immediately.
72   void WriteOrBufferBlocked(QuicStreamId id, QuicStreamOffset byte_offset);
73 
74   // Tries to send a STREAMS_BLOCKED Frame. Buffers the frame if it cannot be
75   // sent immediately.
76   void WriteOrBufferStreamsBlocked(QuicStreamCount count, bool unidirectional);
77 
78   // Tries to send a MAX_STREAMS Frame. Buffers the frame if it cannot be sent
79   // immediately.
80   void WriteOrBufferMaxStreams(QuicStreamCount count, bool unidirectional);
81 
82   // Tries to send an IETF-QUIC STOP_SENDING frame. The frame is buffered if it
83   // can not be sent immediately.
84   void WriteOrBufferStopSending(QuicResetStreamError error,
85                                 QuicStreamId stream_id);
86 
87   // Tries to send an HANDSHAKE_DONE frame. The frame is buffered if it can not
88   // be sent immediately.
89   void WriteOrBufferHandshakeDone();
90 
91   // Tries to send an AckFrequencyFrame. The frame is buffered if it cannot be
92   // sent immediately.
93   void WriteOrBufferAckFrequency(
94       const QuicAckFrequencyFrame& ack_frequency_frame);
95 
96   // Tries to send a NEW_CONNECTION_ID frame. The frame is buffered if it cannot
97   // be sent immediately.
98   void WriteOrBufferNewConnectionId(
99       const QuicConnectionId& connection_id, uint64_t sequence_number,
100       uint64_t retire_prior_to,
101       const StatelessResetToken& stateless_reset_token);
102 
103   // Tries to send a RETIRE_CONNNECTION_ID frame. The frame is buffered if it
104   // cannot be sent immediately.
105   void WriteOrBufferRetireConnectionId(uint64_t sequence_number);
106 
107   // Tries to send a NEW_TOKEN frame. Buffers the frame if it cannot be sent
108   // immediately.
109   void WriteOrBufferNewToken(absl::string_view token);
110 
111   // Called when |frame| gets acked. Returns true if |frame| gets acked for the
112   // first time, return false otherwise.
113   bool OnControlFrameAcked(const QuicFrame& frame);
114 
115   // Called when |frame| is considered as lost.
116   void OnControlFrameLost(const QuicFrame& frame);
117 
118   // Called by the session when the connection becomes writable.
119   void OnCanWrite();
120 
121   // Retransmit |frame| if it is still outstanding. Returns false if the frame
122   // does not get retransmitted because the connection is blocked. Otherwise,
123   // returns true.
124   bool RetransmitControlFrame(const QuicFrame& frame, TransmissionType type);
125 
126   // Returns true if |frame| is outstanding and waiting to be acked. Returns
127   // false otherwise.
128   bool IsControlFrameOutstanding(const QuicFrame& frame) const;
129 
130   // Returns true if there is any lost control frames waiting to be
131   // retransmitted.
132   bool HasPendingRetransmission() const;
133 
134   // Returns true if there are any lost or new control frames waiting to be
135   // sent.
136   bool WillingToWrite() const;
137 
138  private:
139   friend class test::QuicControlFrameManagerPeer;
140 
141   // Tries to write buffered control frames to the peer.
142   void WriteBufferedFrames();
143 
144   // Called when |frame| is sent for the first time or gets retransmitted.
145   void OnControlFrameSent(const QuicFrame& frame);
146 
147   // Writes pending retransmissions if any.
148   void WritePendingRetransmission();
149 
150   // Called when frame with |id| gets acked. Returns true if |id| gets acked for
151   // the first time, return false otherwise.
152   bool OnControlFrameIdAcked(QuicControlFrameId id);
153 
154   // Retrieves the next pending retransmission. This must only be called when
155   // there are pending retransmissions.
156   QuicFrame NextPendingRetransmission() const;
157 
158   // Returns true if there are buffered frames waiting to be sent for the first
159   // time.
160   bool HasBufferedFrames() const;
161 
162   // Writes or buffers a control frame.  Frame is buffered if there already
163   // are frames waiting to be sent. If no others waiting, will try to send the
164   // frame.
165   void WriteOrBufferQuicFrame(QuicFrame frame);
166 
167   quiche::QuicheCircularDeque<QuicFrame> control_frames_;
168 
169   // Id of latest saved control frame. 0 if no control frame has been saved.
170   QuicControlFrameId last_control_frame_id_;
171 
172   // The control frame at the 0th index of control_frames_.
173   QuicControlFrameId least_unacked_;
174 
175   // ID of the least unsent control frame.
176   QuicControlFrameId least_unsent_;
177 
178   // TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
179   // is not used here.
180   // Lost control frames waiting to be retransmitted.
181   quiche::QuicheLinkedHashMap<QuicControlFrameId, bool>
182       pending_retransmissions_;
183 
184   DelegateInterface* delegate_;
185 
186   // Last sent window update frame for each stream.
187   absl::flat_hash_map<QuicStreamId, QuicControlFrameId> window_update_frames_;
188 };
189 
190 }  // namespace quic
191 
192 #endif  // QUICHE_QUIC_CORE_QUIC_CONTROL_FRAME_MANAGER_H_
193