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; OnWriteBlocked()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 connection()170 QuicConnection* connection() { return connection_.get(); } connection()171 const QuicConnection* connection() const { return connection_.get(); } num_active_requests()172 size_t num_active_requests() const { return stream_map_.size(); } peer_address()173 const IPEndPoint& peer_address() const { 174 return connection_->peer_address(); 175 } connection_id()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 goaway_received()191 bool goaway_received() const { 192 return goaway_received_; 193 } 194 goaway_sent()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 error()202 QuicErrorCode error() const { return error_; } 203 is_server()204 bool is_server() const { return connection_->is_server(); } 205 flow_controller()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 streams()241 base::hash_map<QuicStreamId, QuicDataStream*>* streams() { 242 return &stream_map_; 243 } 244 streams()245 const base::hash_map<QuicStreamId, QuicDataStream*>* streams() const { 246 return &stream_map_; 247 } 248 closed_streams()249 std::vector<QuicDataStream*>* closed_streams() { return &closed_streams_; } 250 get_max_open_streams()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