Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: net/spdy/spdy_session.h

Issue 8230037: Send PING to check the status of the SPDY connection. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698