1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The base class for client/server reliable streams.
#ifndef NET_QUIC_RELIABLE_QUIC_STREAM_H_
#define NET_QUIC_RELIABLE_QUIC_STREAM_H_
#include <sys/types.h>
#include <list>
#include <string>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "net/base/iovec.h"
#include "net/base/net_export.h"
#include "net/quic/quic_ack_notifier.h"
#include "net/quic/quic_flow_controller.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_stream_sequencer.h"
#include "net/quic/quic_types.h"
namespace net {
namespace test {
class ReliableQuicStreamPeer;
} // namespace test
class QuicSession;
class NET_EXPORT_PRIVATE ReliableQuicStream {
public:
ReliableQuicStream(QuicStreamId id,
QuicSession* session);
virtual ~ReliableQuicStream();
// Called when a (potentially duplicate) stream frame has been received
// for this stream.
virtual void OnStreamFrame(const QuicStreamFrame& frame);
// Called when the connection becomes writeable to allow the stream
// to write any pending data.
virtual void OnCanWrite();
// Called by the session just before the stream is deleted.
virtual void OnClose();
// Called when we get a stream reset from the peer.
virtual void OnStreamReset(const QuicRstStreamFrame& frame);
// Called when we get or send a connection close, and should immediately
// close the stream. This is not passed through the sequencer,
// but is handled immediately.
virtual void OnConnectionClosed(QuicErrorCode error, bool from_peer);
// Called when the final data has been read.
virtual void OnFinRead();
virtual uint32 ProcessRawData(const char* data, uint32 data_len) = 0;
// Called to reset the stream from this end.
virtual void Reset(QuicRstStreamErrorCode error);
// Called to close the entire connection from this end.
virtual void CloseConnection(QuicErrorCode error);
virtual void CloseConnectionWithDetails(QuicErrorCode error,
const std::string& details);
// Returns the effective priority for the stream. This value may change
// during the life of the stream.
virtual QuicPriority EffectivePriority() const = 0;
QuicStreamId id() const { return id_; }
QuicRstStreamErrorCode stream_error() const { return stream_error_; }
QuicErrorCode connection_error() const { return connection_error_; }
bool read_side_closed() const { return read_side_closed_; }
bool write_side_closed() const { return write_side_closed_; }
uint64 stream_bytes_read() const { return stream_bytes_read_; }
uint64 stream_bytes_written() const { return stream_bytes_written_; }
QuicVersion version() const;
void set_fin_sent(bool fin_sent) { fin_sent_ = fin_sent; }
void set_rst_sent(bool rst_sent) { rst_sent_ = rst_sent; }
void set_fec_policy(FecPolicy fec_policy) { fec_policy_ = fec_policy; }
FecPolicy fec_policy() const { return fec_policy_; }
// Adjust our flow control windows according to new offset in |frame|.
virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);
int num_frames_received() const;
int num_early_frames_received() const;
int num_duplicate_frames_received() const;
QuicFlowController* flow_controller() { return &flow_controller_; }
// Called when we see a frame which could increase the highest offset.
// Returns true if the highest offset did increase.
bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);
// Called when bytese are sent to the peer.
void AddBytesSent(QuicByteCount bytes);
// Called by the stream sequencer as bytes are consumed from the buffer.
// If our receive window has dropped below the threshold, then send a
// WINDOW_UPDATE frame.
void AddBytesConsumed(QuicByteCount bytes);
// Updates the flow controller's send window offset and calls OnCanWrite if
// it was blocked before.
void UpdateSendWindowOffset(QuicStreamOffset new_offset);
// Returns true if the stream is flow control blocked, by the stream flow
// control window or the connection flow control window.
bool IsFlowControlBlocked();
// Returns true if we have received either a RST or a FIN - either of which
// gives a definitive number of bytes which the peer has sent. If this is not
// true on stream termination the session must keep track of the stream's byte
// offset until a definitive final value arrives.
bool HasFinalReceivedByteOffset() const {
return fin_received_ || rst_received_;
}
// Returns true if the stream has queued data waiting to write.
bool HasBufferedData() const;
protected:
// Sends as much of 'data' to the connection as the connection will consume,
// and then buffers any remaining data in queued_data_.
void WriteOrBufferData(
base::StringPiece data,
bool fin,
QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
// Sends as many bytes in the first |count| buffers of |iov| to the connection
// as the connection will consume.
// If |ack_notifier_delegate| is provided, then it will be notified once all
// the ACKs for this write have been received.
// Returns the number of bytes consumed by the connection.
QuicConsumedData WritevData(
const struct iovec* iov,
int iov_count,
bool fin,
QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
// Helper method that returns FecProtection to use for writes to the session.
FecProtection GetFecProtection();
// Close the read side of the socket. Further frames will not be accepted.
virtual void CloseReadSide();
// Close the write side of the socket. Further writes will fail.
void CloseWriteSide();
bool fin_buffered() const { return fin_buffered_; }
const QuicSession* session() const { return session_; }
QuicSession* session() { return session_; }
const QuicStreamSequencer* sequencer() const { return &sequencer_; }
QuicStreamSequencer* sequencer() { return &sequencer_; }
void DisableConnectionFlowControlForThisStream() {
stream_contributes_to_connection_flow_control_ = false;
}
private:
friend class test::ReliableQuicStreamPeer;
friend class QuicStreamUtils;
class ProxyAckNotifierDelegate;
struct PendingData {
PendingData(std::string data_in,
scoped_refptr<ProxyAckNotifierDelegate> delegate_in);
~PendingData();
std::string data;
// Delegate that should be notified when the pending data is acked.
// Can be nullptr.
scoped_refptr<ProxyAckNotifierDelegate> delegate;
};
// Calls MaybeSendBlocked on our flow controller, and connection level flow
// controller. If we are flow control blocked, marks this stream as write
// blocked.
void MaybeSendBlocked();
std::list<PendingData> queued_data_;
QuicStreamSequencer sequencer_;
QuicStreamId id_;
QuicSession* session_;
// Bytes read and written refer to payload bytes only: they do not include
// framing, encryption overhead etc.
uint64 stream_bytes_read_;
uint64 stream_bytes_written_;
// Stream error code received from a RstStreamFrame or error code sent by the
// visitor or sequencer in the RstStreamFrame.
QuicRstStreamErrorCode stream_error_;
// Connection error code due to which the stream was closed. |stream_error_|
// is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
// should check |connection_error_|.
QuicErrorCode connection_error_;
// True if the read side is closed and further frames should be rejected.
bool read_side_closed_;
// True if the write side is closed, and further writes should fail.
bool write_side_closed_;
bool fin_buffered_;
bool fin_sent_;
// True if this stream has received (and the sequencer has accepted) a
// StreamFrame with the FIN set.
bool fin_received_;
// In combination with fin_sent_, used to ensure that a FIN and/or a RST is
// always sent before stream termination.
bool rst_sent_;
// True if this stream has received a RST stream frame.
bool rst_received_;
// FEC policy to be used for this stream.
FecPolicy fec_policy_;
// True if the session this stream is running under is a server session.
bool is_server_;
QuicFlowController flow_controller_;
// The connection level flow controller. Not owned.
QuicFlowController* connection_flow_controller_;
// Special streams, such as the crypto and headers streams, do not respect
// connection level flow control limits (but are stream level flow control
// limited).
bool stream_contributes_to_connection_flow_control_;
DISALLOW_COPY_AND_ASSIGN(ReliableQuicStream);
};
} // namespace net
#endif // NET_QUIC_RELIABLE_QUIC_STREAM_H_
|