15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/reliable_quic_stream.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/iovector.h" 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/quic/quic_flow_controller.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_session.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ") 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct iovec MakeIovec(StringPiece data) { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov = {const_cast<char*>(data.data()), 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<size_t>(data.size())}; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return iov; 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)size_t GetInitialStreamFlowControlWindowToSend(QuicSession* session) { 296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) QuicVersion version = session->connection()->version(); 306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (version <= QUIC_VERSION_19) { 316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return session->config()->GetInitialFlowControlWindowToSend(); 326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return session->config()->GetInitialStreamFlowControlWindowToSend(); 356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)size_t GetReceivedFlowControlWindow(QuicSession* session) { 386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) QuicVersion version = session->connection()->version(); 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (version <= QUIC_VERSION_19) { 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (session->config()->HasReceivedInitialFlowControlWindowBytes()) { 416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return session->config()->ReceivedInitialFlowControlWindowBytes(); 426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return kDefaultFlowControlSendWindow; 456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Version must be >= QUIC_VERSION_21, so we check for stream specific flow 486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // control window. 496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) { 506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return session->config()->ReceivedInitialStreamFlowControlWindowBytes(); 516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return kDefaultFlowControlSendWindow; 546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Wrapper that aggregates OnAckNotifications for packets sent using 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData and delivers them to the original 6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// QuicAckNotifier::DelegateInterface after all bytes written using 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData are acked. This level of indirection is 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// necessary because the delegate interface provides no mechanism that 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData can use to inform it that the write required 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// multiple WritevData calls or that only part of the data has been 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out by the time ACKs start arriving. 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class ReliableQuicStream::ProxyAckNotifierDelegate 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : public QuicAckNotifier::DelegateInterface { 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) explicit ProxyAckNotifierDelegate(DelegateInterface* delegate) 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : delegate_(delegate), 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_acks_(0), 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_(false), 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_(0), 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_(0), 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_(0), 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_(0) { 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void OnAckNotification(int num_original_packets, 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes, 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets, 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int num_retransmitted_bytes, 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicTime::Delta delta_largest_observed) 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OVERRIDE { 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK_LT(0, pending_acks_); 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) --pending_acks_; 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_ += num_original_packets; 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_ += num_original_bytes; 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_ += num_retransmitted_packets; 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_ += num_retransmitted_bytes; 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (wrote_last_data_ && pending_acks_ == 0) { 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate_->OnAckNotification(num_original_packets_, 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_, 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_, 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch num_retransmitted_bytes_, 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch delta_largest_observed); 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void WroteData(bool last_data) { 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!wrote_last_data_); 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++pending_acks_; 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_ = last_data; 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) protected: 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Delegates are ref counted. 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual ~ProxyAckNotifierDelegate() OVERRIDE { 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Original delegate. delegate_->OnAckNotification will be called when: 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // wrote_last_data_ == true and pending_acks_ == 0 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<DelegateInterface> delegate_; 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Number of outstanding acks. 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int pending_acks_; 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // True if no pending writes remain. 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool wrote_last_data_; 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Accumulators. 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_packets_; 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes_; 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets_; 12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_bytes_; 12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProxyAckNotifierDelegate); 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::PendingData( 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) string data_in, scoped_refptr<ProxyAckNotifierDelegate> delegate_in) 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : data(data_in), delegate(delegate_in) { 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::~PendingData() { 13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sequencer_(this), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_read_(0), 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_(0), 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_(QUIC_STREAM_NO_ERROR), 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_(QUIC_NO_ERROR), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_(false), 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_side_closed_(false), 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_(false), 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fin_sent_(false), 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fin_received_(false), 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_(false), 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) rst_received_(false), 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fec_policy_(FEC_PROTECT_OPTIONAL), 1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_server_(session_->is_server()), 1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch flow_controller_( 1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) session_->connection(), id_, is_server_, 1596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetReceivedFlowControlWindow(session), 1606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetInitialStreamFlowControlWindowToSend(session), 1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetInitialStreamFlowControlWindowToSend(session)), 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch connection_flow_controller_(session_->flow_controller()), 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch stream_contributes_to_connection_flow_control_(true) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We don't want to be reading: blackhole the data. 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame.stream_id != id_) { 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) session_->connection()->SendConnectionClose(QUIC_INTERNAL_ERROR); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (frame.fin) { 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fin_received_ = true; 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 185e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // This count include duplicate data received. 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t frame_payload_size = frame.data.TotalBufferSize(); 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) stream_bytes_read_ += frame_payload_size; 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Flow control is interested in tracking highest received offset. 19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) { 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // As the highest received offset has changed, we should check to see if 19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // this is a violation of flow control. 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (flow_controller_.FlowControlViolation() || 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) connection_flow_controller_->FlowControlViolation()) { 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) session_->connection()->SendConnectionClose( 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA); 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sequencer_.OnStreamFrame(frame); 202e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 203e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ReliableQuicStream::num_frames_received() const { 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return sequencer_.num_frames_received(); 206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ReliableQuicStream::num_duplicate_frames_received() const { 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return sequencer_.num_duplicate_frames_received(); 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) { 213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) rst_received_ = true; 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MaybeIncreaseHighestReceivedOffset(frame.byte_offset); 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_error_ = frame.error_code; 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error, 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool from_peer) { 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (read_side_closed_ && write_side_closed_) { 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != QUIC_NO_ERROR) { 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = QUIC_STREAM_CONNECTION_ERROR; 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_ = error; 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::OnFinRead() { 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(sequencer_.IsClosed()); 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) fin_received_ = true; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) { 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NE(QUIC_STREAM_NO_ERROR, error); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = error; 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sending a RstStream results in calling CloseStream. 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->SendRstStream(id(), error, stream_bytes_written_); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnection(QuicErrorCode error) { 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionClose(error); 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error, 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const string& details) { 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionCloseWithDetails(error, details); 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicVersion ReliableQuicStream::version() const { 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->connection()->version(); 260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ReliableQuicStream::WriteOrBufferData( 26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece data, 26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool fin, 26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data.empty() && !fin) { 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "data.empty() && !fin"; 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin_buffered_) { 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "Fin already buffered"; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 27623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<ProxyAckNotifierDelegate> proxy_delegate; 27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (ack_notifier_delegate != NULL) { 27823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate = new ProxyAckNotifierDelegate(ack_notifier_delegate); 27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 28023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConsumedData consumed_data(0, false); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_ = fin; 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.empty()) { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov(MakeIovec(data)); 28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) consumed_data = WritevData(&iov, 1, fin, proxy_delegate.get()); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(consumed_data.bytes_consumed, data.length()); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool write_completed; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there's unconsumed data or an unconsumed fin, queue it. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed < data.length() || 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (fin && !consumed_data.fin_consumed)) { 29423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece remainder(data.substr(consumed_data.bytes_consumed)); 29523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_data_.push_back(PendingData(remainder.as_string(), proxy_delegate)); 29623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = false; 29723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 29823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = true; 29923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if ((proxy_delegate.get() != NULL) && 30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed)) { 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate->WroteData(write_completed); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin = false; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!queued_data_.empty()) { 31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PendingData* pending_data = &queued_data_.front(); 31123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ProxyAckNotifierDelegate* delegate = pending_data->delegate.get(); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.size() == 1 && fin_buffered_) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin = true; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 31523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) struct iovec iov(MakeIovec(pending_data->data)); 31623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicConsumedData consumed_data = WritevData(&iov, 1, fin, delegate); 31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed == pending_data->data.size() && 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin == consumed_data.fin_consumed) { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.pop_front(); 32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(true); 32223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 32423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed > 0) { 32523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_data->data.erase(0, consumed_data.bytes_consumed); 32623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(false); 32823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 32923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::MaybeSendBlocked() { 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) flow_controller_.MaybeSendBlocked(); 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!stream_contributes_to_connection_flow_control_) { 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) connection_flow_controller_->MaybeSendBlocked(); 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If we are connection level flow control blocked, then add the stream 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // to the write blocked list. It will be given a chance to write when a 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // connection level WINDOW_UPDATE arrives. 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (connection_flow_controller_->IsBlocked() && 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !flow_controller_.IsBlocked()) { 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WritevData( 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const struct iovec* iov, 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int iov_count, 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool fin, 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return QuicConsumedData(0, false); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 360e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // How much data we want to write. 361e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch size_t write_length = TotalIovecLength(iov, iov_count); 362e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 363e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // A FIN with zero data payload should not be flow control blocked. 364e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool fin_with_zero_data = (fin && write_length == 0); 365e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (flow_controller_.IsEnabled()) { 3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // How much data we are allowed to write from flow control. 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint64 send_window = flow_controller_.SendWindowSize(); 369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // removing QUIC_VERSION_19. 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (stream_contributes_to_connection_flow_control_ && 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch connection_flow_controller_->IsEnabled()) { 373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) send_window = 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) min(send_window, connection_flow_controller_->SendWindowSize()); 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 3765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 377e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (send_window == 0 && !fin_with_zero_data) { 378e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Quick return if we can't send anything. 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MaybeSendBlocked(); 380e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return QuicConsumedData(0, false); 381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 382e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 383e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (write_length > send_window) { 384e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Don't send the FIN if we aren't going to send all the data. 385e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch fin = false; 386e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 387e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Writing more data would be a violation of flow control. 388e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch write_length = send_window; 389e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Fill an IOVector with bytes from the iovec. 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IOVector data; 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data.AppendIovecAtMostBytes(iov, iov_count, write_length); 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicConsumedData consumed_data = session()->WritevData( 397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) id(), data, stream_bytes_written_, fin, GetFecProtection(), 398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ack_notifier_delegate); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_ += consumed_data.bytes_consumed; 400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AddBytesSent(consumed_data.bytes_consumed); 4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (consumed_data.bytes_consumed == write_length) { 4040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!fin_with_zero_data) { 405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MaybeSendBlocked(); 406e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fin && consumed_data.fin_consumed) { 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_sent_ = true; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseWriteSide(); 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (fin && !consumed_data.fin_consumed) { 411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return consumed_data; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)FecProtection ReliableQuicStream::GetFecProtection() { 420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return fec_policy_ == FEC_PROTECT_ALWAYS ? MUST_FEC_PROTECT : MAY_FEC_PROTECT; 421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_side_closed_) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done reading from stream " << id(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_ = true; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (write_side_closed_) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done writing to stream " << id(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_ = true; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 449010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ReliableQuicStream::HasBufferedData() const { 45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return !queued_data_.empty(); 45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() { 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseReadSide(); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseWriteSide(); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!fin_sent_ && !rst_sent_) { 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, we must tell the peer how many bytes we have 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // written on this stream before termination. Done here if needed, using a 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RST frame. 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); 4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->SendRstStream(id(), QUIC_RST_FLOW_CONTROL_ACCOUNTING, 4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stream_bytes_written_); 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We are closing the stream and will not process any further incoming bytes. 46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // As there may be more bytes in flight and we need to ensure that both 46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // endpoints have the same connection level flow control state, mark all 47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // unreceived or buffered bytes as consumed. 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint64 bytes_to_consume = flow_controller_.highest_received_byte_offset() - 47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) flow_controller_.bytes_consumed(); 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AddBytesConsumed(bytes_to_consume); 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 476e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ReliableQuicStream::OnWindowUpdateFrame( 477e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const QuicWindowUpdateFrame& frame) { 4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!flow_controller_.IsEnabled()) { 479e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DLOG(DFATAL) << "Flow control not enabled! " << version(); 480e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 481e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { 4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // We can write again! 4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(rjshade): This does not respect priorities (e.g. multiple 4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // outstanding POSTs are unblocked on arrival of 4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // SHLO with initial window). 487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // As long as the connection is not flow control blocked, we can write! 4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OnCanWrite(); 489e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 490e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 491e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) { 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!flow_controller_.IsEnabled()) { 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint64 increment = 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_offset - flow_controller_.highest_received_byte_offset(); 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If |new_offset| increased the stream flow controller's highest received 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // offset, then we need to increase the connection flow controller's value 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // by the incremental difference. 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (stream_contributes_to_connection_flow_control_) { 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) connection_flow_controller_->UpdateHighestReceivedOffset( 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) connection_flow_controller_->highest_received_byte_offset() + 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) increment); 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::AddBytesSent(uint64 bytes) { 514010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (flow_controller_.IsEnabled()) { 515010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) flow_controller_.AddBytesSent(bytes); 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (stream_contributes_to_connection_flow_control_) { 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch connection_flow_controller_->AddBytesSent(bytes); 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { 523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (flow_controller_.IsEnabled()) { 52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Only adjust stream level flow controller if we are still reading. 52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!read_side_closed_) { 52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) flow_controller_.AddBytesConsumed(bytes); 52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (stream_contributes_to_connection_flow_control_) { 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch connection_flow_controller_->AddBytesConsumed(bytes); 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochvoid ReliableQuicStream::UpdateSendWindowOffset(uint64 new_window) { 5361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch if (flow_controller_.UpdateSendWindowOffset(new_window)) { 5371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch OnCanWrite(); 5381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch } 5391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch} 5401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ReliableQuicStream::IsFlowControlBlocked() { 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (flow_controller_.IsBlocked()) { 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return stream_contributes_to_connection_flow_control_ && 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch connection_flow_controller_->IsBlocked(); 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 550