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

Side by Side Diff: net/quic/quic_session.cc

Issue 1541263002: Landing Recent QUIC changes until 12/18/2015 13:57 UTC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: replace -1 with 0xff for InvalidPathId Created 4 years, 11 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
« no previous file with comments | « net/quic/quic_session.h ('k') | net/quic/quic_session_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/strings/stringprintf.h"
8 #include "net/quic/crypto/proof_verifier.h" 9 #include "net/quic/crypto/proof_verifier.h"
9 #include "net/quic/quic_connection.h" 10 #include "net/quic/quic_connection.h"
10 #include "net/quic/quic_flags.h" 11 #include "net/quic/quic_flags.h"
11 #include "net/quic/quic_flow_controller.h" 12 #include "net/quic/quic_flow_controller.h"
12 #include "net/ssl/ssl_info.h" 13 #include "net/ssl/ssl_info.h"
13 14
14 using base::StringPiece; 15 using base::StringPiece;
15 using base::hash_map; 16 using base::hash_map;
16 using base::hash_set; 17 using base::hash_set;
17 using std::make_pair; 18 using std::make_pair;
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 return; 398 return;
398 } 399 }
399 400
400 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset 401 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset
401 << " for stream " << stream_id; 402 << " for stream " << stream_id;
402 QuicByteCount offset_diff = final_byte_offset - it->second; 403 QuicByteCount offset_diff = final_byte_offset - it->second;
403 if (flow_controller_.UpdateHighestReceivedOffset( 404 if (flow_controller_.UpdateHighestReceivedOffset(
404 flow_controller_.highest_received_byte_offset() + offset_diff)) { 405 flow_controller_.highest_received_byte_offset() + offset_diff)) {
405 // If the final offset violates flow control, close the connection now. 406 // If the final offset violates flow control, close the connection now.
406 if (flow_controller_.FlowControlViolation()) { 407 if (flow_controller_.FlowControlViolation()) {
407 connection_->SendConnectionClose( 408 connection_->SendConnectionCloseWithDetails(
408 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA); 409 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
410 "Connection level flow control violation");
409 return; 411 return;
410 } 412 }
411 } 413 }
412 414
413 flow_controller_.AddBytesConsumed(offset_diff); 415 flow_controller_.AddBytesConsumed(offset_diff);
414 locally_closed_streams_highest_offset_.erase(it); 416 locally_closed_streams_highest_offset_.erase(it);
415 if (IsIncomingStream(stream_id)) { 417 if (IsIncomingStream(stream_id)) {
416 --num_locally_closed_incoming_streams_highest_offset_; 418 --num_locally_closed_incoming_streams_highest_offset_;
417 } 419 }
418 } 420 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); 510 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window);
509 } 511 }
510 } 512 }
511 513
512 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { 514 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
513 if (new_window < kMinimumFlowControlSendWindow) { 515 if (new_window < kMinimumFlowControlSendWindow) {
514 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: " 516 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: "
515 << new_window 517 << new_window
516 << ", below default: " << kMinimumFlowControlSendWindow; 518 << ", below default: " << kMinimumFlowControlSendWindow;
517 if (connection_->connected()) { 519 if (connection_->connected()) {
518 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); 520 connection_->SendConnectionCloseWithDetails(
521 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low");
519 } 522 }
520 return; 523 return;
521 } 524 }
522 525
523 // Inform all existing streams about the new window. 526 // Inform all existing streams about the new window.
524 for (auto const& kv : static_stream_map_) { 527 for (auto const& kv : static_stream_map_) {
525 kv.second->UpdateSendWindowOffset(new_window); 528 kv.second->UpdateSendWindowOffset(new_window);
526 } 529 }
527 for (auto const& kv : dynamic_stream_map_) { 530 for (auto const& kv : dynamic_stream_map_) {
528 kv.second->UpdateSendWindowOffset(new_window); 531 kv.second->UpdateSendWindowOffset(new_window);
529 } 532 }
530 } 533 }
531 534
532 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { 535 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
533 if (new_window < kMinimumFlowControlSendWindow) { 536 if (new_window < kMinimumFlowControlSendWindow) {
534 LOG(ERROR) << "Peer sent us an invalid session flow control send window: " 537 LOG(ERROR) << "Peer sent us an invalid session flow control send window: "
535 << new_window 538 << new_window
536 << ", below default: " << kMinimumFlowControlSendWindow; 539 << ", below default: " << kMinimumFlowControlSendWindow;
537 if (connection_->connected()) { 540 if (connection_->connected()) {
538 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); 541 connection_->SendConnectionCloseWithDetails(
542 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New connection window too low");
539 } 543 }
540 return; 544 return;
541 } 545 }
542 546
543 flow_controller_.UpdateSendWindowOffset(new_window); 547 flow_controller_.UpdateSendWindowOffset(new_window);
544 } 548 }
545 549
546 void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { 550 void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
547 switch (event) { 551 switch (event) {
548 // TODO(satyamshekhar): Move the logic of setting the encrypter/decrypter 552 // TODO(satyamshekhar): Move the logic of setting the encrypter/decrypter
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 void QuicSession::StreamDraining(QuicStreamId stream_id) { 621 void QuicSession::StreamDraining(QuicStreamId stream_id) {
618 DCHECK(ContainsKey(dynamic_stream_map_, stream_id)); 622 DCHECK(ContainsKey(dynamic_stream_map_, stream_id));
619 if (!ContainsKey(draining_streams_, stream_id)) { 623 if (!ContainsKey(draining_streams_, stream_id)) {
620 draining_streams_.insert(stream_id); 624 draining_streams_.insert(stream_id);
621 if (IsIncomingStream(stream_id)) { 625 if (IsIncomingStream(stream_id)) {
622 ++num_draining_incoming_streams_; 626 ++num_draining_incoming_streams_;
623 } 627 }
624 } 628 }
625 } 629 }
626 630
627 void QuicSession::CloseConnection(QuicErrorCode error) { 631 void QuicSession::CloseConnectionWithDetails(QuicErrorCode error,
632 const char* details) {
628 if (connection()->connected()) { 633 if (connection()->connected()) {
629 connection()->SendConnectionClose(error); 634 connection()->SendConnectionCloseWithDetails(error, details);
630 } 635 }
631 } 636 }
632 637
633 ReliableQuicStream* QuicSession::GetOrCreateDynamicStream( 638 ReliableQuicStream* QuicSession::GetOrCreateDynamicStream(
634 const QuicStreamId stream_id) { 639 const QuicStreamId stream_id) {
635 if (ContainsKey(static_stream_map_, stream_id)) { 640 if (ContainsKey(static_stream_map_, stream_id)) {
636 DLOG(FATAL) 641 DLOG(FATAL)
637 << "Attempt to call GetOrCreateDynamicStream for a static stream"; 642 << "Attempt to call GetOrCreateDynamicStream for a static stream";
638 return nullptr; 643 return nullptr;
639 } 644 }
640 645
641 StreamMap::iterator it = dynamic_stream_map_.find(stream_id); 646 StreamMap::iterator it = dynamic_stream_map_.find(stream_id);
642 if (it != dynamic_stream_map_.end()) { 647 if (it != dynamic_stream_map_.end()) {
643 return it->second; 648 return it->second;
644 } 649 }
645 650
646 if (IsClosedStream(stream_id)) { 651 if (IsClosedStream(stream_id)) {
647 return nullptr; 652 return nullptr;
648 } 653 }
649 654
650 if (!IsIncomingStream(stream_id)) { 655 if (!IsIncomingStream(stream_id)) {
651 // Received a frame for a locally-created stream that is not currently 656 // Received a frame for a locally-created stream that is not currently
652 // active. This is an error. 657 // active. This is an error.
653 CloseConnection(QUIC_INVALID_STREAM_ID); 658 CloseConnectionWithDetails(QUIC_INVALID_STREAM_ID,
659 "Data for nonexistent stream");
654 return nullptr; 660 return nullptr;
655 } 661 }
656 662
657 available_streams_.erase(stream_id); 663 available_streams_.erase(stream_id);
658 664
659 if (stream_id > largest_peer_created_stream_id_) { 665 if (stream_id > largest_peer_created_stream_id_) {
660 // Check if the new number of available streams would cause the number of 666 // Check if the new number of available streams would cause the number of
661 // available streams to exceed the limit. Note that the peer can create 667 // available streams to exceed the limit. Note that the peer can create
662 // only alternately-numbered streams. 668 // only alternately-numbered streams.
663 size_t additional_available_streams = 669 size_t additional_available_streams =
664 (stream_id - largest_peer_created_stream_id_) / 2 - 1; 670 (stream_id - largest_peer_created_stream_id_) / 2 - 1;
665 size_t new_num_available_streams = 671 size_t new_num_available_streams =
666 GetNumAvailableStreams() + additional_available_streams; 672 GetNumAvailableStreams() + additional_available_streams;
667 if (new_num_available_streams > get_max_available_streams()) { 673 if (new_num_available_streams > get_max_available_streams()) {
668 DVLOG(1) << "Failed to create a new incoming stream with id:" << stream_id 674 DVLOG(1) << "Failed to create a new incoming stream with id:" << stream_id
669 << ". There are already " << GetNumAvailableStreams() 675 << ". There are already " << GetNumAvailableStreams()
670 << " streams available, which would become " 676 << " streams available, which would become "
671 << new_num_available_streams << ", which exceeds the limit " 677 << new_num_available_streams << ", which exceeds the limit "
672 << get_max_available_streams() << "."; 678 << get_max_available_streams() << ".";
673 CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS); 679 CloseConnectionWithDetails(
680 QUIC_TOO_MANY_AVAILABLE_STREAMS,
681 base::StringPrintf(
682 "%lu above %lu",
683 static_cast<unsigned long>(new_num_available_streams),
684 static_cast<unsigned long>(get_max_available_streams()))
685 .c_str());
674 return nullptr; 686 return nullptr;
675 } 687 }
676 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; id < stream_id; 688 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; id < stream_id;
677 id += 2) { 689 id += 2) {
678 available_streams_.insert(id); 690 available_streams_.insert(id);
679 } 691 }
680 largest_peer_created_stream_id_ = stream_id; 692 largest_peer_created_stream_id_ = stream_id;
681 } 693 }
682 // Check if the new number of open streams would cause the number of 694 // Check if the new number of open streams would cause the number of
683 // open streams to exceed the limit. 695 // open streams to exceed the limit.
684 size_t num_current_open_streams = 696 size_t num_current_open_streams =
685 FLAGS_quic_distinguish_incoming_outgoing_streams 697 FLAGS_quic_distinguish_incoming_outgoing_streams
686 ? GetNumOpenIncomingStreams() 698 ? GetNumOpenIncomingStreams()
687 : dynamic_stream_map_.size() - draining_streams_.size() + 699 : dynamic_stream_map_.size() - draining_streams_.size() +
688 locally_closed_streams_highest_offset_.size(); 700 locally_closed_streams_highest_offset_.size();
689 if (num_current_open_streams >= get_max_open_streams()) { 701 if (num_current_open_streams >= get_max_open_streams()) {
690 if (connection()->version() <= QUIC_VERSION_27) { 702 if (connection()->version() <= QUIC_VERSION_27) {
691 CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS); 703 CloseConnectionWithDetails(QUIC_TOO_MANY_OPEN_STREAMS,
704 "Old style stream rejection");
692 } else { 705 } else {
693 // Refuse to open the stream. 706 // Refuse to open the stream.
694 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); 707 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0);
695 } 708 }
696 return nullptr; 709 return nullptr;
697 } 710 }
698 ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id); 711 ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id);
699 if (stream == nullptr) { 712 if (stream == nullptr) {
700 return nullptr; 713 return nullptr;
701 } 714 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 } 823 }
811 } 824 }
812 return false; 825 return false;
813 } 826 }
814 827
815 bool QuicSession::IsIncomingStream(QuicStreamId id) const { 828 bool QuicSession::IsIncomingStream(QuicStreamId id) const {
816 return id % 2 != next_outgoing_stream_id_ % 2; 829 return id % 2 != next_outgoing_stream_id_ % 2;
817 } 830 }
818 831
819 } // namespace net 832 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_session.h ('k') | net/quic/quic_session_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698