blob: 49ade23576588e37f51fbf4075082896091f3425 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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#include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
6
7#include <memory>
8#include <utility>
9
10#include "net/third_party/quiche/src/quic/core/quic_ack_listener_interface.h"
11#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
12#include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h"
13#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
14#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer_buffer.h"
15#include "net/third_party/quiche/src/quic/core/quic_types.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
19
20namespace quic {
21
22QuartcStream::QuartcStream(QuicStreamId id, QuicSession* session)
23 : QuicStream(id, session, /*is_static=*/false, BIDIRECTIONAL) {
24 sequencer()->set_level_triggered(true);
25}
26
27QuartcStream::QuartcStream(PendingStream pending)
28 : QuicStream(std::move(pending), BIDIRECTIONAL) {
29 sequencer()->set_level_triggered(true);
30}
31
32QuartcStream::~QuartcStream() {}
33
34void QuartcStream::OnDataAvailable() {
35 bool fin = sequencer()->ReadableBytes() + sequencer()->NumBytesConsumed() ==
36 sequencer()->close_offset();
37
38 // Upper bound on number of readable regions. Each complete block's worth of
39 // data crosses at most one region boundary. The remainder may cross one more
40 // boundary. Number of regions is one more than the number of region
41 // boundaries crossed.
42 size_t iov_length = sequencer()->ReadableBytes() /
43 QuicStreamSequencerBuffer::kBlockSizeBytes +
44 2;
45 std::unique_ptr<iovec[]> iovecs = QuicMakeUnique<iovec[]>(iov_length);
46 iov_length = sequencer()->GetReadableRegions(iovecs.get(), iov_length);
47
48 sequencer()->MarkConsumed(
49 delegate_->OnReceived(this, iovecs.get(), iov_length, fin));
50 if (sequencer()->IsClosed()) {
51 OnFinRead();
52 }
53}
54
55void QuartcStream::OnClose() {
56 QuicStream::OnClose();
57 DCHECK(delegate_);
58 delegate_->OnClose(this);
59}
60
61void QuartcStream::OnStreamDataConsumed(size_t bytes_consumed) {
62 QuicStream::OnStreamDataConsumed(bytes_consumed);
63
64 DCHECK(delegate_);
65 delegate_->OnBufferChanged(this);
66}
67
68void QuartcStream::OnDataBuffered(
69 QuicStreamOffset offset,
70 QuicByteCount data_length,
71 const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) {
72 DCHECK(delegate_);
73 delegate_->OnBufferChanged(this);
74}
75
76bool QuartcStream::OnStreamFrameAcked(QuicStreamOffset offset,
77 QuicByteCount data_length,
78 bool fin_acked,
79 QuicTime::Delta ack_delay_time,
80 QuicByteCount* newly_acked_length) {
81 // Previous losses of acked data are no longer relevant to the retransmission
82 // count. Once data is acked, it will never be retransmitted.
83 lost_frame_counter_.RemoveInterval(
84 QuicInterval<QuicStreamOffset>(offset, offset + data_length));
85
86 return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
87 ack_delay_time, newly_acked_length);
88}
89
90void QuartcStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
91 QuicByteCount data_length,
92 bool fin_retransmitted) {
93 QuicStream::OnStreamFrameRetransmitted(offset, data_length,
94 fin_retransmitted);
95
96 DCHECK(delegate_);
97 delegate_->OnBufferChanged(this);
98}
99
100void QuartcStream::OnStreamFrameLost(QuicStreamOffset offset,
101 QuicByteCount data_length,
102 bool fin_lost) {
103 QuicStream::OnStreamFrameLost(offset, data_length, fin_lost);
104
105 lost_frame_counter_.AddInterval(
106 QuicInterval<QuicStreamOffset>(offset, offset + data_length));
107
108 DCHECK(delegate_);
109 delegate_->OnBufferChanged(this);
110}
111
112void QuartcStream::OnCanWrite() {
113 if (lost_frame_counter_.MaxCount() >
114 static_cast<size_t>(max_retransmission_count_) &&
115 HasPendingRetransmission()) {
116 Reset(QUIC_STREAM_CANCELLED);
117 return;
118 }
119 QuicStream::OnCanWrite();
120}
121
122bool QuartcStream::cancel_on_loss() {
123 return max_retransmission_count_ == 0;
124}
125
126void QuartcStream::set_cancel_on_loss(bool cancel_on_loss) {
127 if (cancel_on_loss) {
128 max_retransmission_count_ = 0;
129 } else {
130 max_retransmission_count_ = std::numeric_limits<int>::max();
131 }
132}
133
134int QuartcStream::max_retransmission_count() const {
135 return max_retransmission_count_;
136}
137
138void QuartcStream::set_max_retransmission_count(int max_retransmission_count) {
139 max_retransmission_count_ = max_retransmission_count;
140}
141
142QuicByteCount QuartcStream::BytesPendingRetransmission() {
143 if (lost_frame_counter_.MaxCount() >
144 static_cast<size_t>(max_retransmission_count_)) {
145 return 0; // Lost bytes will never be retransmitted.
146 }
147 QuicByteCount bytes = 0;
148 for (const auto& interval : send_buffer().pending_retransmissions()) {
149 bytes += interval.Length();
150 }
151 return bytes;
152}
153
154QuicStreamOffset QuartcStream::ReadOffset() {
155 return sequencer()->NumBytesConsumed();
156}
157
158void QuartcStream::FinishWriting() {
159 WriteOrBufferData(QuicStringPiece(nullptr, 0), true, nullptr);
160}
161
162void QuartcStream::SetDelegate(Delegate* delegate) {
163 if (delegate_) {
164 LOG(WARNING) << "The delegate for Stream " << id()
165 << " has already been set.";
166 }
167 delegate_ = delegate;
168 DCHECK(delegate_);
169}
170
171} // namespace quic