blob: c8e5012767aac71a8d2ef0c75788b30fdc75f620 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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// The base class for client/server QUIC streams.
6
7// It does not contain the entire interface needed by an application to interact
8// with a QUIC stream. Some parts of the interface must be obtained by
9// accessing the owning session object. A subclass of QuicStream
10// connects the object and the application that generates and consumes the data
11// of the stream.
12
13// The QuicStream object has a dependent QuicStreamSequencer object,
14// which is given the stream frames as they arrive, and provides stream data in
15// order by invoking ProcessRawData().
16
17#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
18#define QUICHE_QUIC_CORE_QUIC_STREAM_H_
19
20#include <cstddef>
21#include <cstdint>
22#include <list>
vasilvv872e7a32019-03-12 16:42:44 -070023#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050024
QUICHE teama6ef0a62019-03-07 20:34:33 -050025#include "net/third_party/quiche/src/quic/core/quic_flow_controller.h"
26#include "net/third_party/quiche/src/quic/core/quic_packets.h"
27#include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h"
28#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
29#include "net/third_party/quiche/src/quic/core/quic_types.h"
30#include "net/third_party/quiche/src/quic/core/session_notifier_interface.h"
31#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
32#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
nharperd5c4a932019-05-13 13:58:49 -070033#include "net/third_party/quiche/src/quic/platform/api/quic_optional.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050034#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050035#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
36#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
37
38namespace quic {
39
40namespace test {
41class QuicStreamPeer;
42} // namespace test
43
44class QuicSession;
45class QuicStream;
46
47// Buffers frames for a stream until the first byte of that frame arrives.
48class QUIC_EXPORT_PRIVATE PendingStream
49 : public QuicStreamSequencer::StreamInterface {
50 public:
51 PendingStream(QuicStreamId id, QuicSession* session);
52 PendingStream(const PendingStream&) = delete;
53 PendingStream(PendingStream&&) = default;
54 ~PendingStream() override = default;
55
56 // QuicStreamSequencer::StreamInterface
57 void OnDataAvailable() override;
58 void OnFinRead() override;
59 void AddBytesConsumed(QuicByteCount bytes) override;
60 void Reset(QuicRstStreamErrorCode error) override;
61 void CloseConnectionWithDetails(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -070062 const std::string& details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -050063 QuicStreamId id() const override;
64 const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
65
66 // Buffers the contents of |frame|. Frame must have a non-zero offset.
67 // If the data violates flow control, the connection will be closed.
68 void OnStreamFrame(const QuicStreamFrame& frame);
69
70 // Stores the final byte offset from |frame|.
71 // If the final offset violates flow control, the connection will be closed.
72 void OnRstStreamFrame(const QuicRstStreamFrame& frame);
73
74 // Returns the number of bytes read on this stream.
75 uint64_t stream_bytes_read() { return stream_bytes_read_; }
76
renjietang0c558862019-05-08 13:26:23 -070077 const QuicStreamSequencer* sequencer() const { return &sequencer_; }
78
renjietangbb1c4892019-05-24 15:58:44 -070079 void MarkConsumed(size_t num_bytes);
80
bnc4ff60622019-08-09 18:55:45 -070081 // Tells the sequencer to ignore all incoming data itself and not call
82 // OnDataAvailable().
83 void StopReading();
84
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 private:
86 friend class QuicStream;
87
88 bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
89
90 // ID of this stream.
91 QuicStreamId id_;
92
93 // Session which owns this.
94 QuicSession* session_;
95
96 // Bytes read refers to payload bytes only: they do not include framing,
97 // encryption overhead etc.
98 uint64_t stream_bytes_read_;
99
100 // True if a frame containing a fin has been received.
101 bool fin_received_;
102
103 // Connection-level flow controller. Owned by the session.
104 QuicFlowController* connection_flow_controller_;
105 // Stream-level flow controller.
106 QuicFlowController flow_controller_;
107 // Stores the buffered frames.
108 QuicStreamSequencer sequencer_;
109};
110
111class QUIC_EXPORT_PRIVATE QuicStream
112 : public QuicStreamSequencer::StreamInterface {
113 public:
114 // This is somewhat arbitrary. It's possible, but unlikely, we will either
115 // fail to set a priority client-side, or cancel a stream before stripping the
116 // priority from the wire server-side. In either case, start out with a
117 // priority in the middle.
118 static const spdy::SpdyPriority kDefaultPriority = 3;
119 static_assert(kDefaultPriority ==
120 (spdy::kV3LowestPriority + spdy::kV3HighestPriority) / 2,
121 "Unexpected value of kDefaultPriority");
122
123 // Creates a new stream with stream_id |id| associated with |session|. If
124 // |is_static| is true, then the stream will be given precedence
125 // over other streams when determing what streams should write next.
126 // |type| indicates whether the stream is bidirectional, read unidirectional
127 // or write unidirectional.
128 // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
129 QuicStream(QuicStreamId id,
130 QuicSession* session,
131 bool is_static,
132 StreamType type);
renjietangbaea59c2019-05-29 15:08:14 -0700133 QuicStream(PendingStream* pending, StreamType type, bool is_static);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134 QuicStream(const QuicStream&) = delete;
135 QuicStream& operator=(const QuicStream&) = delete;
136
137 virtual ~QuicStream();
138
139 // Not in use currently.
140 void SetFromConfig();
141
142 // QuicStreamSequencer::StreamInterface implementation.
143 QuicStreamId id() const override { return id_; }
144 // Called by the stream subclass after it has consumed the final incoming
145 // data.
146 void OnFinRead() override;
147
148 // Called by the subclass or the sequencer to reset the stream from this
149 // end.
150 void Reset(QuicRstStreamErrorCode error) override;
151
152 // Called by the subclass or the sequencer to close the entire connection from
153 // this end.
154 void CloseConnectionWithDetails(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700155 const std::string& details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157 // Get peer IP of the lastest packet which connection is dealing/delt with.
158 const QuicSocketAddress& PeerAddressOfLatestPacket() const override;
159
160 // Called by the session when a (potentially duplicate) stream frame has been
161 // received for this stream.
162 virtual void OnStreamFrame(const QuicStreamFrame& frame);
163
164 // Called by the session when the connection becomes writeable to allow the
165 // stream to write any pending data.
166 virtual void OnCanWrite();
167
168 // Called by the session just before the object is destroyed.
169 // The object should not be accessed after OnClose is called.
170 // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
171 // a RST_STREAM has been sent.
172 virtual void OnClose();
173
174 // Called by the session when the endpoint receives a RST_STREAM from the
175 // peer.
176 virtual void OnStreamReset(const QuicRstStreamFrame& frame);
177
178 // Called by the session when the endpoint receives or sends a connection
179 // close, and should immediately close the stream.
180 virtual void OnConnectionClosed(QuicErrorCode error,
181 ConnectionCloseSource source);
182
fayang476683a2019-07-25 12:42:16 -0700183 const spdy::SpdyStreamPrecedence& precedence() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184
185 // Sets priority_ to priority. This should only be called before bytes are
186 // written to the server.
fayang476683a2019-07-25 12:42:16 -0700187 void SetPriority(const spdy::SpdyStreamPrecedence& precedence);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188
189 // Returns true if this stream is still waiting for acks of sent data.
190 // This will return false if all data has been acked, or if the stream
191 // is no longer interested in data being acked (which happens when
192 // a stream is reset because of an error).
193 bool IsWaitingForAcks() const;
194
195 // Number of bytes available to read.
196 size_t ReadableBytes() const;
197
198 QuicRstStreamErrorCode stream_error() const { return stream_error_; }
199 QuicErrorCode connection_error() const { return connection_error_; }
200
201 bool reading_stopped() const {
202 return sequencer_.ignore_read_data() || read_side_closed_;
203 }
204 bool write_side_closed() const { return write_side_closed_; }
205
206 bool rst_received() const { return rst_received_; }
207 bool rst_sent() const { return rst_sent_; }
208 bool fin_received() const { return fin_received_; }
209 bool fin_sent() const { return fin_sent_; }
210 bool fin_outstanding() const { return fin_outstanding_; }
211 bool fin_lost() const { return fin_lost_; }
212
213 uint64_t BufferedDataBytes() const;
214
215 uint64_t stream_bytes_read() const { return stream_bytes_read_; }
216 uint64_t stream_bytes_written() const;
217
218 size_t busy_counter() const { return busy_counter_; }
219 void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }
220
221 void set_fin_sent(bool fin_sent) { fin_sent_ = fin_sent; }
222 void set_fin_received(bool fin_received) { fin_received_ = fin_received; }
223 void set_rst_sent(bool rst_sent) { rst_sent_ = rst_sent; }
224
225 void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
226 void set_stream_error(QuicRstStreamErrorCode error) { stream_error_ = error; }
227
228 // Adjust the flow control window according to new offset in |frame|.
229 virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
230
231 int num_frames_received() const;
232 int num_duplicate_frames_received() const;
233
nharperd5c4a932019-05-13 13:58:49 -0700234 QuicFlowController* flow_controller() { return &*flow_controller_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500235
236 // Called when endpoint receives a frame which could increase the highest
237 // offset.
238 // Returns true if the highest offset did increase.
239 bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240
241 // Updates the flow controller's send window offset and calls OnCanWrite if
242 // it was blocked before.
243 void UpdateSendWindowOffset(QuicStreamOffset new_offset);
244
245 // Returns true if the stream has received either a RST_STREAM or a FIN -
246 // either of which gives a definitive number of bytes which the peer has
247 // sent. If this is not true on deletion of the stream object, the session
248 // must keep track of the stream's byte offset until a definitive final value
249 // arrives.
250 bool HasFinalReceivedByteOffset() const {
251 return fin_received_ || rst_received_;
252 }
253
254 // Returns true if the stream has queued data waiting to write.
255 bool HasBufferedData() const;
256
257 // Returns the version of QUIC being used for this stream.
258 QuicTransportVersion transport_version() const;
259
260 // Returns the crypto handshake protocol that was used on this stream's
261 // connection.
262 HandshakeProtocol handshake_protocol() const;
263
264 // Sets the sequencer to consume all incoming data itself and not call
265 // OnDataAvailable().
266 // When the FIN is received, the stream will be notified automatically (via
267 // OnFinRead()) (which may happen during the call of StopReading()).
268 // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
269 // stop sending stream-level flow-control updates when this end sends FIN.
270 virtual void StopReading();
271
272 // Sends as much of 'data' to the connection as the connection will consume,
273 // and then buffers any remaining data in queued_data_.
274 // If fin is true: if it is immediately passed on to the session,
275 // write_side_closed() becomes true, otherwise fin_buffered_ becomes true.
276 void WriteOrBufferData(
277 QuicStringPiece data,
278 bool fin,
279 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener);
280
281 // Adds random padding after the fin is consumed for this stream.
282 void AddRandomPaddingAfterFin();
283
284 // Write |data_length| of data starts at |offset| from send buffer.
285 bool WriteStreamData(QuicStreamOffset offset,
286 QuicByteCount data_length,
287 QuicDataWriter* writer);
288
289 // Called when data [offset, offset + data_length) is acked. |fin_acked|
290 // indicates whether the fin is acked. Returns true and updates
291 // |newly_acked_length| if any new stream data (including fin) gets acked.
292 virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
293 QuicByteCount data_length,
294 bool fin_acked,
295 QuicTime::Delta ack_delay_time,
296 QuicByteCount* newly_acked_length);
297
298 // Called when data [offset, offset + data_length) was retransmitted.
299 // |fin_retransmitted| indicates whether fin was retransmitted.
300 virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
301 QuicByteCount data_length,
302 bool fin_retransmitted);
303
304 // Called when data [offset, offset + data_length) is considered as lost.
305 // |fin_lost| indicates whether the fin is considered as lost.
306 virtual void OnStreamFrameLost(QuicStreamOffset offset,
307 QuicByteCount data_length,
308 bool fin_lost);
309
310 // Called to retransmit outstanding portion in data [offset, offset +
311 // data_length) and |fin|. Returns true if all data gets retransmitted.
312 virtual bool RetransmitStreamData(QuicStreamOffset offset,
313 QuicByteCount data_length,
314 bool fin);
315
316 // Sets deadline of this stream to be now + |ttl|, returns true if the setting
317 // succeeds.
318 bool MaybeSetTtl(QuicTime::Delta ttl);
319
320 // Same as WritevData except data is provided in reference counted memory so
321 // that data copy is avoided.
322 QuicConsumedData WriteMemSlices(QuicMemSliceSpan span, bool fin);
323
324 // Returns true if any stream data is lost (including fin) and needs to be
325 // retransmitted.
326 virtual bool HasPendingRetransmission() const;
327
328 // Returns true if any portion of data [offset, offset + data_length) is
329 // outstanding or fin is outstanding (if |fin| is true). Returns false
330 // otherwise.
331 bool IsStreamFrameOutstanding(QuicStreamOffset offset,
332 QuicByteCount data_length,
333 bool fin) const;
334
335 StreamType type() const { return type_; }
336
337 // Creates and sends a STOP_SENDING frame. This can be called regardless of
338 // the version that has been negotiated. If not IETF QUIC/Version 99 then the
339 // method is a noop, relieving the application of the necessity of
340 // understanding the connection's QUIC version and knowing whether it can call
341 // this method or not.
342 void SendStopSending(uint16_t code);
343
344 // Invoked when QUIC receives a STOP_SENDING frame for this stream, informing
345 // the application that the peer has sent a STOP_SENDING. The default
346 // implementation is a noop. Is to be overridden by the application-specific
347 // QuicStream class.
348 virtual void OnStopSending(uint16_t code);
349
350 // Close the write side of the socket. Further writes will fail.
351 // Can be called by the subclass or internally.
352 // Does not send a FIN. May cause the stream to be closed.
353 virtual void CloseWriteSide();
354
renjietangfbeb5bf2019-04-19 15:06:20 -0700355 // Returns true if the stream is static.
356 bool is_static() const { return is_static_; }
357
QUICHE teama6ef0a62019-03-07 20:34:33 -0500358 protected:
359 // Sends as many bytes in the first |count| buffers of |iov| to the connection
360 // as the connection will consume. If FIN is consumed, the write side is
361 // immediately closed.
362 // Returns the number of bytes consumed by the connection.
363 // Please note: Returned consumed data is the amount of data saved in send
364 // buffer. The data is not necessarily consumed by the connection. So write
365 // side is closed when FIN is sent.
366 // TODO(fayang): Let WritevData return boolean.
367 QuicConsumedData WritevData(const struct iovec* iov, int iov_count, bool fin);
368
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369 // Close the read side of the socket. May cause the stream to be closed.
370 // Subclasses and consumers should use StopReading to terminate reading early
371 // if expecting a FIN. Can be used directly by subclasses if not expecting a
372 // FIN.
373 void CloseReadSide();
374
375 // Called when data of [offset, offset + data_length] is buffered in send
376 // buffer.
377 virtual void OnDataBuffered(
dschinazi17d42422019-06-18 16:35:07 -0700378 QuicStreamOffset /*offset*/,
379 QuicByteCount /*data_length*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500380 const QuicReferenceCountedPointer<QuicAckListenerInterface>&
dschinazi17d42422019-06-18 16:35:07 -0700381 /*ack_listener*/) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500382
383 // True if buffered data in send buffer is below buffered_data_threshold_.
384 bool CanWriteNewData() const;
385
386 // True if buffered data in send buffer is still below
387 // buffered_data_threshold_ even after writing |length| bytes.
388 bool CanWriteNewDataAfterData(QuicByteCount length) const;
389
390 // Called when upper layer can write new data.
391 virtual void OnCanWriteNewData() {}
392
393 // Called when |bytes_consumed| bytes has been consumed.
394 virtual void OnStreamDataConsumed(size_t bytes_consumed);
395
ianswett93637202019-04-03 08:05:29 -0700396 // Called by the stream sequencer as bytes are consumed from the buffer.
397 // If the receive window has dropped below the threshold, then send a
398 // WINDOW_UPDATE frame.
399 void AddBytesConsumed(QuicByteCount bytes) override;
400
QUICHE teama6ef0a62019-03-07 20:34:33 -0500401 // Writes pending retransmissions if any.
402 virtual void WritePendingRetransmission();
403
404 // This is called when stream tries to retransmit data after deadline_. Make
405 // this virtual so that subclasses can implement their own logics.
406 virtual void OnDeadlinePassed();
407
408 bool fin_buffered() const { return fin_buffered_; }
409
410 const QuicSession* session() const { return session_; }
411 QuicSession* session() { return session_; }
412
413 const QuicStreamSequencer* sequencer() const { return &sequencer_; }
414 QuicStreamSequencer* sequencer() { return &sequencer_; }
415
416 void DisableConnectionFlowControlForThisStream() {
417 stream_contributes_to_connection_flow_control_ = false;
418 }
419
420 const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;
421
422 const QuicStreamSendBuffer& send_buffer() const { return send_buffer_; }
423
424 QuicStreamSendBuffer& send_buffer() { return send_buffer_; }
425
426 private:
427 friend class test::QuicStreamPeer;
428 friend class QuicStreamUtils;
429
430 QuicStream(QuicStreamId id,
431 QuicSession* session,
432 QuicStreamSequencer sequencer,
433 bool is_static,
434 StreamType type,
435 uint64_t stream_bytes_read,
436 bool fin_received,
nharperd5c4a932019-05-13 13:58:49 -0700437 QuicOptional<QuicFlowController> flow_controller,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500438 QuicFlowController* connection_flow_controller);
439
440 // Subclasses and consumers should use reading_stopped.
441 bool read_side_closed() const { return read_side_closed_; }
442
443 // Calls MaybeSendBlocked on the stream's flow controller and the connection
444 // level flow controller. If the stream is flow control blocked by the
445 // connection-level flow controller but not by the stream-level flow
446 // controller, marks this stream as connection-level write blocked.
447 void MaybeSendBlocked();
448
449 // Write buffered data in send buffer. TODO(fayang): Consider combine
450 // WriteOrBufferData, Writev and WriteBufferedData.
451 void WriteBufferedData();
452
ianswett93637202019-04-03 08:05:29 -0700453 // Called when bytes are sent to the peer.
454 void AddBytesSent(QuicByteCount bytes);
455
QUICHE teama6ef0a62019-03-07 20:34:33 -0500456 // Returns true if deadline_ has passed.
457 bool HasDeadlinePassed() const;
458
459 QuicStreamSequencer sequencer_;
460 QuicStreamId id_;
461 // Pointer to the owning QuicSession object.
462 QuicSession* session_;
fayang476683a2019-07-25 12:42:16 -0700463 // The precedence of the stream, once parsed.
464 spdy::SpdyStreamPrecedence precedence_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500465 // Bytes read refers to payload bytes only: they do not include framing,
466 // encryption overhead etc.
467 uint64_t stream_bytes_read_;
468
469 // Stream error code received from a RstStreamFrame or error code sent by the
470 // visitor or sequencer in the RstStreamFrame.
471 QuicRstStreamErrorCode stream_error_;
472 // Connection error code due to which the stream was closed. |stream_error_|
473 // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
474 // should check |connection_error_|.
475 QuicErrorCode connection_error_;
476
477 // True if the read side is closed and further frames should be rejected.
478 bool read_side_closed_;
479 // True if the write side is closed, and further writes should fail.
480 bool write_side_closed_;
481
482 // True if the subclass has written a FIN with WriteOrBufferData, but it was
483 // buffered in queued_data_ rather than being sent to the session.
484 bool fin_buffered_;
485 // True if a FIN has been sent to the session.
486 bool fin_sent_;
487 // True if a FIN is waiting to be acked.
488 bool fin_outstanding_;
489 // True if a FIN is lost.
490 bool fin_lost_;
491
492 // True if this stream has received (and the sequencer has accepted) a
493 // StreamFrame with the FIN set.
494 bool fin_received_;
495
496 // True if an RST_STREAM has been sent to the session.
497 // In combination with fin_sent_, used to ensure that a FIN and/or a
498 // RST_STREAM is always sent to terminate the stream.
499 bool rst_sent_;
500
501 // True if this stream has received a RST_STREAM frame.
502 bool rst_received_;
503
504 // Tracks if the session this stream is running under was created by a
505 // server or a client.
506 Perspective perspective_;
507
nharperd5c4a932019-05-13 13:58:49 -0700508 QuicOptional<QuicFlowController> flow_controller_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509
510 // The connection level flow controller. Not owned.
511 QuicFlowController* connection_flow_controller_;
512
513 // Special streams, such as the crypto and headers streams, do not respect
514 // connection level flow control limits (but are stream level flow control
515 // limited).
516 bool stream_contributes_to_connection_flow_control_;
517
518 // A counter incremented when OnCanWrite() is called and no progress is made.
519 // For debugging only.
520 size_t busy_counter_;
521
522 // Indicates whether paddings will be added after the fin is consumed for this
523 // stream.
524 bool add_random_padding_after_fin_;
525
526 // Send buffer of this stream. Send buffer is cleaned up when data gets acked
527 // or discarded.
528 QuicStreamSendBuffer send_buffer_;
529
bnc5a401422019-06-18 04:32:32 -0700530 // Latched value of quic_buffered_data_threshold.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500531 const QuicByteCount buffered_data_threshold_;
532
533 // If true, then this stream has precedence over other streams for write
534 // scheduling.
535 const bool is_static_;
536
537 // If initialized, reset this stream at this deadline.
538 QuicTime deadline_;
539
540 // Indicates whether this stream is bidirectional, read unidirectional or
541 // write unidirectional.
542 const StreamType type_;
543};
544
545} // namespace quic
546
547#endif // QUICHE_QUIC_CORE_QUIC_STREAM_H_