blob: 8fd9c7632c6fa9a23ae5c05ecdfba2cd0f5d6512 [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"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include "net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h"
dmcardlec60e87a2019-12-12 09:43:19 -080017#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018
19namespace quic {
20
21QuartcStream::QuartcStream(QuicStreamId id, QuicSession* session)
22 : QuicStream(id, session, /*is_static=*/false, BIDIRECTIONAL) {
23 sequencer()->set_level_triggered(true);
24}
25
QUICHE teama6ef0a62019-03-07 20:34:33 -050026QuartcStream::~QuartcStream() {}
27
28void QuartcStream::OnDataAvailable() {
QUICHE team335e56f2019-07-29 15:06:31 -070029 size_t bytes_consumed = 0;
30 do {
31 bool fin = sequencer()->ReadableBytes() + sequencer()->NumBytesConsumed() ==
32 sequencer()->close_offset();
QUICHE teama6ef0a62019-03-07 20:34:33 -050033
QUICHE team335e56f2019-07-29 15:06:31 -070034 // Upper bound on number of readable regions. Each complete block's worth
35 // of data crosses at most one region boundary. The remainder may cross one
36 // more boundary. Number of regions is one more than the number of region
37 // boundaries crossed.
38 size_t iov_length = sequencer()->ReadableBytes() /
39 QuicStreamSequencerBuffer::kBlockSizeBytes +
40 2;
vasilvv0fc587f2019-09-06 13:33:08 -070041 std::unique_ptr<iovec[]> iovecs = std::make_unique<iovec[]>(iov_length);
QUICHE team335e56f2019-07-29 15:06:31 -070042 iov_length = sequencer()->GetReadableRegions(iovecs.get(), iov_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -050043
QUICHE team335e56f2019-07-29 15:06:31 -070044 bytes_consumed = delegate_->OnReceived(this, iovecs.get(), iov_length, fin);
45 sequencer()->MarkConsumed(bytes_consumed);
46 if (sequencer()->IsClosed()) {
47 OnFinRead();
48 break;
49 }
50 } while (bytes_consumed > 0);
QUICHE teama6ef0a62019-03-07 20:34:33 -050051}
52
53void QuartcStream::OnClose() {
54 QuicStream::OnClose();
55 DCHECK(delegate_);
56 delegate_->OnClose(this);
57}
58
59void QuartcStream::OnStreamDataConsumed(size_t bytes_consumed) {
60 QuicStream::OnStreamDataConsumed(bytes_consumed);
61
QUICHE team335e56f2019-07-29 15:06:31 -070062 if (delegate_) {
63 delegate_->OnBufferChanged(this);
64 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050065}
66
67void QuartcStream::OnDataBuffered(
dschinazi17d42422019-06-18 16:35:07 -070068 QuicStreamOffset /*offset*/,
69 QuicByteCount /*data_length*/,
70 const QuicReferenceCountedPointer<
71 QuicAckListenerInterface>& /*ack_listener*/) {
QUICHE team335e56f2019-07-29 15:06:31 -070072 if (delegate_) {
73 delegate_->OnBufferChanged(this);
74 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050075}
76
77bool QuartcStream::OnStreamFrameAcked(QuicStreamOffset offset,
78 QuicByteCount data_length,
79 bool fin_acked,
80 QuicTime::Delta ack_delay_time,
81 QuicByteCount* newly_acked_length) {
82 // Previous losses of acked data are no longer relevant to the retransmission
83 // count. Once data is acked, it will never be retransmitted.
84 lost_frame_counter_.RemoveInterval(
85 QuicInterval<QuicStreamOffset>(offset, offset + data_length));
86
87 return QuicStream::OnStreamFrameAcked(offset, data_length, fin_acked,
88 ack_delay_time, newly_acked_length);
89}
90
91void QuartcStream::OnStreamFrameRetransmitted(QuicStreamOffset offset,
92 QuicByteCount data_length,
93 bool fin_retransmitted) {
94 QuicStream::OnStreamFrameRetransmitted(offset, data_length,
95 fin_retransmitted);
96
97 DCHECK(delegate_);
98 delegate_->OnBufferChanged(this);
99}
100
101void QuartcStream::OnStreamFrameLost(QuicStreamOffset offset,
102 QuicByteCount data_length,
103 bool fin_lost) {
104 QuicStream::OnStreamFrameLost(offset, data_length, fin_lost);
105
106 lost_frame_counter_.AddInterval(
107 QuicInterval<QuicStreamOffset>(offset, offset + data_length));
108
109 DCHECK(delegate_);
110 delegate_->OnBufferChanged(this);
111}
112
113void QuartcStream::OnCanWrite() {
114 if (lost_frame_counter_.MaxCount() >
115 static_cast<size_t>(max_retransmission_count_) &&
116 HasPendingRetransmission()) {
117 Reset(QUIC_STREAM_CANCELLED);
118 return;
119 }
120 QuicStream::OnCanWrite();
121}
122
123bool QuartcStream::cancel_on_loss() {
124 return max_retransmission_count_ == 0;
125}
126
127void QuartcStream::set_cancel_on_loss(bool cancel_on_loss) {
128 if (cancel_on_loss) {
129 max_retransmission_count_ = 0;
130 } else {
131 max_retransmission_count_ = std::numeric_limits<int>::max();
132 }
133}
134
135int QuartcStream::max_retransmission_count() const {
136 return max_retransmission_count_;
137}
138
139void QuartcStream::set_max_retransmission_count(int max_retransmission_count) {
140 max_retransmission_count_ = max_retransmission_count;
141}
142
143QuicByteCount QuartcStream::BytesPendingRetransmission() {
144 if (lost_frame_counter_.MaxCount() >
145 static_cast<size_t>(max_retransmission_count_)) {
146 return 0; // Lost bytes will never be retransmitted.
147 }
148 QuicByteCount bytes = 0;
149 for (const auto& interval : send_buffer().pending_retransmissions()) {
150 bytes += interval.Length();
151 }
152 return bytes;
153}
154
155QuicStreamOffset QuartcStream::ReadOffset() {
156 return sequencer()->NumBytesConsumed();
157}
158
159void QuartcStream::FinishWriting() {
dmcardlec60e87a2019-12-12 09:43:19 -0800160 WriteOrBufferData(quiche::QuicheStringPiece(nullptr, 0), true, nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161}
162
163void QuartcStream::SetDelegate(Delegate* delegate) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500164 delegate_ = delegate;
165 DCHECK(delegate_);
166}
167
168} // namespace quic