reliable_quic_stream.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_session.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ") 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct iovec MakeIovec(StringPiece data) { 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov = {const_cast<char*>(data.data()), 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<size_t>(data.size())}; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return iov; 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Wrapper that aggregates OnAckNotifications for packets sent using 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData and delivers them to the original 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// QuicAckNotifier::DelegateInterface after all bytes written using 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData are acked. This level of indirection is 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// necessary because the delegate interface provides no mechanism that 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData can use to inform it that the write required 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// multiple WritevData calls or that only part of the data has been 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out by the time ACKs start arriving. 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class ReliableQuicStream::ProxyAckNotifierDelegate 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : public QuicAckNotifier::DelegateInterface { 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) explicit ProxyAckNotifierDelegate(DelegateInterface* delegate) 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : delegate_(delegate), 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_acks_(0), 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_(false), 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_(0), 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_(0), 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_(0), 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_(0) { 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void OnAckNotification(int num_original_packets, 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes, 5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets, 5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_bytes) OVERRIDE { 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK_LT(0, pending_acks_); 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) --pending_acks_; 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_packets_ += num_original_packets; 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_ += num_original_bytes; 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_ += num_retransmitted_packets; 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_ += num_retransmitted_bytes; 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (wrote_last_data_ && pending_acks_ == 0) { 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate_->OnAckNotification(num_original_packets_, 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_original_bytes_, 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_packets_, 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) num_retransmitted_bytes_); 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void WroteData(bool last_data) { 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!wrote_last_data_); 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ++pending_acks_; 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) wrote_last_data_ = last_data; 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) protected: 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Delegates are ref counted. 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~ProxyAckNotifierDelegate() { 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private: 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Original delegate. delegate_->OnAckNotification will be called when: 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // wrote_last_data_ == true and pending_acks_ == 0 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<DelegateInterface> delegate_; 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Number of outstanding acks. 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int pending_acks_; 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // True if no pending writes remain. 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool wrote_last_data_; 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Accumulators. 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_packets_; 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_original_bytes_; 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_packets_; 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int num_retransmitted_bytes_; 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProxyAckNotifierDelegate); 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::PendingData( 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) string data_in, scoped_refptr<ProxyAckNotifierDelegate> delegate_in) 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : data(data_in), delegate(delegate_in) { 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::~PendingData() { 10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::ReliableQuicStream(QuicStreamId id, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicSession* session) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sequencer_(this), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_read_(0), 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_(0), 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_(QUIC_STREAM_NO_ERROR), 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_(QUIC_NO_ERROR), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_(false), 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_side_closed_(false), 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_(false), 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fin_sent_(false), 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_(false), 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) is_server_(session_->is_server()) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::WillAcceptStreamFrame( 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuicStreamFrame& frame) const { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame.stream_id != id_) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error!"; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.WillAcceptStreamFrame(frame); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(frame.stream_id, id_); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't want to be reading: blackhole the data. 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: This count include duplicate data received. 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stream_bytes_read_ += frame.data.TotalBufferSize(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool accepted = sequencer_.OnStreamFrame(frame); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accepted; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) { 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_error_ = frame.error_code; 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error, 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool from_peer) { 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (read_side_closed_ && write_side_closed_) { 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != QUIC_NO_ERROR) { 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = QUIC_STREAM_CONNECTION_ERROR; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_ = error; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::OnFinRead() { 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(sequencer_.IsClosed()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) { 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NE(QUIC_STREAM_NO_ERROR, error); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = error; 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sending a RstStream results in calling CloseStream. 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->SendRstStream(id(), error, stream_bytes_written_); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnection(QuicErrorCode error) { 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionClose(error); 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error, 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const string& details) { 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionCloseWithDetails(error, details); 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicVersion ReliableQuicStream::version() const { 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->connection()->version(); 198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ReliableQuicStream::WriteOrBufferData( 20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece data, 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool fin, 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data.empty() && !fin) { 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "data.empty() && !fin"; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin_buffered_) { 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "Fin already buffered"; 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<ProxyAckNotifierDelegate> proxy_delegate; 21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (ack_notifier_delegate != NULL) { 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate = new ProxyAckNotifierDelegate(ack_notifier_delegate); 21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConsumedData consumed_data(0, false); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_ = fin; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.empty()) { 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov(MakeIovec(data)); 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) consumed_data = WritevData(&iov, 1, fin, proxy_delegate.get()); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(consumed_data.bytes_consumed, data.length()); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool write_completed; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there's unconsumed data or an unconsumed fin, queue it. 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed < data.length() || 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (fin && !consumed_data.fin_consumed)) { 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) StringPiece remainder(data.substr(consumed_data.bytes_consumed)); 23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) queued_data_.push_back(PendingData(remainder.as_string(), proxy_delegate)); 23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = false; 23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) write_completed = true; 23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if ((proxy_delegate.get() != NULL) && 24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed)) { 24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) proxy_delegate->WroteData(write_completed); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin = false; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!queued_data_.empty()) { 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PendingData* pending_data = &queued_data_.front(); 24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ProxyAckNotifierDelegate* delegate = pending_data->delegate.get(); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.size() == 1 && fin_buffered_) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin = true; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) struct iovec iov(MakeIovec(pending_data->data)); 25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicConsumedData consumed_data = WritevData(&iov, 1, fin, delegate); 25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed == pending_data->data.size() && 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin == consumed_data.fin_consumed) { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.pop_front(); 25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(true); 26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumed_data.bytes_consumed > 0) { 26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pending_data->data.erase(0, consumed_data.bytes_consumed); 26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (delegate != NULL) { 26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) delegate->WroteData(false); 26623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 26723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WritevData( 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const struct iovec* iov, 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int iov_count, 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool fin, 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return QuicConsumedData(0, false); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) size_t write_length = 0u; 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < iov_count; ++i) { 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) write_length += iov[i].iov_len; 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(rjshade): Maybe block write based on available flow control window. 287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Fill an IOVector with bytes from the iovec. 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IOVector data; 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data.AppendIovecAtMostBytes(iov, iov_count, write_length); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicConsumedData consumed_data = session()->WritevData( 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) id(), data, stream_bytes_written_, fin, ack_notifier_delegate); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_ += consumed_data.bytes_consumed; 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (consumed_data.bytes_consumed == write_length) { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fin && consumed_data.fin_consumed) { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_sent_ = true; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseWriteSide(); 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (fin && !consumed_data.fin_consumed) { 301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return consumed_data; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_side_closed_) { 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done reading from stream " << id(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_ = true; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (write_side_closed_) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done writing to stream " << id(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_ = true; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ReliableQuicStream::HasBufferedData() { 33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return !queued_data_.empty(); 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() { 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseReadSide(); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseWriteSide(); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (version() > QUIC_VERSION_13 && 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !fin_sent_ && !rst_sent_) { 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, we must tell the peer how many bytes we have 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // written on this stream before termination. Done here if needed, using a 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RST frame. 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_->SendRstStream(id(), QUIC_STREAM_NO_ERROR, stream_bytes_written_); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 355