1 // Copyright (c) 2018 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 #ifndef QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_ 5 #define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_ 6 7 #include "net/third_party/quiche/src/quic/core/frames/quic_frame.h" 8 #include "net/third_party/quiche/src/quic/core/quic_types.h" 9 #include "net/third_party/quiche/src/quic/core/quic_versions.h" 10 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" 11 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" 12 13 namespace quic { 14 15 namespace test { 16 class QuicSessionPeer; 17 class QuicStreamIdManagerPeer; 18 } // namespace test 19 20 // This class manages the stream ids for IETF QUIC. 21 class QUIC_EXPORT_PRIVATE QuicStreamIdManager { 22 public: 23 class QUIC_EXPORT_PRIVATE DelegateInterface { 24 public: 25 virtual ~DelegateInterface() = default; 26 27 // Send a MAX_STREAMS frame. 28 virtual void SendMaxStreams(QuicStreamCount stream_count, 29 bool unidirectional) = 0; 30 }; 31 32 QuicStreamIdManager(DelegateInterface* delegate, 33 bool unidirectional, 34 Perspective perspective, 35 ParsedQuicVersion version, 36 QuicStreamCount max_allowed_outgoing_streams, 37 QuicStreamCount max_allowed_incoming_streams); 38 39 ~QuicStreamIdManager(); 40 41 // Generate a string suitable for sending to the log/etc to show current state 42 // of the stream ID manager. DebugString()43 std::string DebugString() const { 44 return quiche::QuicheStrCat( 45 " { unidirectional_: ", unidirectional_, 46 ", perspective: ", perspective_, 47 ", outgoing_max_streams_: ", outgoing_max_streams_, 48 ", next_outgoing_stream_id_: ", next_outgoing_stream_id_, 49 ", outgoing_stream_count_: ", outgoing_stream_count_, 50 ", incoming_actual_max_streams_: ", incoming_actual_max_streams_, 51 ", incoming_advertised_max_streams_: ", 52 incoming_advertised_max_streams_, 53 ", incoming_stream_count_: ", incoming_stream_count_, 54 ", available_streams_.size(): ", available_streams_.size(), 55 ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_, 56 " }"); 57 } 58 59 // Processes the STREAMS_BLOCKED frame. If error is encountered, populates 60 // |error_details| and returns false. 61 bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame, 62 std::string* error_details); 63 64 // Returns whether the next outgoing stream ID can be allocated or not. 65 bool CanOpenNextOutgoingStream() const; 66 67 // Generate and send a MAX_STREAMS frame. 68 void SendMaxStreamsFrame(); 69 70 // Invoked to deal with releasing a stream. Does nothing if the stream is 71 // outgoing. If the stream is incoming, the number of streams that the peer 72 // can open will be updated and a MAX_STREAMS frame, informing the peer of 73 // the additional streams, may be sent. 74 void OnStreamClosed(QuicStreamId stream_id); 75 76 // Returns the next outgoing stream id. Applications must call 77 // CanOpenNextOutgoingStream() first. 78 QuicStreamId GetNextOutgoingStreamId(); 79 80 void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams); 81 82 // Called on |max_open_streams| outgoing streams can be created because of 1) 83 // config negotiated or 2) MAX_STREAMS received. Returns true if new 84 // streams can be created. 85 bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams); 86 87 // Checks if the incoming stream ID exceeds the MAX_STREAMS limit. If the 88 // limit is exceeded, populates |error_detials| and returns false. 89 bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id, 90 std::string* error_details); 91 92 // Returns true if |id| is still available. 93 bool IsAvailableStream(QuicStreamId id) const; 94 incoming_initial_max_open_streams()95 QuicStreamCount incoming_initial_max_open_streams() const { 96 return incoming_initial_max_open_streams_; 97 } 98 next_outgoing_stream_id()99 QuicStreamId next_outgoing_stream_id() const { 100 return next_outgoing_stream_id_; 101 } 102 103 // Number of streams that the peer believes that it can still create. 104 QuicStreamCount available_incoming_streams() const; 105 largest_peer_created_stream_id()106 QuicStreamId largest_peer_created_stream_id() const { 107 return largest_peer_created_stream_id_; 108 } 109 outgoing_max_streams()110 QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; } incoming_actual_max_streams()111 QuicStreamCount incoming_actual_max_streams() const { 112 return incoming_actual_max_streams_; 113 } incoming_advertised_max_streams()114 QuicStreamCount incoming_advertised_max_streams() const { 115 return incoming_advertised_max_streams_; 116 } outgoing_stream_count()117 QuicStreamCount outgoing_stream_count() const { 118 return outgoing_stream_count_; 119 } 120 121 private: 122 friend class test::QuicSessionPeer; 123 friend class test::QuicStreamIdManagerPeer; 124 125 // Check whether the MAX_STREAMS window has opened up enough and, if so, 126 // generate and send a MAX_STREAMS frame. 127 void MaybeSendMaxStreamsFrame(); 128 129 // Get what should be the first incoming/outgoing stream ID that 130 // this stream id manager will manage, taking into account directionality and 131 // client/server perspective. 132 QuicStreamId GetFirstOutgoingStreamId() const; 133 QuicStreamId GetFirstIncomingStreamId() const; 134 135 // Back reference to the session containing this Stream ID Manager. 136 DelegateInterface* delegate_; 137 138 // Whether this stream id manager is for unidrectional (true) or bidirectional 139 // (false) streams. 140 const bool unidirectional_; 141 142 // Is this manager a client or a server. 143 const Perspective perspective_; 144 145 // QUIC version used for this manager. 146 const ParsedQuicVersion version_; 147 148 // The number of streams that this node can initiate. 149 // This limit is first set when config is negotiated, but may be updated upon 150 // receiving MAX_STREAMS frame. 151 QuicStreamCount outgoing_max_streams_; 152 153 // The ID to use for the next outgoing stream. 154 QuicStreamId next_outgoing_stream_id_; 155 156 // The number of outgoing streams that have ever been opened, including those 157 // that have been closed. This number must never be larger than 158 // outgoing_max_streams_. 159 QuicStreamCount outgoing_stream_count_; 160 161 // FOR INCOMING STREAMS 162 163 // The actual maximum number of streams that can be opened by the peer. 164 QuicStreamCount incoming_actual_max_streams_; 165 // Max incoming stream number that has been advertised to the peer and is <= 166 // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_ 167 // when a MAX_STREAMS is sent. 168 QuicStreamCount incoming_advertised_max_streams_; 169 170 // Initial maximum on the number of open streams allowed. 171 QuicStreamCount incoming_initial_max_open_streams_; 172 173 // The number of streams that have been created, including open ones and 174 // closed ones. 175 QuicStreamCount incoming_stream_count_; 176 177 // Set of stream ids that are less than the largest stream id that has been 178 // received, but are nonetheless available to be created. 179 QuicHashSet<QuicStreamId> available_streams_; 180 181 QuicStreamId largest_peer_created_stream_id_; 182 }; 183 } // namespace quic 184 185 #endif // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_ 186