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