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