| 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 "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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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("%lu above %lu", new_num_available_streams, |
| 682 get_max_available_streams()) |
| 683 .c_str()); |
| 674 return nullptr; | 684 return nullptr; |
| 675 } | 685 } |
| 676 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; | 686 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; |
| 677 id < stream_id; | 687 id < stream_id; |
| 678 id += 2) { | 688 id += 2) { |
| 679 available_streams_.insert(id); | 689 available_streams_.insert(id); |
| 680 } | 690 } |
| 681 largest_peer_created_stream_id_ = stream_id; | 691 largest_peer_created_stream_id_ = stream_id; |
| 682 } | 692 } |
| 683 // Check if the new number of open streams would cause the number of | 693 // Check if the new number of open streams would cause the number of |
| 684 // open streams to exceed the limit. | 694 // open streams to exceed the limit. |
| 685 size_t num_current_open_streams = | 695 size_t num_current_open_streams = |
| 686 FLAGS_quic_distinguish_incoming_outgoing_streams | 696 FLAGS_quic_distinguish_incoming_outgoing_streams |
| 687 ? GetNumOpenIncomingStreams() | 697 ? GetNumOpenIncomingStreams() |
| 688 : dynamic_stream_map_.size() - draining_streams_.size() + | 698 : dynamic_stream_map_.size() - draining_streams_.size() + |
| 689 locally_closed_streams_highest_offset_.size(); | 699 locally_closed_streams_highest_offset_.size(); |
| 690 if (num_current_open_streams >= get_max_open_streams()) { | 700 if (num_current_open_streams >= get_max_open_streams()) { |
| 691 if (connection()->version() <= QUIC_VERSION_27) { | 701 if (connection()->version() <= QUIC_VERSION_27) { |
| 692 CloseConnection(QUIC_TOO_MANY_OPEN_STREAMS); | 702 CloseConnectionWithDetails(QUIC_TOO_MANY_OPEN_STREAMS, |
| 703 "Old style stream rejection"); |
| 693 } else { | 704 } else { |
| 694 // Refuse to open the stream. | 705 // Refuse to open the stream. |
| 695 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); | 706 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); |
| 696 } | 707 } |
| 697 return nullptr; | 708 return nullptr; |
| 698 } | 709 } |
| 699 ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id); | 710 ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id); |
| 700 if (stream == nullptr) { | 711 if (stream == nullptr) { |
| 701 return nullptr; | 712 return nullptr; |
| 702 } | 713 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 } | 822 } |
| 812 } | 823 } |
| 813 return false; | 824 return false; |
| 814 } | 825 } |
| 815 | 826 |
| 816 bool QuicSession::IsIncomingStream(QuicStreamId id) const { | 827 bool QuicSession::IsIncomingStream(QuicStreamId id) const { |
| 817 return id % 2 != next_outgoing_stream_id_ % 2; | 828 return id % 2 != next_outgoing_stream_id_ % 2; |
| 818 } | 829 } |
| 819 | 830 |
| 820 } // namespace net | 831 } // namespace net |
| OLD | NEW |