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 |