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