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// A QuicSession, which demuxes a single connection to individual streams.
6
7#ifndef NET_QUIC_QUIC_SESSION_H_
8#define NET_QUIC_QUIC_SESSION_H_
9
10#include <vector>
11
12#include "base/compiler_specific.h"
13#include "base/containers/hash_tables.h"
14#include "net/base/ip_endpoint.h"
15#include "net/quic/quic_connection.h"
16#include "net/quic/quic_crypto_stream.h"
17#include "net/quic/quic_data_stream.h"
18#include "net/quic/quic_headers_stream.h"
19#include "net/quic/quic_packet_creator.h"
20#include "net/quic/quic_protocol.h"
21#include "net/quic/quic_write_blocked_list.h"
22#include "net/quic/reliable_quic_stream.h"
23
24namespace net {
25
26class QuicCryptoStream;
27class QuicFlowController;
28class ReliableQuicStream;
29class SSLInfo;
30class VisitorShim;
31
32namespace test {
33class QuicSessionPeer;
34}  // namespace test
35
36class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
37 public:
38  // CryptoHandshakeEvent enumerates the events generated by a QuicCryptoStream.
39  enum CryptoHandshakeEvent {
40    // ENCRYPTION_FIRST_ESTABLISHED indicates that a full client hello has been
41    // sent by a client and that subsequent packets will be encrypted. (Client
42    // only.)
43    ENCRYPTION_FIRST_ESTABLISHED,
44    // ENCRYPTION_REESTABLISHED indicates that a client hello was rejected by
45    // the server and thus the encryption key has been updated. Therefore the
46    // connection should resend any packets that were sent under
47    // ENCRYPTION_INITIAL. (Client only.)
48    ENCRYPTION_REESTABLISHED,
49    // HANDSHAKE_CONFIRMED, in a client, indicates the the server has accepted
50    // our handshake. In a server it indicates that a full, valid client hello
51    // has been received. (Client and server.)
52    HANDSHAKE_CONFIRMED,
53  };
54
55  QuicSession(QuicConnection* connection, const QuicConfig& config);
56  void InitializeSession();
57
58  virtual ~QuicSession();
59
60  // QuicConnectionVisitorInterface methods:
61  virtual void OnStreamFrames(
62      const std::vector<QuicStreamFrame>& frames) OVERRIDE;
63  virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE;
64  virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE;
65  virtual void OnWindowUpdateFrames(
66      const std::vector<QuicWindowUpdateFrame>& frames) OVERRIDE;
67  virtual void OnBlockedFrames(
68      const std::vector<QuicBlockedFrame>& frames) OVERRIDE;
69  virtual void OnConnectionClosed(QuicErrorCode error, bool from_peer) OVERRIDE;
70  virtual void OnWriteBlocked() OVERRIDE {}
71  virtual void OnSuccessfulVersionNegotiation(
72      const QuicVersion& version) OVERRIDE;
73  virtual void OnCanWrite() OVERRIDE;
74  virtual void OnCongestionWindowChange(QuicTime now) OVERRIDE {}
75  virtual bool WillingAndAbleToWrite() const OVERRIDE;
76  virtual bool HasPendingHandshake() const OVERRIDE;
77  virtual bool HasOpenDataStreams() const OVERRIDE;
78
79  // Called by the headers stream when headers have been received for a stream.
80  virtual void OnStreamHeaders(QuicStreamId stream_id,
81                               base::StringPiece headers_data);
82  // Called by the headers stream when headers with a priority have been
83  // received for this stream.  This method will only be called for server
84  // streams.
85  virtual void OnStreamHeadersPriority(QuicStreamId stream_id,
86                                       QuicPriority priority);
87  // Called by the headers stream when headers have been completely received
88  // for a stream.  |fin| will be true if the fin flag was set in the headers
89  // frame.
90  virtual void OnStreamHeadersComplete(QuicStreamId stream_id,
91                                       bool fin,
92                                       size_t frame_len);
93
94  // Called by streams when they want to write data to the peer.
95  // Returns a pair with the number of bytes consumed from data, and a boolean
96  // indicating if the fin bit was consumed.  This does not indicate the data
97  // has been sent on the wire: it may have been turned into a packet and queued
98  // if the socket was unexpectedly blocked.  |fec_protection| indicates if
99  // data is to be FEC protected. Note that data that is sent immediately
100  // following MUST_FEC_PROTECT data may get protected by falling within the
101  // same FEC group.
102  // If provided, |ack_notifier_delegate| will be registered to be notified when
103  // we have seen ACKs for all packets resulting from this call.
104  virtual QuicConsumedData WritevData(
105      QuicStreamId id,
106      const IOVector& data,
107      QuicStreamOffset offset,
108      bool fin,
109      FecProtection fec_protection,
110      QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
111
112  // Writes |headers| for the stream |id| to the dedicated headers stream.
113  // If |fin| is true, then no more data will be sent for the stream |id|.
114  // If provided, |ack_notifier_delegate| will be registered to be notified when
115  // we have seen ACKs for all packets resulting from this call.
116  size_t WriteHeaders(
117      QuicStreamId id,
118      const SpdyHeaderBlock& headers,
119      bool fin,
120      QuicAckNotifier::DelegateInterface* ack_notifier_delegate);
121
122  // Called by streams when they want to close the stream in both directions.
123  virtual void SendRstStream(QuicStreamId id,
124                             QuicRstStreamErrorCode error,
125                             QuicStreamOffset bytes_written);
126
127  // Called when the session wants to go away and not accept any new streams.
128  void SendGoAway(QuicErrorCode error_code, const std::string& reason);
129
130  // Removes the stream associated with 'stream_id' from the active stream map.
131  virtual void CloseStream(QuicStreamId stream_id);
132
133  // Returns true if outgoing packets will be encrypted, even if the server
134  // hasn't confirmed the handshake yet.
135  virtual bool IsEncryptionEstablished();
136
137  // For a client, returns true if the server has confirmed our handshake. For
138  // a server, returns true if a full, valid client hello has been received.
139  virtual bool IsCryptoHandshakeConfirmed();
140
141  // Called by the QuicCryptoStream when a new QuicConfig has been negotiated.
142  virtual void OnConfigNegotiated();
143
144  // Called by the QuicCryptoStream when the handshake enters a new state.
145  //
146  // Clients will call this function in the order:
147  //   ENCRYPTION_FIRST_ESTABLISHED
148  //   zero or more ENCRYPTION_REESTABLISHED
149  //   HANDSHAKE_CONFIRMED
150  //
151  // Servers will simply call it once with HANDSHAKE_CONFIRMED.
152  virtual void OnCryptoHandshakeEvent(CryptoHandshakeEvent event);
153
154  // Called by the QuicCryptoStream when a handshake message is sent.
155  virtual void OnCryptoHandshakeMessageSent(
156      const CryptoHandshakeMessage& message);
157
158  // Called by the QuicCryptoStream when a handshake message is received.
159  virtual void OnCryptoHandshakeMessageReceived(
160      const CryptoHandshakeMessage& message);
161
162  // Returns mutable config for this session. Returned config is owned
163  // by QuicSession.
164  QuicConfig* config();
165
166  // Returns true if the stream existed previously and has been closed.
167  // Returns false if the stream is still active or if the stream has
168  // not yet been created.
169  bool IsClosedStream(QuicStreamId id);
170
171  QuicConnection* connection() { return connection_.get(); }
172  const QuicConnection* connection() const { return connection_.get(); }
173  size_t num_active_requests() const { return stream_map_.size(); }
174  const IPEndPoint& peer_address() const {
175    return connection_->peer_address();
176  }
177  QuicConnectionId connection_id() const {
178    return connection_->connection_id();
179  }
180
181  // Returns the number of currently open streams, including those which have
182  // been implicitly created, but excluding the reserved headers and crypto
183  // streams.
184  virtual size_t GetNumOpenStreams() const;
185
186  void MarkWriteBlocked(QuicStreamId id, QuicPriority priority);
187
188  // Returns true if the session has data to be sent, either queued in the
189  // connection, or in a write-blocked stream.
190  bool HasDataToWrite() const;
191
192  bool goaway_received() const {
193    return goaway_received_;
194  }
195
196  bool goaway_sent() const {
197    return goaway_sent_;
198  }
199
200  // Gets the SSL connection information.
201  virtual bool GetSSLInfo(SSLInfo* ssl_info) const;
202
203  QuicErrorCode error() const { return error_; }
204
205  bool is_server() const { return connection_->is_server(); }
206
207  QuicFlowController* flow_controller() { return flow_controller_.get(); }
208
209  size_t get_max_open_streams() const { return max_open_streams_; }
210
211 protected:
212  typedef base::hash_map<QuicStreamId, QuicDataStream*> DataStreamMap;
213
214  // Creates a new stream, owned by the caller, to handle a peer-initiated
215  // stream.  Returns NULL and does error handling if the stream can not be
216  // created.
217  virtual QuicDataStream* CreateIncomingDataStream(QuicStreamId id) = 0;
218
219  // Create a new stream, owned by the caller, to handle a locally-initiated
220  // stream.  Returns NULL if max streams have already been opened.
221  virtual QuicDataStream* CreateOutgoingDataStream() = 0;
222
223  // Return the reserved crypto stream.
224  virtual QuicCryptoStream* GetCryptoStream() = 0;
225
226  // Adds 'stream' to the active stream map.
227  virtual void ActivateStream(QuicDataStream* stream);
228
229  // Returns the stream id for a new stream.
230  QuicStreamId GetNextStreamId();
231
232  QuicDataStream* GetIncomingDataStream(QuicStreamId stream_id);
233
234  QuicDataStream* GetDataStream(const QuicStreamId stream_id);
235
236  ReliableQuicStream* GetStream(const QuicStreamId stream_id);
237
238  // This is called after every call other than OnConnectionClose from the
239  // QuicConnectionVisitor to allow post-processing once the work has been done.
240  // In this case, it deletes streams given that it's safe to do so (no other
241  // operations are being done on the streams at this time)
242  virtual void PostProcessAfterData();
243
244  base::hash_map<QuicStreamId, QuicDataStream*>* streams() {
245    return &stream_map_;
246  }
247
248  const base::hash_map<QuicStreamId, QuicDataStream*>* streams() const {
249    return &stream_map_;
250  }
251
252  std::vector<QuicDataStream*>* closed_streams() { return &closed_streams_; }
253
254  void set_max_open_streams(size_t max_open_streams);
255
256  scoped_ptr<QuicHeadersStream> headers_stream_;
257
258 private:
259  friend class test::QuicSessionPeer;
260  friend class VisitorShim;
261
262  // Performs the work required to close |stream_id|.  If |locally_reset|
263  // then the stream has been reset by this endpoint, not by the peer.
264  void CloseStreamInner(QuicStreamId stream_id, bool locally_reset);
265
266  // When a stream is closed locally, it may not yet know how many bytes the
267  // peer sent on that stream.
268  // When this data arrives (via stream frame w. FIN, or RST) this method
269  // is called, and correctly updates the connection level flow controller.
270  void UpdateFlowControlOnFinalReceivedByteOffset(
271      QuicStreamId id, QuicStreamOffset final_byte_offset);
272
273  // Called in OnConfigNegotiated when we receive a new stream level flow
274  // control window in a negotiated config. Closes the connection if invalid.
275  void OnNewStreamFlowControlWindow(uint32 new_window);
276
277  // Called in OnConfigNegotiated when we receive a new session level flow
278  // control window in a negotiated config. Closes the connection if invalid.
279  void OnNewSessionFlowControlWindow(uint32 new_window);
280
281  // Keep track of highest received byte offset of locally closed streams, while
282  // waiting for a definitive final highest offset from the peer.
283  std::map<QuicStreamId, QuicStreamOffset>
284      locally_closed_streams_highest_offset_;
285
286  scoped_ptr<QuicConnection> connection_;
287
288  // A shim to stand between the connection and the session, to handle stream
289  // deletions.
290  scoped_ptr<VisitorShim> visitor_shim_;
291
292  std::vector<QuicDataStream*> closed_streams_;
293
294  QuicConfig config_;
295
296  // Returns the maximum number of streams this connection can open.
297  size_t max_open_streams_;
298
299  // Map from StreamId to pointers to streams that are owned by the caller.
300  DataStreamMap stream_map_;
301  QuicStreamId next_stream_id_;
302
303  // Set of stream ids that have been "implicitly created" by receipt
304  // of a stream id larger than the next expected stream id.
305  base::hash_set<QuicStreamId> implicitly_created_streams_;
306
307  // A list of streams which need to write more data.
308  QuicWriteBlockedList write_blocked_streams_;
309
310  QuicStreamId largest_peer_created_stream_id_;
311
312  // The latched error with which the connection was closed.
313  QuicErrorCode error_;
314
315  // Whether a GoAway has been received.
316  bool goaway_received_;
317  // Whether a GoAway has been sent.
318  bool goaway_sent_;
319
320  // Indicate if there is pending data for the crypto stream.
321  bool has_pending_handshake_;
322
323  // Used for session level flow control.
324  scoped_ptr<QuicFlowController> flow_controller_;
325
326  DISALLOW_COPY_AND_ASSIGN(QuicSession);
327};
328
329}  // namespace net
330
331#endif  // NET_QUIC_QUIC_SESSION_H_
332