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