Chromium Code Reviews| 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_; | |
|
willchan no longer on Chromium
2011/10/15 08:08:03
Is this a new optimization? I haven't heard about
jar (doing other things)
2011/10/15 09:00:52
Recall that the back-and-forth discussion was abou
willchan no longer on Chromium
2011/10/15 20:17:40
Please recall http://code.google.com/p/chromium/is
jar (doing other things)
2011/10/15 23:25:11
If you are concerned with it, we can set the time
ramant (doing other things)
2011/10/15 23:33:11
I think it is just variable name change. In patch
willchan no longer on Chromium
2011/10/15 23:52:28
Great, let's do that.
willchan no longer on Chromium
2011/10/15 23:52:28
Oh wow, I totally missed that previously. My bad.
| |
| 571 | |
| 572 // This is the amount of time (in milliseconds) we wait before sending a | |
| 573 // trailing ping. | |
|
willchan no longer on Chromium
2011/10/15 08:08:03
You should explain why we use a trailing ping.
jar (doing other things)
2011/10/15 09:00:52
Suggested comment:
We use a trailing ping (sent a
ramant (doing other things)
2011/10/15 23:33:11
Done.
| |
| 574 static int trailing_ping_delay_time_ms_; | |
| 575 | |
| 576 // The amount of time (in milliseconds) that we are willing to tolerate with | |
| 577 // no data received (of any form), while there is a ping in flight, before we | |
| 578 // declare the connection to be hung. | |
| 579 static int hung_interval_ms_; | |
| 460 }; | 580 }; |
| 461 | 581 |
| 462 class NetLogSpdySynParameter : public NetLog::EventParameters { | 582 class NetLogSpdySynParameter : public NetLog::EventParameters { |
| 463 public: | 583 public: |
| 464 NetLogSpdySynParameter(const linked_ptr<spdy::SpdyHeaderBlock>& headers, | 584 NetLogSpdySynParameter(const linked_ptr<spdy::SpdyHeaderBlock>& headers, |
| 465 spdy::SpdyControlFlags flags, | 585 spdy::SpdyControlFlags flags, |
| 466 spdy::SpdyStreamId id, | 586 spdy::SpdyStreamId id, |
| 467 spdy::SpdyStreamId associated_stream); | 587 spdy::SpdyStreamId associated_stream); |
| 468 | 588 |
| 469 const linked_ptr<spdy::SpdyHeaderBlock>& GetHeaders() const { | 589 const linked_ptr<spdy::SpdyHeaderBlock>& GetHeaders() const { |
| 470 return headers_; | 590 return headers_; |
| 471 } | 591 } |
| 472 | 592 |
| 473 virtual base::Value* ToValue() const; | 593 virtual base::Value* ToValue() const; |
| 474 | 594 |
| 475 private: | 595 private: |
| 476 virtual ~NetLogSpdySynParameter(); | 596 virtual ~NetLogSpdySynParameter(); |
| 477 | 597 |
| 478 const linked_ptr<spdy::SpdyHeaderBlock> headers_; | 598 const linked_ptr<spdy::SpdyHeaderBlock> headers_; |
| 479 const spdy::SpdyControlFlags flags_; | 599 const spdy::SpdyControlFlags flags_; |
| 480 const spdy::SpdyStreamId id_; | 600 const spdy::SpdyStreamId id_; |
| 481 const spdy::SpdyStreamId associated_stream_; | 601 const spdy::SpdyStreamId associated_stream_; |
| 482 | 602 |
| 483 DISALLOW_COPY_AND_ASSIGN(NetLogSpdySynParameter); | 603 DISALLOW_COPY_AND_ASSIGN(NetLogSpdySynParameter); |
| 484 }; | 604 }; |
| 485 | 605 |
| 486 } // namespace net | 606 } // namespace net |
| 487 | 607 |
| 488 #endif // NET_SPDY_SPDY_SESSION_H_ | 608 #endif // NET_SPDY_SPDY_SESSION_H_ |
| OLD | NEW |