reliable_quic_stream.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/reliable_quic_stream.h"
6
7#include "net/quic/quic_session.h"
8
9using base::StringPiece;
10
11namespace net {
12
13ReliableQuicStream::ReliableQuicStream(QuicStreamId id,
14                                       QuicSession* session)
15    : sequencer_(this),
16      id_(id),
17      offset_(0),
18      session_(session),
19      error_(QUIC_NO_ERROR),
20      read_side_closed_(false),
21      write_side_closed_(false) {
22}
23
24ReliableQuicStream::~ReliableQuicStream() {
25}
26
27bool ReliableQuicStream::WillAcceptStreamFrame(
28    const QuicStreamFrame& frame) const {
29  if (read_side_closed_) {
30    return false;
31  }
32  if (frame.stream_id != id_) {
33    LOG(ERROR) << "Error!";
34    return false;
35  }
36  return sequencer_.WillAcceptStreamFrame(frame);
37}
38
39bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
40  DCHECK_EQ(frame.stream_id, id_);
41  if (read_side_closed_) {
42    // This can only happen if a client sends data after sending a fin or stream
43    // reset.
44    Close(QUIC_STREAM_DATA_AFTER_TERMINATION);
45    return false;
46  }
47
48  bool accepted = sequencer_.OnStreamFrame(frame);
49
50  if (frame.fin) {
51    sequencer_.CloseStreamAtOffset(frame.offset + frame.data.size(),
52                                   true);
53  }
54
55  return accepted;
56}
57
58void ReliableQuicStream::OnStreamReset(QuicErrorCode error,
59                                       QuicStreamOffset offset) {
60  error_ = error;
61  sequencer_.CloseStreamAtOffset(offset, false);  // Full close.
62}
63
64void ReliableQuicStream::ConnectionClose(QuicErrorCode error, bool from_peer) {
65  error_ = error;
66  if (from_peer) {
67    TerminateFromPeer(false);
68  } else {
69    CloseWriteSide();
70    CloseReadSide();
71  }
72}
73
74void ReliableQuicStream::TerminateFromPeer(bool half_close) {
75  if (!half_close) {
76    CloseWriteSide();
77  }
78  CloseReadSide();
79}
80
81void ReliableQuicStream::Close(QuicErrorCode error) {
82  error_ = error;
83  session()->SendRstStream(id(), error, offset_);
84}
85
86bool ReliableQuicStream::IsHalfClosed() const {
87  return sequencer_.IsHalfClosed();
88}
89
90bool ReliableQuicStream::HasBytesToRead() const {
91  return sequencer_.HasBytesToRead();
92}
93
94int ReliableQuicStream::WriteData(StringPiece data, bool fin) {
95  if (write_side_closed_) {
96    DLOG(ERROR) << "Attempt to write when the write side is closed";
97    return 0;
98  }
99
100  session()->WriteData(id(), data, offset_, fin);
101  offset_ += data.length();
102  if (fin) {
103    CloseWriteSide();
104  }
105  return data.length();
106}
107
108void ReliableQuicStream::CloseReadSide() {
109  DLOG(INFO) << "Done reading from stream " << id();
110
111  read_side_closed_ = true;
112  if (write_side_closed_) {
113    session_->CloseStream(id());
114  }
115}
116
117void ReliableQuicStream::CloseWriteSide() {
118  DLOG(INFO) << "Done writing to stream " << id();
119
120  write_side_closed_ = true;
121  if (read_side_closed_) {
122    session_->CloseStream(id());
123  }
124}
125
126}  // namespace net
127