quic_session.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A QuicSession, which demuxes a single connection to individual streams.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_QUIC_QUIC_SESSION_H_
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_QUIC_QUIC_SESSION_H_
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h"
152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/base/linked_hash_map.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_connection.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_crypto_stream.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_packet_creator.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_protocol.h"
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/quic_spdy_compressor.h"
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/quic_spdy_decompressor.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/reliable_quic_stream.h"
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/spdy/write_blocked_list.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuicCryptoStream;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ReliableQuicStream;
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass SSLInfo;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class VisitorShim;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuicSessionPeer;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CryptoHandshakeEvent enumerates the events generated by a QuicCryptoStream.
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum CryptoHandshakeEvent {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // ENCRYPTION_FIRST_ESTABLISHED indicates that a full client hello has been
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // sent by a client and that subsequent packets will be encrypted. (Client
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // only.)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ENCRYPTION_FIRST_ESTABLISHED,
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // ENCRYPTION_REESTABLISHED indicates that a client hello was rejected by
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the server and thus the encryption key has been updated. Therefore the
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // connection should resend any packets that were sent under
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // ENCRYPTION_INITIAL. (Client only.)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ENCRYPTION_REESTABLISHED,
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // HANDSHAKE_CONFIRMED, in a client, indicates the the server has accepted
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // our handshake. In a server it indicates that a full, valid client hello
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // has been received. (Client and server.)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    HANDSHAKE_CONFIRMED,
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  QuicSession(QuicConnection* connection,
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              const QuicConfig& config,
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              bool is_server);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~QuicSession();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // QuicConnectionVisitorInterface methods:
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual bool OnStreamFrames(
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const std::vector<QuicStreamFrame>& frames) OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE;
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void OnSuccessfulVersionNegotiation(
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const QuicVersion& version) OVERRIDE{}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not needed for HTTP.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool OnCanWrite() OVERRIDE;
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual bool HasPendingHandshake() const OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by streams when they want to write data to the peer.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a pair with the number of bytes consumed from data, and a boolean
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // indicating if the fin bit was consumed.  This does not indicate the data
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // has been sent on the wire: it may have been turned into a packet and queued
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if the socket was unexpectedly blocked.
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual QuicConsumedData WritevData(QuicStreamId id,
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      const struct iovec* iov,
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      int iov_count,
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      QuicStreamOffset offset,
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      bool fin);
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by streams when they want to close the stream in both directions.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when the session wants to go away and not accept any new streams.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SendGoAway(QuicErrorCode error_code, const std::string& reason);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes the stream associated with 'stream_id' from the active stream map.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseStream(QuicStreamId stream_id);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if outgoing packets will be encrypted, even if the server
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // hasn't confirmed the handshake yet.
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsEncryptionEstablished();
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For a client, returns true if the server has confirmed our handshake. For
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // a server, returns true if a full, valid client hello has been received.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool IsCryptoHandshakeConfirmed();
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by the QuicCryptoStream when the handshake enters a new state.
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Clients will call this function in the order:
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   ENCRYPTION_FIRST_ESTABLISHED
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   zero or more ENCRYPTION_REESTABLISHED
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   HANDSHAKE_CONFIRMED
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Servers will simply call it once with HANDSHAKE_CONFIRMED.
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnCryptoHandshakeEvent(CryptoHandshakeEvent event);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Called by the QuicCryptoStream when a handshake message is sent.
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void OnCryptoHandshakeMessageSent(
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const CryptoHandshakeMessage& message);
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Called by the QuicCryptoStream when a handshake message is received.
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void OnCryptoHandshakeMessageReceived(
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const CryptoHandshakeMessage& message);
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Returns mutable config for this session. Returned config is owned
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // by QuicSession.
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicConfig* config();
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the stream existed previously and has been closed.
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns false if the stream is still active or if the stream has
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not yet been created.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsClosedStream(QuicStreamId id);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicConnection* connection() { return connection_.get(); }
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const QuicConnection* connection() const { return connection_.get(); }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t num_active_requests() const { return stream_map_.size(); }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const IPEndPoint& peer_address() const {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return connection_->peer_address();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGuid guid() const { return connection_->guid(); }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicPacketCreator::Options* options() { return connection()->options(); }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of currently open streams, including those which have
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been implicitly created.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual size_t GetNumOpenStreams() const;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void MarkWriteBlocked(QuicStreamId id, QuicPriority priority);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Marks that |stream_id| is blocked waiting to decompress the
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // headers identified by |decompression_id|.
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void MarkDecompressionBlocked(QuicHeaderId decompression_id,
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                QuicStreamId stream_id);
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool goaway_received() const {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return goaway_received_;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool goaway_sent() const {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return goaway_sent_;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  QuicSpdyDecompressor* decompressor() { return &decompressor_; }
158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  QuicSpdyCompressor* compressor() { return &compressor_; }
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Gets the SSL connection information.
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool GetSSLInfo(SSLInfo* ssl_info);
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicErrorCode error() const { return error_; }
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new stream, owned by the caller, to handle a peer-initiated
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // stream.  Returns NULL and does error handling if the stream can not be
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // created.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReliableQuicStream* CreateIncomingReliableStream(QuicStreamId id) = 0;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a new stream, owned by the caller, to handle a locally-initiated
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stream.  Returns NULL if max streams have already been opened.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReliableQuicStream* CreateOutgoingReliableStream() = 0;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the reserved crypto stream.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual QuicCryptoStream* GetCryptoStream() = 0;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds 'stream' to the active stream map.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ActivateStream(ReliableQuicStream* stream);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the stream id for a new stream.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicStreamId GetNextStreamId();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReliableQuicStream* GetIncomingReliableStream(QuicStreamId stream_id);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ReliableQuicStream* GetStream(const QuicStreamId stream_id);
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is called after every call other than OnConnectionClose from the
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // QuicConnectionVisitor to allow post-processing once the work has been done.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In this case, it deletes streams given that it's safe to do so (no other
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // operations are being done on the streams at this time)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void PostProcessAfterData();
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::hash_map<QuicStreamId, ReliableQuicStream*>* streams() {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &stream_map_;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const base::hash_map<QuicStreamId, ReliableQuicStream*>* streams() const {
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return &stream_map_;
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ReliableQuicStream*>* closed_streams() {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &closed_streams_;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t get_max_open_streams() const {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return max_open_streams_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class test::QuicSessionPeer;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class VisitorShim;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::hash_map<QuicStreamId, ReliableQuicStream*> ReliableStreamMap;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Performs the work required to close |stream_id|.  If |locally_reset|
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // then the stream has been reset by this endpoint, not by the peer.  This
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // means the stream may become a zombie stream which needs to stay
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // around until headers have been decompressed.
220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void CloseStreamInner(QuicStreamId stream_id, bool locally_reset);
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Adds |stream_id| to the zobmie stream map, closing the oldest
223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // zombie stream if the set is full.
224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void AddZombieStream(QuicStreamId stream_id);
225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Closes the zombie stream |stream_id| and removes it from the zombie
227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // stream map.
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void CloseZombieStream(QuicStreamId stream_id);
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Adds |stream_id| to the prematurely closed stream map, removing the
231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // oldest prematurely closed stream if the set is full.
232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void AddPrematurelyClosedStream(QuicStreamId stream_id);
233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicConnection> connection_;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Tracks the last 20 streams which closed without decompressing headers.
2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // This is for best-effort detection of an unrecoverable compression context.
2382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Ideally this would be a linked_hash_set as the boolean is unused.
2392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  linked_hash_map<QuicStreamId, bool> prematurely_closed_streams_;
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Streams which have been locally reset before decompressing headers
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // from the peer.  These streams need to stay open long enough to
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // process any headers from the peer.
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Ideally this would be a linked_hash_set as the boolean is unused.
245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  linked_hash_map<QuicStreamId, bool> zombie_streams_;
246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A shim to stand between the connection and the session, to handle stream
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // deletions.
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<VisitorShim> visitor_shim_;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ReliableQuicStream*> closed_streams_;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  QuicSpdyDecompressor decompressor_;
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  QuicSpdyCompressor compressor_;
255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  QuicConfig config_;
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the maximum number of streams this connection can open.
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t max_open_streams_;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map from StreamId to pointers to streams that are owned by the caller.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReliableStreamMap stream_map_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicStreamId next_stream_id_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_server_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set of stream ids that have been "implicitly created" by receipt
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of a stream id larger than the next expected stream id.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::hash_set<QuicStreamId> implicitly_created_streams_;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A list of streams which need to write more data.
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WriteBlockedList<QuicStreamId> write_blocked_streams_;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // A map of headers waiting to be compressed, and the streams
274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // they are associated with.
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  map<uint32, QuicStreamId> decompression_blocked_streams_;
276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicStreamId largest_peer_created_stream_id_;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The latched error with which the connection was closed.
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  QuicErrorCode error_;
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Whether a GoAway has been received.
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool goaway_received_;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Whether a GoAway has been sent.
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool goaway_sent_;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Indicate if there is pending data for the crypto stream.
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool has_pending_handshake_;
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuicSession);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_QUIC_QUIC_SESSION_H_
296