OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include "net/quic/quic_session.h" | 5 #include "net/quic/quic_session.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "net/quic/crypto/proof_verifier.h" | 8 #include "net/quic/crypto/proof_verifier.h" |
9 #include "net/quic/quic_connection.h" | 9 #include "net/quic/quic_connection.h" |
10 #include "net/quic/quic_flags.h" | |
11 #include "net/quic/quic_flow_controller.h" | 10 #include "net/quic/quic_flow_controller.h" |
12 #include "net/quic/quic_headers_stream.h" | 11 #include "net/quic/quic_headers_stream.h" |
13 #include "net/ssl/ssl_info.h" | 12 #include "net/ssl/ssl_info.h" |
14 | 13 |
15 using base::StringPiece; | 14 using base::StringPiece; |
16 using base::hash_map; | 15 using base::hash_map; |
17 using base::hash_set; | 16 using base::hash_set; |
18 using std::make_pair; | 17 using std::make_pair; |
19 using std::max; | 18 using std::max; |
20 using std::vector; | 19 using std::vector; |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( | 430 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( |
432 QuicStreamId stream_id, QuicStreamOffset final_byte_offset) { | 431 QuicStreamId stream_id, QuicStreamOffset final_byte_offset) { |
433 map<QuicStreamId, QuicStreamOffset>::iterator it = | 432 map<QuicStreamId, QuicStreamOffset>::iterator it = |
434 locally_closed_streams_highest_offset_.find(stream_id); | 433 locally_closed_streams_highest_offset_.find(stream_id); |
435 if (it == locally_closed_streams_highest_offset_.end()) { | 434 if (it == locally_closed_streams_highest_offset_.end()) { |
436 return; | 435 return; |
437 } | 436 } |
438 | 437 |
439 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset | 438 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset |
440 << " for stream " << stream_id; | 439 << " for stream " << stream_id; |
441 uint64 offset_diff = final_byte_offset - it->second; | 440 QuicByteCount offset_diff = final_byte_offset - it->second; |
442 if (flow_controller_->UpdateHighestReceivedOffset( | 441 if (flow_controller_->UpdateHighestReceivedOffset( |
443 flow_controller_->highest_received_byte_offset() + offset_diff)) { | 442 flow_controller_->highest_received_byte_offset() + offset_diff)) { |
444 // If the final offset violates flow control, close the connection now. | 443 // If the final offset violates flow control, close the connection now. |
445 if (flow_controller_->FlowControlViolation()) { | 444 if (flow_controller_->FlowControlViolation()) { |
446 connection_->SendConnectionClose( | 445 connection_->SendConnectionClose( |
447 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA); | 446 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA); |
448 return; | 447 return; |
449 } | 448 } |
450 } | 449 } |
451 | 450 |
452 flow_controller_->AddBytesConsumed(offset_diff); | 451 flow_controller_->AddBytesConsumed(offset_diff); |
453 locally_closed_streams_highest_offset_.erase(it); | 452 locally_closed_streams_highest_offset_.erase(it); |
454 } | 453 } |
455 | 454 |
456 bool QuicSession::IsEncryptionEstablished() { | 455 bool QuicSession::IsEncryptionEstablished() { |
457 return GetCryptoStream()->encryption_established(); | 456 return GetCryptoStream()->encryption_established(); |
458 } | 457 } |
459 | 458 |
460 bool QuicSession::IsCryptoHandshakeConfirmed() { | 459 bool QuicSession::IsCryptoHandshakeConfirmed() { |
461 return GetCryptoStream()->handshake_confirmed(); | 460 return GetCryptoStream()->handshake_confirmed(); |
462 } | 461 } |
463 | 462 |
464 void QuicSession::OnConfigNegotiated() { | 463 void QuicSession::OnConfigNegotiated() { |
465 connection_->SetFromConfig(config_); | 464 connection_->SetFromConfig(config_); |
466 QuicVersion version = connection()->version(); | 465 QuicVersion version = connection()->version(); |
467 | 466 |
468 if (FLAGS_quic_allow_more_open_streams) { | 467 uint32 max_streams = config_.MaxStreamsPerConnection(); |
469 uint32 max_streams = config_.MaxStreamsPerConnection(); | 468 if (is_server()) { |
470 if (is_server()) { | 469 // A server should accept a small number of additional streams beyond the |
471 // A server should accept a small number of additional streams beyond the | 470 // limit sent to the client. This helps avoid early connection termination |
472 // limit sent to the client. This helps avoid early connection termination | 471 // when FIN/RSTs for old streams are lost or arrive out of order. |
473 // when FIN/RSTs for old streams are lost or arrive out of order. | 472 // Use a minimum number of additional streams, or a percentage increase, |
474 // Use a minimum number of additional streams, or a percentage increase, | 473 // whichever is larger. |
475 // whichever is larger. | 474 max_streams = |
476 max_streams = | 475 max(max_streams + kMaxStreamsMinimumIncrement, |
477 max(max_streams + kMaxStreamsMinimumIncrement, | 476 static_cast<uint32>(max_streams * kMaxStreamsMultiplier)); |
478 static_cast<uint32>(max_streams * kMaxStreamsMultiplier)); | |
479 } | |
480 set_max_open_streams(max_streams); | |
481 } | 477 } |
| 478 set_max_open_streams(max_streams); |
482 | 479 |
483 if (version == QUIC_VERSION_19) { | 480 if (version == QUIC_VERSION_19) { |
484 // QUIC_VERSION_19 doesn't support independent stream/session flow | 481 // QUIC_VERSION_19 doesn't support independent stream/session flow |
485 // control windows. | 482 // control windows. |
486 if (config_.HasReceivedInitialFlowControlWindowBytes()) { | 483 if (config_.HasReceivedInitialFlowControlWindowBytes()) { |
487 // Streams which were created before the SHLO was received (0-RTT | 484 // Streams which were created before the SHLO was received (0-RTT |
488 // requests) are now informed of the peer's initial flow control window. | 485 // requests) are now informed of the peer's initial flow control window. |
489 uint32 new_window = config_.ReceivedInitialFlowControlWindowBytes(); | 486 QuicStreamOffset new_window = |
| 487 config_.ReceivedInitialFlowControlWindowBytes(); |
490 OnNewStreamFlowControlWindow(new_window); | 488 OnNewStreamFlowControlWindow(new_window); |
491 OnNewSessionFlowControlWindow(new_window); | 489 OnNewSessionFlowControlWindow(new_window); |
492 } | 490 } |
493 | 491 |
494 return; | 492 return; |
495 } | 493 } |
496 | 494 |
497 // QUIC_VERSION_21 and higher can have independent stream and session flow | 495 // QUIC_VERSION_21 and higher can have independent stream and session flow |
498 // control windows. | 496 // control windows. |
499 if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) { | 497 if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) { |
500 // Streams which were created before the SHLO was received (0-RTT | 498 // Streams which were created before the SHLO was received (0-RTT |
501 // requests) are now informed of the peer's initial flow control window. | 499 // requests) are now informed of the peer's initial flow control window. |
502 OnNewStreamFlowControlWindow( | 500 OnNewStreamFlowControlWindow( |
503 config_.ReceivedInitialStreamFlowControlWindowBytes()); | 501 config_.ReceivedInitialStreamFlowControlWindowBytes()); |
504 } | 502 } |
505 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { | 503 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { |
506 OnNewSessionFlowControlWindow( | 504 OnNewSessionFlowControlWindow( |
507 config_.ReceivedInitialSessionFlowControlWindowBytes()); | 505 config_.ReceivedInitialSessionFlowControlWindowBytes()); |
508 } | 506 } |
509 } | 507 } |
510 | 508 |
511 void QuicSession::OnNewStreamFlowControlWindow(uint32 new_window) { | 509 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { |
512 if (new_window < kDefaultFlowControlSendWindow) { | 510 if (new_window < kDefaultFlowControlSendWindow) { |
513 LOG(ERROR) | 511 LOG(ERROR) |
514 << "Peer sent us an invalid stream flow control send window: " | 512 << "Peer sent us an invalid stream flow control send window: " |
515 << new_window << ", below default: " << kDefaultFlowControlSendWindow; | 513 << new_window << ", below default: " << kDefaultFlowControlSendWindow; |
516 if (connection_->connected()) { | 514 if (connection_->connected()) { |
517 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); | 515 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); |
518 } | 516 } |
519 return; | 517 return; |
520 } | 518 } |
521 | 519 |
522 // Inform all existing streams about the new window. | 520 // Inform all existing streams about the new window. |
523 if (connection_->version() >= QUIC_VERSION_21) { | 521 if (connection_->version() >= QUIC_VERSION_21) { |
524 GetCryptoStream()->UpdateSendWindowOffset(new_window); | 522 GetCryptoStream()->UpdateSendWindowOffset(new_window); |
525 headers_stream_->UpdateSendWindowOffset(new_window); | 523 headers_stream_->UpdateSendWindowOffset(new_window); |
526 } | 524 } |
527 for (DataStreamMap::iterator it = stream_map_.begin(); | 525 for (DataStreamMap::iterator it = stream_map_.begin(); |
528 it != stream_map_.end(); ++it) { | 526 it != stream_map_.end(); ++it) { |
529 it->second->UpdateSendWindowOffset(new_window); | 527 it->second->UpdateSendWindowOffset(new_window); |
530 } | 528 } |
531 } | 529 } |
532 | 530 |
533 void QuicSession::OnNewSessionFlowControlWindow(uint32 new_window) { | 531 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { |
534 if (new_window < kDefaultFlowControlSendWindow) { | 532 if (new_window < kDefaultFlowControlSendWindow) { |
535 LOG(ERROR) | 533 LOG(ERROR) |
536 << "Peer sent us an invalid session flow control send window: " | 534 << "Peer sent us an invalid session flow control send window: " |
537 << new_window << ", below default: " << kDefaultFlowControlSendWindow; | 535 << new_window << ", below default: " << kDefaultFlowControlSendWindow; |
538 if (connection_->connected()) { | 536 if (connection_->connected()) { |
539 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); | 537 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); |
540 } | 538 } |
541 return; | 539 return; |
542 } | 540 } |
543 | 541 |
(...skipping 12 matching lines...) Expand all Loading... |
556 // decrypted by the peer. | 554 // decrypted by the peer. |
557 connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION); | 555 connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION); |
558 break; | 556 break; |
559 | 557 |
560 case HANDSHAKE_CONFIRMED: | 558 case HANDSHAKE_CONFIRMED: |
561 LOG_IF(DFATAL, !config_.negotiated()) << ENDPOINT | 559 LOG_IF(DFATAL, !config_.negotiated()) << ENDPOINT |
562 << "Handshake confirmed without parameter negotiation."; | 560 << "Handshake confirmed without parameter negotiation."; |
563 // Discard originally encrypted packets, since they can't be decrypted by | 561 // Discard originally encrypted packets, since they can't be decrypted by |
564 // the peer. | 562 // the peer. |
565 connection_->NeuterUnencryptedPackets(); | 563 connection_->NeuterUnencryptedPackets(); |
566 if (!FLAGS_quic_allow_more_open_streams) { | |
567 max_open_streams_ = config_.MaxStreamsPerConnection(); | |
568 } | |
569 break; | 564 break; |
570 | 565 |
571 default: | 566 default: |
572 LOG(ERROR) << ENDPOINT << "Got unknown handshake event: " << event; | 567 LOG(ERROR) << ENDPOINT << "Got unknown handshake event: " << event; |
573 } | 568 } |
574 } | 569 } |
575 | 570 |
576 void QuicSession::OnCryptoHandshakeMessageSent( | 571 void QuicSession::OnCryptoHandshakeMessageSent( |
577 const CryptoHandshakeMessage& message) { | 572 const CryptoHandshakeMessage& message) { |
578 } | 573 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 for (DataStreamMap::iterator it = stream_map_.begin(); | 776 for (DataStreamMap::iterator it = stream_map_.begin(); |
782 it != stream_map_.end(); ++it) { | 777 it != stream_map_.end(); ++it) { |
783 if (it->second->flow_controller()->IsBlocked()) { | 778 if (it->second->flow_controller()->IsBlocked()) { |
784 return true; | 779 return true; |
785 } | 780 } |
786 } | 781 } |
787 return false; | 782 return false; |
788 } | 783 } |
789 | 784 |
790 } // namespace net | 785 } // namespace net |
OLD | NEW |