reliable_quic_stream.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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" 9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/quic_spdy_decompressor.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ENDPOINT (is_server_ ? "Server: " : " Client: ") 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct iovec MakeIovec(StringPiece data) { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov = {const_cast<char*>(data.data()), 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<size_t>(data.size())}; 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return iov; 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::ReliableQuicStream(QuicStreamId id, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicSession* session) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sequencer_(this), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_read_(0), 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_(0), 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_(QUIC_STREAM_NO_ERROR), 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_(QUIC_NO_ERROR), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_(false), 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) write_side_closed_(false), 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_(false), 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) fin_sent_(false), 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_(false), 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) is_server_(session_->is_server()) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::WillAcceptStreamFrame( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuicStreamFrame& frame) const { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame.stream_id != id_) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error!"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.WillAcceptStreamFrame(frame); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(frame.stream_id, id_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't want to be reading: blackhole the data. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note: This count include duplicate data received. 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) stream_bytes_read_ += frame.data.TotalBufferSize(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool accepted = sequencer_.OnStreamFrame(frame); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accepted; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_error_ = frame.error_code; 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error, 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool from_peer) { 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (read_side_closed_ && write_side_closed_) { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != QUIC_NO_ERROR) { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = QUIC_STREAM_CONNECTION_ERROR; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection_error_ = error; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseWriteSide(); 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CloseReadSide(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::OnFinRead() { 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(sequencer_.IsClosed()); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) { 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NE(QUIC_STREAM_NO_ERROR, error); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_error_ = error; 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Sending a RstStream results in calling CloseStream. 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->SendRstStream(id(), error, stream_bytes_written_); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnection(QuicErrorCode error) { 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionClose(error); 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error, 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const string& details) { 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) session()->connection()->SendConnectionCloseWithDetails(error, details); 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicVersion ReliableQuicStream::version() { 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->connection()->version(); 120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::WriteOrBufferData(StringPiece data, bool fin) { 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data.empty() && !fin) { 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "data.empty() && !fin"; 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin_buffered_) { 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "Fin already buffered"; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) QuicConsumedData consumed_data(0, false); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_buffered_ = fin; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.empty()) { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov(MakeIovec(data)); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumed_data = WritevData(&iov, 1, fin, NULL); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(consumed_data.bytes_consumed, data.length()); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there's unconsumed data or an unconsumed fin, queue it. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed < data.length() || 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (fin && !consumed_data.fin_consumed)) { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.push_back( 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string(data.data() + consumed_data.bytes_consumed, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data.length() - consumed_data.bytes_consumed)); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin = false; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!queued_data_.empty()) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string& data = queued_data_.front(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (queued_data_.size() == 1 && fin_buffered_) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin = true; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iov(MakeIovec(data)); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicConsumedData consumed_data = WritevData(&iov, 1, fin, NULL); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed == data.size() && 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin == consumed_data.fin_consumed) { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.pop_front(); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_data_.front().erase(0, consumed_data.bytes_consumed); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WritevData( 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const struct iovec* iov, 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int iov_count, 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool fin, 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return QuicConsumedData(0, false); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) size_t write_length = 0u; 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < iov_count; ++i) { 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) write_length += iov[i].iov_len; 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicConsumedData consumed_data = session()->WritevData( 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) id(), iov, iov_count, stream_bytes_written_, fin, ack_notifier_delegate); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_bytes_written_ += consumed_data.bytes_consumed; 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (consumed_data.bytes_consumed == write_length) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fin && consumed_data.fin_consumed) { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_sent_ = true; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseWriteSide(); 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (fin && !consumed_data.fin_consumed) { 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return consumed_data; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_side_closed_) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done reading from stream " << id(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_side_closed_ = true; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (write_side_closed_) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Done writing to stream " << id(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_ = true; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << ENDPOINT << "Closing stream: " << id(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ReliableQuicStream::HasBufferedData() { 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return !queued_data_.empty(); 22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() { 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseReadSide(); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloseWriteSide(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (version() > QUIC_VERSION_13 && 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !fin_sent_ && !rst_sent_) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For flow control accounting, we must tell the peer how many bytes we have 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // written on this stream before termination. Done here if needed, using a 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RST frame. 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_->SendRstStream(id(), QUIC_STREAM_NO_ERROR, stream_bytes_written_); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rst_sent_ = true; 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 246