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