reliable_quic_stream.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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) 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Wrapper that aggregates OnAckNotifications for packets sent using 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData and delivers them to the original 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// QuicAckNotifier::DelegateInterface after all bytes written using 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData are acked. This level of indirection is 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// necessary because the delegate interface provides no mechanism that 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData can use to inform it that the write required 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// multiple WritevData calls or that only part of the data has been 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out by the time ACKs start arriving. 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class ReliableQuicStream::ProxyAckNotifierDelegate 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : public QuicAckNotifier::DelegateInterface { 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) explicit ProxyAckNotifierDelegate(DelegateInterface* delegate) 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : delegate_(delegate), 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_acks_(0), 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_(false), 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_(0), 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_(0), 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_(0), 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_(0) { 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void OnAckNotification(int num_original_packets, 5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes, 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets, 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int num_retransmitted_bytes, 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicTime::Delta delta_largest_observed) 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OVERRIDE { 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK_LT(0, pending_acks_); 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) --pending_acks_; 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_ += num_original_packets; 6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_ += num_original_bytes; 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_ += num_retransmitted_packets; 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_ += num_retransmitted_bytes; 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (wrote_last_data_ && pending_acks_ == 0) { 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate_->OnAckNotification(num_original_packets_, 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_, 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_, 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch num_retransmitted_bytes_, 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch delta_largest_observed); 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void WroteData(bool last_data) { 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!wrote_last_data_); 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++pending_acks_; 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_ = last_data; 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) protected: 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Delegates are ref counted. 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~ProxyAckNotifierDelegate() { 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Original delegate. delegate_->OnAckNotification will be called when: 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // wrote_last_data_ == true and pending_acks_ == 0 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<DelegateInterface> delegate_; 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Number of outstanding acks. 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int pending_acks_; 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // True if no pending writes remain. 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool wrote_last_data_; 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Accumulators. 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_packets_; 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes_; 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets_; 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_bytes_; 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProxyAckNotifierDelegate); 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::PendingData( 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) string data_in, scoped_refptr<ProxyAckNotifierDelegate> delegate_in) 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : data(data_in), delegate(delegate_in) { 10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::~PendingData() { 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sequencer_(this), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_read_(0), 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_(0), 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_(QUIC_STREAM_NO_ERROR), 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_(QUIC_NO_ERROR), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_(false), 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_side_closed_(false), 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_(false), 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fin_sent_(false), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_(false), 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_server_(session_->is_server()), 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch flow_controller_( 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu session_->connection()->version(), 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch id_, 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_server_, 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->config()->HasReceivedInitialFlowControlWindowBytes() ? 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->config()->ReceivedInitialFlowControlWindowBytes() : 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch kDefaultFlowControlSendWindow, 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->connection()->max_flow_control_receive_window_bytes(), 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->connection()->max_flow_control_receive_window_bytes()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We don't want to be reading: blackhole the data. 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame.stream_id != id_) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error!"; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // This count include duplicate data received. 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stream_bytes_read_ += frame.data.TotalBufferSize(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool accepted = sequencer_.OnStreamFrame(frame); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (flow_controller_.FlowControlViolation()) { 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu session_->connection()->SendConnectionClose(QUIC_FLOW_CONTROL_ERROR); 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 160e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MaybeSendWindowUpdate(); 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accepted; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ReliableQuicStream::MaybeSendWindowUpdate() { 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu flow_controller_.MaybeSendWindowUpdate(session()->connection()); 168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint ReliableQuicStream::num_frames_received() { 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return sequencer_.num_frames_received(); 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint ReliableQuicStream::num_duplicate_frames_received() { 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return sequencer_.num_duplicate_frames_received(); 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) { 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_error_ = frame.error_code; 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error, 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool from_peer) { 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (read_side_closed_ && write_side_closed_) { 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != QUIC_NO_ERROR) { 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = QUIC_STREAM_CONNECTION_ERROR; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_ = error; 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::OnFinRead() { 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(sequencer_.IsClosed()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) { 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NE(QUIC_STREAM_NO_ERROR, error); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = error; 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sending a RstStream results in calling CloseStream. 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->SendRstStream(id(), error, stream_bytes_written_); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnection(QuicErrorCode error) { 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionClose(error); 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error, 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const string& details) { 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionCloseWithDetails(error, details); 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicVersion ReliableQuicStream::version() const { 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->connection()->version(); 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ReliableQuicStream::WriteOrBufferData( 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece data, 22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool fin, 22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data.empty() && !fin) { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "data.empty() && !fin"; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin_buffered_) { 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "Fin already buffered"; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 236b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<ProxyAckNotifierDelegate> proxy_delegate; 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (ack_notifier_delegate != NULL) { 24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate = new ProxyAckNotifierDelegate(ack_notifier_delegate); 24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConsumedData consumed_data(0, false); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_ = fin; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.empty()) { 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov(MakeIovec(data)); 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) consumed_data = WritevData(&iov, 1, fin, proxy_delegate.get()); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(consumed_data.bytes_consumed, data.length()); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool write_completed; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there's unconsumed data or an unconsumed fin, queue it. 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed < data.length() || 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (fin && !consumed_data.fin_consumed)) { 25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece remainder(data.substr(consumed_data.bytes_consumed)); 25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_data_.push_back(PendingData(remainder.as_string(), proxy_delegate)); 25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = false; 25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = true; 26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if ((proxy_delegate.get() != NULL) && 26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed)) { 26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate->WroteData(write_completed); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin = false; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!queued_data_.empty()) { 27223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PendingData* pending_data = &queued_data_.front(); 27323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ProxyAckNotifierDelegate* delegate = pending_data->delegate.get(); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.size() == 1 && fin_buffered_) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin = true; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) struct iovec iov(MakeIovec(pending_data->data)); 27823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicConsumedData consumed_data = WritevData(&iov, 1, fin, delegate); 27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed == pending_data->data.size() && 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin == consumed_data.fin_consumed) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.pop_front(); 28223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 28323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(true); 28423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed > 0) { 28723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_data->data.erase(0, consumed_data.bytes_consumed); 28823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 28923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(false); 29023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 29123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WritevData( 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const struct iovec* iov, 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int iov_count, 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool fin, 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return QuicConsumedData(0, false); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // How much data we want to write. 308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch size_t write_length = TotalIovecLength(iov, iov_count); 309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // A FIN with zero data payload should not be flow control blocked. 311e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool fin_with_zero_data = (fin && write_length == 0); 312e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (flow_controller_.IsEnabled()) { 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // How much data we are allowed to write from flow control. 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t send_window = flow_controller_.SendWindowSize(); 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (send_window == 0 && !fin_with_zero_data) { 318e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Quick return if we can't send anything. 3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch flow_controller_.MaybeSendBlocked(session()->connection()); 320e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return QuicConsumedData(0, false); 321e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 323e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (write_length > send_window) { 324e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Don't send the FIN if we aren't going to send all the data. 325e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch fin = false; 326e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Writing more data would be a violation of flow control. 328e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch write_length = send_window; 329e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Fill an IOVector with bytes from the iovec. 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IOVector data; 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data.AppendIovecAtMostBytes(iov, iov_count, write_length); 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicConsumedData consumed_data = session()->WritevData( 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), data, stream_bytes_written_, fin, ack_notifier_delegate); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_ += consumed_data.bytes_consumed; 339e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 3405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu flow_controller_.AddBytesSent(consumed_data.bytes_consumed); 3410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (consumed_data.bytes_consumed == write_length) { 3430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!fin_with_zero_data) { 3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu flow_controller_.MaybeSendBlocked(session()->connection()); 345e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fin && consumed_data.fin_consumed) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_sent_ = true; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseWriteSide(); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (fin && !consumed_data.fin_consumed) { 350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return consumed_data; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_side_closed_) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done reading from stream " << id(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_ = true; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() { 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (write_side_closed_) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done writing to stream " << id(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_ = true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ReliableQuicStream::HasBufferedData() { 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return !queued_data_.empty(); 38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() { 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseReadSide(); 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseWriteSide(); 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!fin_sent_ && !rst_sent_) { 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, we must tell the peer how many bytes we have 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // written on this stream before termination. Done here if needed, using a 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RST frame. 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); 3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch session_->SendRstStream(id(), QUIC_RST_FLOW_CONTROL_ACCOUNTING, 3980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch stream_bytes_written_); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 403e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ReliableQuicStream::OnWindowUpdateFrame( 404e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const QuicWindowUpdateFrame& frame) { 4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!flow_controller_.IsEnabled()) { 406e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DLOG(DFATAL) << "Flow control not enabled! " << version(); 407e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 408e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 409e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { 4110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // We can write again! 4120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(rjshade): This does not respect priorities (e.g. multiple 4130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // outstanding POSTs are unblocked on arrival of 4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // SHLO with initial window). 4150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch OnCanWrite(); 416e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 417e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 420