quic_session.h revision 868fa2fe829687343ffae624259930155e16dbd8
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/hash_tables.h"
14#include "net/base/ip_endpoint.h"
15#include "net/quic/blocked_list.h"
16#include "net/quic/quic_connection.h"
17#include "net/quic/quic_crypto_stream.h"
18#include "net/quic/quic_packet_creator.h"
19#include "net/quic/quic_protocol.h"
20#include "net/quic/quic_spdy_compressor.h"
21#include "net/quic/quic_spdy_decompressor.h"
22#include "net/quic/reliable_quic_stream.h"
23
24namespace net {
25
26class QuicCryptoStream;
27class ReliableQuicStream;
28class VisitorShim;
29
30namespace test {
31class QuicSessionPeer;
32}  // namespace test
33
34class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
35 public:
36  // CryptoHandshakeEvent enumerates the events generated by a QuicCryptoStream.
37  enum CryptoHandshakeEvent {
38    // ENCRYPTION_FIRST_ESTABLISHED indicates that a full client hello has been
39    // sent by a client and that subsequent packets will be encrypted. (Client
40    // only.)
41    ENCRYPTION_FIRST_ESTABLISHED,
42    // ENCRYPTION_REESTABLISHED indicates that a client hello was rejected by
43    // the server and thus the encryption key has been updated. Therefore the
44    // connection should resend any packets that were sent under
45    // ENCRYPTION_INITIAL. (Client only.)
46    ENCRYPTION_REESTABLISHED,
47    // HANDSHAKE_CONFIRMED, in a client, indicates the the server has accepted
48    // our handshake. In a server it indicates that a full, valid client hello
49    // has been received. (Client and server.)
50    HANDSHAKE_CONFIRMED,
51  };
52
53  QuicSession(QuicConnection* connection,
54              const QuicConfig& config,
55              bool is_server);
56
57  virtual ~QuicSession();
58
59  // QuicConnectionVisitorInterface methods:
60  virtual bool OnPacket(const IPEndPoint& self_address,
61                        const IPEndPoint& peer_address,
62                        const QuicPacketHeader& header,
63                        const std::vector<QuicStreamFrame>& frame) OVERRIDE;
64  virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE;
65  virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE;
66  virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE;
67  // Not needed for HTTP.
68  virtual void OnAck(const SequenceNumberSet& acked_packets) OVERRIDE {}
69  virtual bool OnCanWrite() OVERRIDE;
70
71  // Called by streams when they want to write data to the peer.
72  // Returns a pair with the number of bytes consumed from data, and a boolean
73  // indicating if the fin bit was consumed.  This does not indicate the data
74  // has been sent on the wire: it may have been turned into a packet and queued
75  // if the socket was unexpectedly blocked.
76  virtual QuicConsumedData WriteData(QuicStreamId id,
77                                     base::StringPiece data,
78                                     QuicStreamOffset offset,
79                                     bool fin);
80  // Called by streams when they want to close the stream in both directions.
81  virtual void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error);
82
83  // Called when the session wants to go away and not accept any new streams.
84  void SendGoAway(QuicErrorCode error_code, const std::string& reason);
85
86  // Removes the stream associated with 'stream_id' from the active stream map.
87  virtual void CloseStream(QuicStreamId stream_id);
88
89  // Returns true if outgoing packets will be encrypted, even if the server
90  // hasn't confirmed the handshake yet.
91  virtual bool IsEncryptionEstablished();
92
93  // For a client, returns true if the server has confirmed our handshake. For
94  // a server, returns true if a full, valid client hello has been received.
95  virtual bool IsCryptoHandshakeConfirmed();
96
97  // Called by the QuicCryptoStream when the handshake enters a new state.
98  //
99  // Clients will call this function in the order:
100  //   ENCRYPTION_FIRST_ESTABLISHED
101  //   zero or more ENCRYPTION_REESTABLISHED
102  //   HANDSHAKE_CONFIRMED
103  //
104  // Servers will simply call it once with HANDSHAKE_CONFIRMED.
105  virtual void OnCryptoHandshakeEvent(CryptoHandshakeEvent event);
106
107  // Returns mutable config for this session. Returned config is owned
108  // by QuicSession.
109  QuicConfig* config();
110
111  // Returns true if the stream existed previously and has been closed.
112  // Returns false if the stream is still active or if the stream has
113  // not yet been created.
114  bool IsClosedStream(QuicStreamId id);
115
116  QuicConnection* connection() { return connection_.get(); }
117  const QuicConnection* connection() const { return connection_.get(); }
118  size_t num_active_requests() const { return stream_map_.size(); }
119  const IPEndPoint& peer_address() const {
120    return connection_->peer_address();
121  }
122  QuicGuid guid() const { return connection_->guid(); }
123
124  QuicPacketCreator::Options* options() { return connection()->options(); }
125
126  // Returns the number of currently open streams, including those which have
127  // been implicitly created.
128  virtual size_t GetNumOpenStreams() const;
129
130  void MarkWriteBlocked(QuicStreamId id);
131
132  // Marks that |stream_id| is blocked waiting to decompress the
133  // headers identified by |decompression_id|.
134  void MarkDecompressionBlocked(QuicHeaderId decompression_id,
135                                QuicStreamId stream_id);
136
137  bool goaway_received() const {
138    return goaway_received_;
139  }
140
141  bool goaway_sent() const {
142    return goaway_sent_;
143  }
144
145  QuicSpdyDecompressor* decompressor() { return &decompressor_; }
146  QuicSpdyCompressor* compressor() { return &compressor_; }
147
148  QuicErrorCode error() const { return error_; }
149
150 protected:
151  // Creates a new stream, owned by the caller, to handle a peer-initiated
152  // stream.  Returns NULL and does error handling if the stream can not be
153  // created.
154  virtual ReliableQuicStream* CreateIncomingReliableStream(QuicStreamId id) = 0;
155
156  // Create a new stream, owned by the caller, to handle a locally-initiated
157  // stream.  Returns NULL if max streams have already been opened.
158  virtual ReliableQuicStream* CreateOutgoingReliableStream() = 0;
159
160  // Return the reserved crypto stream.
161  virtual QuicCryptoStream* GetCryptoStream() = 0;
162
163  // Adds 'stream' to the active stream map.
164  virtual void ActivateStream(ReliableQuicStream* stream);
165
166  // Returns the stream id for a new stream.
167  QuicStreamId GetNextStreamId();
168
169  ReliableQuicStream* GetIncomingReliableStream(QuicStreamId stream_id);
170
171  // This is called after every call other than OnConnectionClose from the
172  // QuicConnectionVisitor to allow post-processing once the work has been done.
173  // In this case, it deletes streams given that it's safe to do so (no other
174  // operations are being done on the streams at this time)
175  virtual void PostProcessAfterData();
176
177  base::hash_map<QuicStreamId, ReliableQuicStream*>* streams() {
178    return &stream_map_;
179  }
180
181  const base::hash_map<QuicStreamId, ReliableQuicStream*>* streams() const {
182    return &stream_map_;
183  }
184
185  std::vector<ReliableQuicStream*>* closed_streams() {
186    return &closed_streams_;
187  }
188
189  size_t get_max_open_streams() const {
190    return max_open_streams_;
191  }
192
193  void set_max_open_streams(size_t max_open_streams) {
194    max_open_streams_ = max_open_streams;
195  }
196
197 private:
198  friend class test::QuicSessionPeer;
199  friend class VisitorShim;
200
201  typedef base::hash_map<QuicStreamId, ReliableQuicStream*> ReliableStreamMap;
202
203  ReliableQuicStream* GetStream(const QuicStreamId stream_id);
204
205  scoped_ptr<QuicConnection> connection_;
206
207  // A shim to stand between the connection and the session, to handle stream
208  // deletions.
209  scoped_ptr<VisitorShim> visitor_shim_;
210
211  std::vector<ReliableQuicStream*> closed_streams_;
212
213  QuicSpdyDecompressor decompressor_;
214  QuicSpdyCompressor compressor_;
215
216  QuicConfig config_;
217
218  // Returns the maximum number of streams this connection can open.
219  size_t max_open_streams_;
220
221  // Map from StreamId to pointers to streams that are owned by the caller.
222  ReliableStreamMap stream_map_;
223  QuicStreamId next_stream_id_;
224  bool is_server_;
225
226  // Set of stream ids that have been "implicitly created" by receipt
227  // of a stream id larger than the next expected stream id.
228  base::hash_set<QuicStreamId> implicitly_created_streams_;
229
230  // A list of streams which need to write more data.
231  BlockedList<QuicStreamId> write_blocked_streams_;
232
233  // A map of headers waiting to be compressed, and the streams
234  // they are associated with.
235  map<uint32, QuicStreamId> decompression_blocked_streams_;
236
237  QuicStreamId largest_peer_created_stream_id_;
238
239  // The latched error with which the connection was closed.
240  QuicErrorCode error_;
241
242  // Whether a GoAway has been received.
243  bool goaway_received_;
244  // Whether a GoAway has been sent.
245  bool goaway_sent_;
246
247  DISALLOW_COPY_AND_ASSIGN(QuicSession);
248};
249
250}  // namespace net
251
252#endif  // NET_QUIC_QUIC_SESSION_H_
253