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