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