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)
286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)size_t GetInitialStreamFlowControlWindowToSend(QuicSession* session) {
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  QuicVersion version = session->connection()->version();
306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (version <= QUIC_VERSION_19) {
316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return session->config()->GetInitialFlowControlWindowToSend();
326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return session->config()->GetInitialStreamFlowControlWindowToSend();
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)size_t GetReceivedFlowControlWindow(QuicSession* session) {
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  QuicVersion version = session->connection()->version();
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (version <= QUIC_VERSION_19) {
406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (session->config()->HasReceivedInitialFlowControlWindowBytes()) {
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      return session->config()->ReceivedInitialFlowControlWindowBytes();
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return kDefaultFlowControlSendWindow;
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Version must be >= QUIC_VERSION_21, so we check for stream specific flow
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // control window.
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (session->config()->HasReceivedInitialStreamFlowControlWindowBytes()) {
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return session->config()->ReceivedInitialStreamFlowControlWindowBytes();
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return kDefaultFlowControlSendWindow;
546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Wrapper that aggregates OnAckNotifications for packets sent using
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData and delivers them to the original
6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// QuicAckNotifier::DelegateInterface after all bytes written using
6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData are acked.  This level of indirection is
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// necessary because the delegate interface provides no mechanism that
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// WriteOrBufferData can use to inform it that the write required
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// multiple WritevData calls or that only part of the data has been
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// sent out by the time ACKs start arriving.
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class ReliableQuicStream::ProxyAckNotifierDelegate
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : public QuicAckNotifier::DelegateInterface {
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public:
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  explicit ProxyAckNotifierDelegate(DelegateInterface* delegate)
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      : delegate_(delegate),
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        pending_acks_(0),
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        wrote_last_data_(false),
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        num_original_packets_(0),
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        num_original_bytes_(0),
7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        num_retransmitted_packets_(0),
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        num_retransmitted_bytes_(0) {
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void OnAckNotification(int num_original_packets,
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 int num_original_bytes,
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 int num_retransmitted_packets,
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 int num_retransmitted_bytes,
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                 QuicTime::Delta delta_largest_observed)
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      OVERRIDE {
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK_LT(0, pending_acks_);
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    --pending_acks_;
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    num_original_packets_ += num_original_packets;
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    num_original_bytes_ += num_original_bytes;
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    num_retransmitted_packets_ += num_retransmitted_packets;
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    num_retransmitted_bytes_ += num_retransmitted_bytes;
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (wrote_last_data_ && pending_acks_ == 0) {
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      delegate_->OnAckNotification(num_original_packets_,
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                   num_original_bytes_,
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                   num_retransmitted_packets_,
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   num_retransmitted_bytes_,
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   delta_largest_observed);
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void WroteData(bool last_data) {
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(!wrote_last_data_);
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ++pending_acks_;
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    wrote_last_data_ = last_data;
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) protected:
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Delegates are ref counted.
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~ProxyAckNotifierDelegate() OVERRIDE {
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private:
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Original delegate.  delegate_->OnAckNotification will be called when:
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  //   wrote_last_data_ == true and pending_acks_ == 0
11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<DelegateInterface> delegate_;
11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Number of outstanding acks.
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int pending_acks_;
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // True if no pending writes remain.
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool wrote_last_data_;
12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Accumulators.
12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int num_original_packets_;
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int num_original_bytes_;
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int num_retransmitted_packets_;
12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int num_retransmitted_bytes_;
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProxyAckNotifierDelegate);
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::PendingData(
13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    string data_in, scoped_refptr<ProxyAckNotifierDelegate> delegate_in)
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : data(data_in), delegate(delegate_in) {
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ReliableQuicStream::PendingData::~PendingData() {
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochReliableQuicStream::ReliableQuicStream(QuicStreamId id, QuicSession* session)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sequencer_(this),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_(id),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_(session),
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stream_bytes_read_(0),
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stream_bytes_written_(0),
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_error_(QUIC_STREAM_NO_ERROR),
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      connection_error_(QUIC_NO_ERROR),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_side_closed_(false),
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      write_side_closed_(false),
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin_buffered_(false),
1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      fin_sent_(false),
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      fin_received_(false),
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      rst_sent_(false),
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rst_received_(false),
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      fec_policy_(FEC_PROTECT_OPTIONAL),
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      is_server_(session_->is_server()),
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      flow_controller_(
1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          session_->connection(), id_, is_server_,
1596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          GetReceivedFlowControlWindow(session),
1606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          GetInitialStreamFlowControlWindowToSend(session),
1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          GetInitialStreamFlowControlWindowToSend(session)),
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      connection_flow_controller_(session_->flow_controller()),
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      stream_contributes_to_connection_flow_control_(true) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_side_closed_) {
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DVLOG(1) << ENDPOINT << "Ignoring frame " << frame.stream_id;
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // We don't want to be reading: blackhole the data.
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (frame.stream_id != id_) {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    session_->connection()->SendConnectionClose(QUIC_INTERNAL_ERROR);
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (frame.fin) {
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    fin_received_ = true;
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
185e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // This count include duplicate data received.
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t frame_payload_size = frame.data.TotalBufferSize();
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  stream_bytes_read_ += frame_payload_size;
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Flow control is interested in tracking highest received offset.
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // As the highest received offset has changed, we should check to see if
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // this is a violation of flow control.
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (flow_controller_.FlowControlViolation() ||
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        connection_flow_controller_->FlowControlViolation()) {
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      session_->connection()->SendConnectionClose(
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA);
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sequencer_.OnStreamFrame(frame);
202e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
203e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ReliableQuicStream::num_frames_received() const {
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return sequencer_.num_frames_received();
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ReliableQuicStream::num_duplicate_frames_received() const {
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return sequencer_.num_duplicate_frames_received();
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(const QuicRstStreamFrame& frame) {
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  rst_received_ = true;
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_error_ = frame.error_code;
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CloseWriteSide();
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CloseReadSide();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::OnConnectionClosed(QuicErrorCode error,
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                            bool from_peer) {
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (read_side_closed_ && write_side_closed_) {
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != QUIC_NO_ERROR) {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    stream_error_ = QUIC_STREAM_CONNECTION_ERROR;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    connection_error_ = error;
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CloseWriteSide();
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CloseReadSide();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::OnFinRead() {
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(sequencer_.IsClosed());
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  fin_received_ = true;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloseReadSide();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ReliableQuicStream::Reset(QuicRstStreamErrorCode error) {
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_NE(QUIC_STREAM_NO_ERROR, error);
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_error_ = error;
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Sending a RstStream results in calling CloseStream.
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  session()->SendRstStream(id(), error, stream_bytes_written_);
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rst_sent_ = true;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnection(QuicErrorCode error) {
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  session()->connection()->SendConnectionClose(error);
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ReliableQuicStream::CloseConnectionWithDetails(QuicErrorCode error,
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                    const string& details) {
2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  session()->connection()->SendConnectionCloseWithDetails(error, details);
2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicVersion ReliableQuicStream::version() const {
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return session()->connection()->version();
260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
261b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ReliableQuicStream::WriteOrBufferData(
26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    StringPiece data,
26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool fin,
26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (data.empty() && !fin) {
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(DFATAL) << "data.empty() && !fin";
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (fin_buffered_) {
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(DFATAL) << "Fin already buffered";
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<ProxyAckNotifierDelegate> proxy_delegate;
27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (ack_notifier_delegate != NULL) {
27823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    proxy_delegate = new ProxyAckNotifierDelegate(ack_notifier_delegate);
27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
28023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed_data(0, false);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fin_buffered_ = fin;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (queued_data_.empty()) {
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    struct iovec iov(MakeIovec(data));
28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    consumed_data = WritevData(&iov, 1, fin, proxy_delegate.get());
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_LE(consumed_data.bytes_consumed, data.length());
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool write_completed;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there's unconsumed data or an unconsumed fin, queue it.
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (consumed_data.bytes_consumed < data.length() ||
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (fin && !consumed_data.fin_consumed)) {
29423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    StringPiece remainder(data.substr(consumed_data.bytes_consumed));
29523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    queued_data_.push_back(PendingData(remainder.as_string(), proxy_delegate));
29623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    write_completed = false;
29723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
29823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    write_completed = true;
29923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if ((proxy_delegate.get() != NULL) &&
30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      (consumed_data.bytes_consumed > 0 || consumed_data.fin_consumed)) {
30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    proxy_delegate->WroteData(write_completed);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool fin = false;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (!queued_data_.empty()) {
31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    PendingData* pending_data = &queued_data_.front();
31123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ProxyAckNotifierDelegate* delegate = pending_data->delegate.get();
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_data_.size() == 1 && fin_buffered_) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin = true;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
31523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    struct iovec iov(MakeIovec(pending_data->data));
31623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    QuicConsumedData consumed_data = WritevData(&iov, 1, fin, delegate);
31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (consumed_data.bytes_consumed == pending_data->data.size() &&
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fin == consumed_data.fin_consumed) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_data_.pop_front();
32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (delegate != NULL) {
32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        delegate->WroteData(true);
32223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
32423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (consumed_data.bytes_consumed > 0) {
32523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        pending_data->data.erase(0, consumed_data.bytes_consumed);
32623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        if (delegate != NULL) {
32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          delegate->WroteData(false);
32823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        }
32923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::MaybeSendBlocked() {
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  flow_controller_.MaybeSendBlocked();
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!stream_contributes_to_connection_flow_control_) {
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connection_flow_controller_->MaybeSendBlocked();
341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // If we are connection level flow control blocked, then add the stream
342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to the write blocked list. It will be given a chance to write when a
343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // connection level WINDOW_UPDATE arrives.
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (connection_flow_controller_->IsBlocked() &&
345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !flow_controller_.IsBlocked()) {
346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    session_->MarkWriteBlocked(id(), EffectivePriority());
347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WritevData(
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const struct iovec* iov,
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int iov_count,
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool fin,
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_side_closed_) {
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed";
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return QuicConsumedData(0, false);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
360e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // How much data we want to write.
361e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  size_t write_length = TotalIovecLength(iov, iov_count);
362e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
363e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // A FIN with zero data payload should not be flow control blocked.
364e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool fin_with_zero_data = (fin && write_length == 0);
365e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (flow_controller_.IsEnabled()) {
3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // How much data we are allowed to write from flow control.
368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    uint64 send_window = flow_controller_.SendWindowSize();
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // removing QUIC_VERSION_19.
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (stream_contributes_to_connection_flow_control_ &&
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        connection_flow_controller_->IsEnabled()) {
373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      send_window =
374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          min(send_window, connection_flow_controller_->SendWindowSize());
375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
3765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
377e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (send_window == 0 && !fin_with_zero_data) {
378e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // Quick return if we can't send anything.
379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      MaybeSendBlocked();
380e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return QuicConsumedData(0, false);
381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
382e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
383e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (write_length > send_window) {
384e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // Don't send the FIN if we aren't going to send all the data.
385e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      fin = false;
386e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
387e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // Writing more data would be a violation of flow control.
388e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      write_length = send_window;
389e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Fill an IOVector with bytes from the iovec.
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  IOVector data;
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data.AppendIovecAtMostBytes(iov, iov_count, write_length);
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  QuicConsumedData consumed_data = session()->WritevData(
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      id(), data, stream_bytes_written_, fin, GetFecProtection(),
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ack_notifier_delegate);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_bytes_written_ += consumed_data.bytes_consumed;
400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AddBytesSent(consumed_data.bytes_consumed);
4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (consumed_data.bytes_consumed == write_length) {
4040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!fin_with_zero_data) {
405010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      MaybeSendBlocked();
406e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (fin && consumed_data.fin_consumed) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin_sent_ = true;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CloseWriteSide();
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (fin && !consumed_data.fin_consumed) {
411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      session_->MarkWriteBlocked(id(), EffectivePriority());
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    session_->MarkWriteBlocked(id(), EffectivePriority());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return consumed_data;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)FecProtection ReliableQuicStream::GetFecProtection() {
420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return fec_policy_ == FEC_PROTECT_ALWAYS ? MUST_FEC_PROTECT : MAY_FEC_PROTECT;
421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (read_side_closed_) {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_side_closed_ = true;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_side_closed_) {
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << ENDPOINT << "Closing stream: " << id();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->CloseStream(id());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (write_side_closed_) {
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_side_closed_ = true;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_side_closed_) {
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(1) << ENDPOINT << "Closing stream: " << id();
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->CloseStream(id());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
449010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ReliableQuicStream::HasBufferedData() const {
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return !queued_data_.empty();
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() {
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CloseReadSide();
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CloseWriteSide();
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!fin_sent_ && !rst_sent_) {
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // For flow control accounting, we must tell the peer how many bytes we have
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // written on this stream before termination. Done here if needed, using a
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // RST frame.
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id();
4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    session_->SendRstStream(id(), QUIC_RST_FLOW_CONTROL_ACCOUNTING,
4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            stream_bytes_written_);
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rst_sent_ = true;
465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // We are closing the stream and will not process any further incoming bytes.
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // As there may be more bytes in flight and we need to ensure that both
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // endpoints have the same connection level flow control state, mark all
47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // unreceived or buffered bytes as consumed.
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint64 bytes_to_consume = flow_controller_.highest_received_byte_offset() -
47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      flow_controller_.bytes_consumed();
47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AddBytesConsumed(bytes_to_consume);
474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
476e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ReliableQuicStream::OnWindowUpdateFrame(
477e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const QuicWindowUpdateFrame& frame) {
4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!flow_controller_.IsEnabled()) {
479e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    DLOG(DFATAL) << "Flow control not enabled! " << version();
480e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
481e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) {
4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // We can write again!
4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // TODO(rjshade): This does not respect priorities (e.g. multiple
4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    //                outstanding POSTs are unblocked on arrival of
4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    //                SHLO with initial window).
487010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // As long as the connection is not flow control blocked, we can write!
4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    OnCanWrite();
489e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
490e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
491e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) {
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!flow_controller_.IsEnabled()) {
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
495010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uint64 increment =
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new_offset - flow_controller_.highest_received_byte_offset();
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If |new_offset| increased the stream flow controller's highest received
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // offset, then we need to increase the connection flow controller's value
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // by the incremental difference.
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (stream_contributes_to_connection_flow_control_) {
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection_flow_controller_->UpdateHighestReceivedOffset(
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        connection_flow_controller_->highest_received_byte_offset() +
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        increment);
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::AddBytesSent(uint64 bytes) {
514010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (flow_controller_.IsEnabled()) {
515010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    flow_controller_.AddBytesSent(bytes);
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (stream_contributes_to_connection_flow_control_) {
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      connection_flow_controller_->AddBytesSent(bytes);
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ReliableQuicStream::AddBytesConsumed(uint64 bytes) {
523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (flow_controller_.IsEnabled()) {
52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Only adjust stream level flow controller if we are still reading.
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!read_side_closed_) {
52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      flow_controller_.AddBytesConsumed(bytes);
52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (stream_contributes_to_connection_flow_control_) {
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      connection_flow_controller_->AddBytesConsumed(bytes);
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochvoid ReliableQuicStream::UpdateSendWindowOffset(uint64 new_window) {
5361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (flow_controller_.UpdateSendWindowOffset(new_window)) {
5371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    OnCanWrite();
5381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
5391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch}
5401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ReliableQuicStream::IsFlowControlBlocked() {
5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (flow_controller_.IsBlocked()) {
5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return stream_contributes_to_connection_flow_control_ &&
546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      connection_flow_controller_->IsBlocked();
547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
550