OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_SPDY_SESSION_H_ | 5 #ifndef NET_SPDY_SPDY_SESSION_H_ |
6 #define NET_SPDY_SPDY_SESSION_H_ | 6 #define NET_SPDY_SPDY_SESSION_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <deque> | 9 #include <deque> |
10 #include <list> | 10 #include <list> |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 bool is_secure, | 97 bool is_secure, |
98 int certificate_error_code); | 98 int certificate_error_code); |
99 | 99 |
100 // Check to see if this SPDY session can support an additional domain. | 100 // Check to see if this SPDY session can support an additional domain. |
101 // If the session is un-authenticated, then this call always returns true. | 101 // If the session is un-authenticated, then this call always returns true. |
102 // For SSL-based sessions, verifies that the certificate in use by this | 102 // For SSL-based sessions, verifies that the certificate in use by this |
103 // session provides authentication for the domain. | 103 // session provides authentication for the domain. |
104 // NOTE: This function can have false negatives on some platforms. | 104 // NOTE: This function can have false negatives on some platforms. |
105 bool VerifyDomainAuthentication(const std::string& domain); | 105 bool VerifyDomainAuthentication(const std::string& domain); |
106 | 106 |
107 // Send the SYN frame for |stream_id|. | 107 // Send the SYN frame for |stream_id|. This also sends PING message to check |
| 108 // the status of the connection. |
108 int WriteSynStream( | 109 int WriteSynStream( |
109 spdy::SpdyStreamId stream_id, | 110 spdy::SpdyStreamId stream_id, |
110 RequestPriority priority, | 111 RequestPriority priority, |
111 spdy::SpdyControlFlags flags, | 112 spdy::SpdyControlFlags flags, |
112 const linked_ptr<spdy::SpdyHeaderBlock>& headers); | 113 const linked_ptr<spdy::SpdyHeaderBlock>& headers); |
113 | 114 |
114 // Write a data frame to the stream. | 115 // Write a data frame to the stream. |
115 // Used to create and queue a data frame for the given stream. | 116 // Used to create and queue a data frame for the given stream. |
116 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data, | 117 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data, |
117 int len, | 118 int len, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 150 |
150 // Sets the max concurrent streams per session, as a ceiling on any server | 151 // Sets the max concurrent streams per session, as a ceiling on any server |
151 // specific SETTINGS value. | 152 // specific SETTINGS value. |
152 static void set_max_concurrent_streams(size_t value) { | 153 static void set_max_concurrent_streams(size_t value) { |
153 max_concurrent_stream_limit_ = value; | 154 max_concurrent_stream_limit_ = value; |
154 } | 155 } |
155 static size_t max_concurrent_streams() { | 156 static size_t max_concurrent_streams() { |
156 return max_concurrent_stream_limit_; | 157 return max_concurrent_stream_limit_; |
157 } | 158 } |
158 | 159 |
| 160 // Enable sending of PING frame with each request. |
| 161 static void set_enable_ping_based_connection_checking(bool enable) { |
| 162 enable_ping_based_connection_checking_ = enable; |
| 163 } |
| 164 static bool enable_ping_based_connection_checking() { |
| 165 return enable_ping_based_connection_checking_; |
| 166 } |
| 167 |
159 // The initial max concurrent streams per session, can be overridden by the | 168 // The initial max concurrent streams per session, can be overridden by the |
160 // server via SETTINGS. | 169 // server via SETTINGS. |
161 static void set_init_max_concurrent_streams(size_t value) { | 170 static void set_init_max_concurrent_streams(size_t value) { |
162 init_max_concurrent_streams_ = | 171 init_max_concurrent_streams_ = |
163 std::min(value, max_concurrent_stream_limit_); | 172 std::min(value, max_concurrent_stream_limit_); |
164 } | 173 } |
165 | 174 |
166 // Send WINDOW_UPDATE frame, called by a stream whenever receive window | 175 // Send WINDOW_UPDATE frame, called by a stream whenever receive window |
167 // size is increased. | 176 // size is increased. |
168 void SendWindowUpdate(spdy::SpdyStreamId stream_id, int delta_window_size); | 177 void SendWindowUpdate(spdy::SpdyStreamId stream_id, int delta_window_size); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 return unclaimed_pushed_streams_.size(); | 219 return unclaimed_pushed_streams_.size(); |
211 } | 220 } |
212 | 221 |
213 const BoundNetLog& net_log() const { return net_log_; } | 222 const BoundNetLog& net_log() const { return net_log_; } |
214 | 223 |
215 int GetPeerAddress(AddressList* address) const; | 224 int GetPeerAddress(AddressList* address) const; |
216 int GetLocalAddress(IPEndPoint* address) const; | 225 int GetLocalAddress(IPEndPoint* address) const; |
217 | 226 |
218 private: | 227 private: |
219 friend class base::RefCounted<SpdySession>; | 228 friend class base::RefCounted<SpdySession>; |
| 229 // Allow tests to access our innards for testing purposes. |
| 230 FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, Ping); |
220 FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, GetActivePushStream); | 231 FRIEND_TEST_ALL_PREFIXES(SpdySessionTest, GetActivePushStream); |
221 | 232 |
222 struct PendingCreateStream { | 233 struct PendingCreateStream { |
223 PendingCreateStream(const GURL& url, RequestPriority priority, | 234 PendingCreateStream(const GURL& url, RequestPriority priority, |
224 scoped_refptr<SpdyStream>* spdy_stream, | 235 scoped_refptr<SpdyStream>* spdy_stream, |
225 const BoundNetLog& stream_net_log, | 236 const BoundNetLog& stream_net_log, |
226 OldCompletionCallback* callback) | 237 OldCompletionCallback* callback) |
227 : url(&url), priority(priority), spdy_stream(spdy_stream), | 238 : url(&url), priority(priority), spdy_stream(spdy_stream), |
228 stream_net_log(&stream_net_log), callback(callback) { } | 239 stream_net_log(&stream_net_log), callback(callback) { } |
229 | 240 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 281 |
271 // Control frame handlers. | 282 // Control frame handlers. |
272 void OnSyn(const spdy::SpdySynStreamControlFrame& frame, | 283 void OnSyn(const spdy::SpdySynStreamControlFrame& frame, |
273 const linked_ptr<spdy::SpdyHeaderBlock>& headers); | 284 const linked_ptr<spdy::SpdyHeaderBlock>& headers); |
274 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame, | 285 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame, |
275 const linked_ptr<spdy::SpdyHeaderBlock>& headers); | 286 const linked_ptr<spdy::SpdyHeaderBlock>& headers); |
276 void OnHeaders(const spdy::SpdyHeadersControlFrame& frame, | 287 void OnHeaders(const spdy::SpdyHeadersControlFrame& frame, |
277 const linked_ptr<spdy::SpdyHeaderBlock>& headers); | 288 const linked_ptr<spdy::SpdyHeaderBlock>& headers); |
278 void OnRst(const spdy::SpdyRstStreamControlFrame& frame); | 289 void OnRst(const spdy::SpdyRstStreamControlFrame& frame); |
279 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame); | 290 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame); |
| 291 void OnPing(const spdy::SpdyPingControlFrame& frame); |
280 void OnSettings(const spdy::SpdySettingsControlFrame& frame); | 292 void OnSettings(const spdy::SpdySettingsControlFrame& frame); |
281 void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame); | 293 void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame); |
282 | 294 |
283 // IO Callbacks | 295 // IO Callbacks |
284 void OnReadComplete(int result); | 296 void OnReadComplete(int result); |
285 void OnWriteComplete(int result); | 297 void OnWriteComplete(int result); |
286 | 298 |
287 // Send relevant SETTINGS. This is generally called on connection setup. | 299 // Send relevant SETTINGS. This is generally called on connection setup. |
288 void SendSettings(); | 300 void SendSettings(); |
289 | 301 |
290 // Handle SETTINGS. Either when we send settings, or when we receive a | 302 // Handle SETTINGS. Either when we send settings, or when we receive a |
291 // SETTINGS ontrol frame, update our SpdySession accordingly. | 303 // SETTINGS ontrol frame, update our SpdySession accordingly. |
292 void HandleSettings(const spdy::SpdySettings& settings); | 304 void HandleSettings(const spdy::SpdySettings& settings); |
293 | 305 |
| 306 // Send the PING (preface-PING and trailing-PING) frames. |
| 307 void SendPrefacePingIfNoneInFlight(); |
| 308 |
| 309 // Send PING if there are no PINGs in flight and we haven't heard from server. |
| 310 void SendPrefacePing(); |
| 311 |
| 312 // Send a PING after delay. Don't post a PING if there is already |
| 313 // a trailing PING pending. |
| 314 void PlanToSendTrailingPing(); |
| 315 |
| 316 // Send a PING if there is no |trailing_ping_pending_|. This PING verifies |
| 317 // that the requests are being received by the server. |
| 318 void SendTrailingPing(); |
| 319 |
| 320 // Send the PING frame. |
| 321 void WritePingFrame(uint32 unique_id); |
| 322 |
| 323 // Post a CheckPingStatus call after delay. Don't post if there is already |
| 324 // CheckPingStatus running. |
| 325 void PlanToCheckPingStatus(); |
| 326 |
| 327 // Check the status of the connection. It calls |CloseSessionOnError| if we |
| 328 // haven't received any data in |kHungInterval| time period. |
| 329 void CheckPingStatus(base::TimeTicks last_check_time); |
| 330 |
294 // Start reading from the socket. | 331 // Start reading from the socket. |
295 // Returns OK on success, or an error on failure. | 332 // Returns OK on success, or an error on failure. |
296 net::Error ReadSocket(); | 333 net::Error ReadSocket(); |
297 | 334 |
298 // Write current data to the socket. | 335 // Write current data to the socket. |
299 void WriteSocketLater(); | 336 void WriteSocketLater(); |
300 void WriteSocket(); | 337 void WriteSocket(); |
301 | 338 |
302 // Get a new stream id. | 339 // Get a new stream id. |
303 int GetNewStreamId(); | 340 int GetNewStreamId(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 const char* data, | 378 const char* data, |
342 size_t len); | 379 size_t len); |
343 virtual void OnControl(const spdy::SpdyControlFrame* frame); | 380 virtual void OnControl(const spdy::SpdyControlFrame* frame); |
344 | 381 |
345 virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id, | 382 virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id, |
346 const char* header_data, | 383 const char* header_data, |
347 size_t len); | 384 size_t len); |
348 | 385 |
349 virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame); | 386 virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame); |
350 | 387 |
| 388 // -------------------------- |
| 389 // Helper methods for testing |
| 390 // -------------------------- |
| 391 static void set_connection_at_risk_of_loss_ms(int duration) { |
| 392 connection_at_risk_of_loss_ms_ = duration; |
| 393 } |
| 394 static int connection_at_risk_of_loss_ms() { |
| 395 return connection_at_risk_of_loss_ms_; |
| 396 } |
| 397 |
| 398 static void set_trailing_ping_delay_time_ms(int duration) { |
| 399 trailing_ping_delay_time_ms_ = duration; |
| 400 } |
| 401 static int trailing_ping_delay_time_ms() { |
| 402 return trailing_ping_delay_time_ms_; |
| 403 } |
| 404 |
| 405 static void set_hung_interval_ms(int duration) { |
| 406 hung_interval_ms_ = duration; |
| 407 } |
| 408 static int hung_interval_ms() { |
| 409 return hung_interval_ms_; |
| 410 } |
| 411 |
| 412 int64 pings_in_flight() const { return pings_in_flight_; } |
| 413 |
| 414 uint32 next_ping_id() const { return next_ping_id_; } |
| 415 |
| 416 base::TimeTicks received_data_time() const { return received_data_time_; } |
| 417 |
| 418 bool trailing_ping_pending() const { return trailing_ping_pending_; } |
| 419 |
| 420 bool check_ping_status_pending() const { return check_ping_status_pending_; } |
| 421 |
351 // Callbacks for the Spdy session. | 422 // Callbacks for the Spdy session. |
352 OldCompletionCallbackImpl<SpdySession> read_callback_; | 423 OldCompletionCallbackImpl<SpdySession> read_callback_; |
353 OldCompletionCallbackImpl<SpdySession> write_callback_; | 424 OldCompletionCallbackImpl<SpdySession> write_callback_; |
354 | 425 |
355 // Used for posting asynchronous IO tasks. We use this even though | 426 // Used for posting asynchronous IO tasks. We use this even though |
356 // SpdySession is refcounted because we don't need to keep the SpdySession | 427 // SpdySession is refcounted because we don't need to keep the SpdySession |
357 // alive if the last reference is within a RunnableMethod. Just revoke the | 428 // alive if the last reference is within a RunnableMethod. Just revoke the |
358 // method. | 429 // method. |
359 ScopedRunnableMethodFactory<SpdySession> method_factory_; | 430 ScopedRunnableMethodFactory<SpdySession> method_factory_; |
360 | 431 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 int streams_pushed_count_; | 501 int streams_pushed_count_; |
431 int streams_pushed_and_claimed_count_; | 502 int streams_pushed_and_claimed_count_; |
432 int streams_abandoned_count_; | 503 int streams_abandoned_count_; |
433 int frames_received_; | 504 int frames_received_; |
434 int bytes_received_; | 505 int bytes_received_; |
435 bool sent_settings_; // Did this session send settings when it started. | 506 bool sent_settings_; // Did this session send settings when it started. |
436 bool received_settings_; // Did this session receive at least one settings | 507 bool received_settings_; // Did this session receive at least one settings |
437 // frame. | 508 // frame. |
438 int stalled_streams_; // Count of streams that were ever stalled. | 509 int stalled_streams_; // Count of streams that were ever stalled. |
439 | 510 |
| 511 // Count of all pings on the wire, for which we have not gotten a response. |
| 512 int64 pings_in_flight_; |
| 513 |
| 514 // This is the next ping_id (unique_id) to be sent in PING frame. |
| 515 uint32 next_ping_id_; |
| 516 |
| 517 // This is the last time we have received data. |
| 518 base::TimeTicks received_data_time_; |
| 519 |
| 520 // Indicate if we have already scheduled a delayed task to send a trailing |
| 521 // ping (and we never have more than one scheduled at a time). |
| 522 bool trailing_ping_pending_; |
| 523 |
| 524 // Indicate if we have already scheduled a delayed task to check the ping |
| 525 // status. |
| 526 bool check_ping_status_pending_; |
| 527 |
| 528 // Indicate if the last data we sent was a ping (generally, a trailing ping). |
| 529 // This helps us to decide if we need yet another trailing ping, or if it |
| 530 // would be a waste of effort (and MUST not be done). |
| 531 bool last_sent_was_ping_; |
| 532 |
440 // Initial send window size for the session; can be changed by an | 533 // Initial send window size for the session; can be changed by an |
441 // arriving SETTINGS frame; newly created streams use this value for the | 534 // arriving SETTINGS frame; newly created streams use this value for the |
442 // initial send window size. | 535 // initial send window size. |
443 int initial_send_window_size_; | 536 int initial_send_window_size_; |
444 | 537 |
445 // Initial receive window size for the session; there are plans to add a | 538 // Initial receive window size for the session; there are plans to add a |
446 // command line switch that would cause a SETTINGS frame with window size | 539 // command line switch that would cause a SETTINGS frame with window size |
447 // announcement to be sent on startup; newly created streams will use | 540 // announcement to be sent on startup; newly created streams will use |
448 // this value for the initial receive window size. | 541 // this value for the initial receive window size. |
449 int initial_recv_window_size_; | 542 int initial_recv_window_size_; |
450 | 543 |
451 BoundNetLog net_log_; | 544 BoundNetLog net_log_; |
452 | 545 |
453 // Outside of tests, this should always be true. | 546 // Outside of tests, this should always be true. |
454 bool verify_domain_authentication_; | 547 bool verify_domain_authentication_; |
455 | 548 |
456 static bool use_ssl_; | 549 static bool use_ssl_; |
457 static bool use_flow_control_; | 550 static bool use_flow_control_; |
458 static size_t init_max_concurrent_streams_; | 551 static size_t init_max_concurrent_streams_; |
459 static size_t max_concurrent_stream_limit_; | 552 static size_t max_concurrent_stream_limit_; |
| 553 |
| 554 // This enables or disables connection health checking system. |
| 555 static bool enable_ping_based_connection_checking_; |
| 556 |
| 557 // |connection_at_risk_of_loss_ms_| is an optimization to avoid sending |
| 558 // wasteful preface pings (when we just got some data). |
| 559 // |
| 560 // If it is zero (the most conservative figure), then we always send the |
| 561 // preface ping (when none are in flight). |
| 562 // |
| 563 // It is common for TCP/IP sessions to time out in about 3-5 minutes. |
| 564 // Certainly if it has been more than 3 minutes, we do want to send a preface |
| 565 // ping. |
| 566 // |
| 567 // We don't think any connection will time out in under about 10 seconds. So |
| 568 // this might as well be set to something conservative like 10 seconds. Later, |
| 569 // we could adjust it to send fewer pings perhaps. |
| 570 static int connection_at_risk_of_loss_ms_; |
| 571 |
| 572 // This is the amount of time (in milliseconds) we wait before sending a |
| 573 // trailing ping. We use a trailing ping (sent after all data) to get an |
| 574 // effective acknowlegement from the server that it has indeed received all |
| 575 // (prior) data frames. With that assurance, we are willing to enter into a |
| 576 // wait state for responses to our last data frame(s) without further pings. |
| 577 static int trailing_ping_delay_time_ms_; |
| 578 |
| 579 // The amount of time (in milliseconds) that we are willing to tolerate with |
| 580 // no data received (of any form), while there is a ping in flight, before we |
| 581 // declare the connection to be hung. |
| 582 static int hung_interval_ms_; |
460 }; | 583 }; |
461 | 584 |
462 class NetLogSpdySynParameter : public NetLog::EventParameters { | 585 class NetLogSpdySynParameter : public NetLog::EventParameters { |
463 public: | 586 public: |
464 NetLogSpdySynParameter(const linked_ptr<spdy::SpdyHeaderBlock>& headers, | 587 NetLogSpdySynParameter(const linked_ptr<spdy::SpdyHeaderBlock>& headers, |
465 spdy::SpdyControlFlags flags, | 588 spdy::SpdyControlFlags flags, |
466 spdy::SpdyStreamId id, | 589 spdy::SpdyStreamId id, |
467 spdy::SpdyStreamId associated_stream); | 590 spdy::SpdyStreamId associated_stream); |
468 | 591 |
469 const linked_ptr<spdy::SpdyHeaderBlock>& GetHeaders() const { | 592 const linked_ptr<spdy::SpdyHeaderBlock>& GetHeaders() const { |
470 return headers_; | 593 return headers_; |
471 } | 594 } |
472 | 595 |
473 virtual base::Value* ToValue() const; | 596 virtual base::Value* ToValue() const; |
474 | 597 |
475 private: | 598 private: |
476 virtual ~NetLogSpdySynParameter(); | 599 virtual ~NetLogSpdySynParameter(); |
477 | 600 |
478 const linked_ptr<spdy::SpdyHeaderBlock> headers_; | 601 const linked_ptr<spdy::SpdyHeaderBlock> headers_; |
479 const spdy::SpdyControlFlags flags_; | 602 const spdy::SpdyControlFlags flags_; |
480 const spdy::SpdyStreamId id_; | 603 const spdy::SpdyStreamId id_; |
481 const spdy::SpdyStreamId associated_stream_; | 604 const spdy::SpdyStreamId associated_stream_; |
482 | 605 |
483 DISALLOW_COPY_AND_ASSIGN(NetLogSpdySynParameter); | 606 DISALLOW_COPY_AND_ASSIGN(NetLogSpdySynParameter); |
484 }; | 607 }; |
485 | 608 |
486 } // namespace net | 609 } // namespace net |
487 | 610 |
488 #endif // NET_SPDY_SPDY_SESSION_H_ | 611 #endif // NET_SPDY_SPDY_SESSION_H_ |
OLD | NEW |