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