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