| 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/tools/quic/quic_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/debug/stack_trace.h" | 9 #include "base/debug/stack_trace.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 class StatelessConnectionTerminator { | 83 class StatelessConnectionTerminator { |
| 84 public: | 84 public: |
| 85 StatelessConnectionTerminator(QuicConnectionId connection_id, | 85 StatelessConnectionTerminator(QuicConnectionId connection_id, |
| 86 QuicFramer* framer, | 86 QuicFramer* framer, |
| 87 QuicConnectionHelperInterface* helper, | 87 QuicConnectionHelperInterface* helper, |
| 88 QuicTimeWaitListManager* time_wait_list_manager) | 88 QuicTimeWaitListManager* time_wait_list_manager) |
| 89 : connection_id_(connection_id), | 89 : connection_id_(connection_id), |
| 90 framer_(framer), | 90 framer_(framer), |
| 91 creator_(connection_id, | 91 creator_(connection_id, |
| 92 framer, | 92 framer, |
| 93 helper->GetRandomGenerator(), | |
| 94 helper->GetBufferAllocator(), | 93 helper->GetBufferAllocator(), |
| 95 &collector_), | 94 &collector_), |
| 96 time_wait_list_manager_(time_wait_list_manager) {} | 95 time_wait_list_manager_(time_wait_list_manager) {} |
| 97 | 96 |
| 98 // Generates a packet containing a CONNECTION_CLOSE frame specifying | 97 // Generates a packet containing a CONNECTION_CLOSE frame specifying |
| 99 // |error_code| and |error_details| and add the connection to time wait. | 98 // |error_code| and |error_details| and add the connection to time wait. |
| 100 void CloseConnection(QuicErrorCode error_code, | 99 void CloseConnection(QuicErrorCode error_code, |
| 101 const std::string& error_details) { | 100 const std::string& error_details) { |
| 102 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame; | 101 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame; |
| 103 frame->error_code = error_code; | 102 frame->error_code = error_code; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 return HandlePacketForTimeWait(header); | 304 return HandlePacketForTimeWait(header); |
| 306 } | 305 } |
| 307 | 306 |
| 308 // The packet has an unknown connection ID. | 307 // The packet has an unknown connection ID. |
| 309 | 308 |
| 310 // Unless the packet provides a version, assume that we can continue | 309 // Unless the packet provides a version, assume that we can continue |
| 311 // processing using our preferred version. | 310 // processing using our preferred version. |
| 312 QuicVersion version = GetSupportedVersions().front(); | 311 QuicVersion version = GetSupportedVersions().front(); |
| 313 if (header.version_flag) { | 312 if (header.version_flag) { |
| 314 QuicVersion packet_version = header.versions.front(); | 313 QuicVersion packet_version = header.versions.front(); |
| 314 if (FLAGS_quic_fix_version_manager && |
| 315 framer_.supported_versions() != GetSupportedVersions()) { |
| 316 // Reset framer's version if version flags change in flight. |
| 317 framer_.SetSupportedVersions(GetSupportedVersions()); |
| 318 } |
| 315 if (!framer_.IsSupportedVersion(packet_version)) { | 319 if (!framer_.IsSupportedVersion(packet_version)) { |
| 316 if (ShouldCreateSessionForUnknownVersion(framer_.last_version_tag())) { | 320 if (ShouldCreateSessionForUnknownVersion(framer_.last_version_tag())) { |
| 317 return true; | 321 return true; |
| 318 } | 322 } |
| 319 // Since the version is not supported, send a version negotiation | 323 // Since the version is not supported, send a version negotiation |
| 320 // packet and stop processing the current packet. | 324 // packet and stop processing the current packet. |
| 321 time_wait_list_manager()->SendVersionNegotiationPacket( | 325 time_wait_list_manager()->SendVersionNegotiationPacket( |
| 322 connection_id, GetSupportedVersions(), current_server_address_, | 326 connection_id, GetSupportedVersions(), current_server_address_, |
| 323 current_client_address_); | 327 current_client_address_); |
| 324 return false; | 328 return false; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 // set. Since this may be a client continuing a connection we lost track of | 426 // set. Since this may be a client continuing a connection we lost track of |
| 423 // via server restart, send a rejection to fast-fail the connection. | 427 // via server restart, send a rejection to fast-fail the connection. |
| 424 if (!header.public_header.version_flag) { | 428 if (!header.public_header.version_flag) { |
| 425 DVLOG(1) << "Packet without version arrived for unknown connection ID " | 429 DVLOG(1) << "Packet without version arrived for unknown connection ID " |
| 426 << header.public_header.connection_id; | 430 << header.public_header.connection_id; |
| 427 return kFateTimeWait; | 431 return kFateTimeWait; |
| 428 } | 432 } |
| 429 | 433 |
| 430 // Check that the sequence number is within the range that the client is | 434 // Check that the sequence number is within the range that the client is |
| 431 // expected to send before receiving a response from the server. | 435 // expected to send before receiving a response from the server. |
| 436 const int kInvalidPacketNumber = 0; |
| 432 if (header.packet_number == kInvalidPacketNumber || | 437 if (header.packet_number == kInvalidPacketNumber || |
| 433 header.packet_number > kMaxReasonableInitialPacketNumber) { | 438 header.packet_number > kMaxReasonableInitialPacketNumber) { |
| 434 return kFateTimeWait; | 439 return kFateTimeWait; |
| 435 } | 440 } |
| 436 | 441 |
| 437 return kFateProcess; | 442 return kFateProcess; |
| 438 } | 443 } |
| 439 | 444 |
| 440 void QuicDispatcher::CleanUpSession(SessionMap::iterator it, | 445 void QuicDispatcher::CleanUpSession(SessionMap::iterator it, |
| 441 QuicConnection* connection, | 446 QuicConnection* connection, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 DeleteSessions(); | 491 DeleteSessions(); |
| 487 } | 492 } |
| 488 | 493 |
| 489 void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id, | 494 void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id, |
| 490 QuicErrorCode error, | 495 QuicErrorCode error, |
| 491 const string& error_details) { | 496 const string& error_details) { |
| 492 SessionMap::iterator it = session_map_.find(connection_id); | 497 SessionMap::iterator it = session_map_.find(connection_id); |
| 493 if (it == session_map_.end()) { | 498 if (it == session_map_.end()) { |
| 494 QUIC_BUG << "ConnectionId " << connection_id | 499 QUIC_BUG << "ConnectionId " << connection_id |
| 495 << " does not exist in the session map. Error: " | 500 << " does not exist in the session map. Error: " |
| 496 << QuicUtils::ErrorToString(error); | 501 << QuicErrorCodeToString(error); |
| 497 QUIC_BUG << base::debug::StackTrace().ToString(); | 502 QUIC_BUG << base::debug::StackTrace().ToString(); |
| 498 return; | 503 return; |
| 499 } | 504 } |
| 500 | 505 |
| 501 DVLOG_IF(1, error != QUIC_NO_ERROR) | 506 DVLOG_IF(1, error != QUIC_NO_ERROR) |
| 502 << "Closing connection (" << connection_id | 507 << "Closing connection (" << connection_id |
| 503 << ") due to error: " << QuicUtils::ErrorToString(error) | 508 << ") due to error: " << QuicErrorCodeToString(error) |
| 504 << ", with details: " << error_details; | 509 << ", with details: " << error_details; |
| 505 | 510 |
| 506 if (closed_session_list_.empty()) { | 511 if (closed_session_list_.empty()) { |
| 507 delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(), | 512 delete_sessions_alarm_->Update(helper()->GetClock()->ApproximateNow(), |
| 508 QuicTime::Delta::Zero()); | 513 QuicTime::Delta::Zero()); |
| 509 } | 514 } |
| 510 QuicConnection* connection = it->second->connection(); | 515 QuicConnection* connection = it->second->connection(); |
| 511 closed_session_list_.push_back(std::move(it->second)); | 516 closed_session_list_.push_back(std::move(it->second)); |
| 512 const bool should_close_statelessly = | 517 const bool should_close_statelessly = |
| 513 (error == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT); | 518 (error == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 529 void QuicDispatcher::OnConnectionAddedToTimeWaitList( | 534 void QuicDispatcher::OnConnectionAddedToTimeWaitList( |
| 530 QuicConnectionId connection_id) { | 535 QuicConnectionId connection_id) { |
| 531 DVLOG(1) << "Connection " << connection_id << " added to time wait list."; | 536 DVLOG(1) << "Connection " << connection_id << " added to time wait list."; |
| 532 } | 537 } |
| 533 | 538 |
| 534 void QuicDispatcher::OnPacket() {} | 539 void QuicDispatcher::OnPacket() {} |
| 535 | 540 |
| 536 void QuicDispatcher::OnError(QuicFramer* framer) { | 541 void QuicDispatcher::OnError(QuicFramer* framer) { |
| 537 QuicErrorCode error = framer->error(); | 542 QuicErrorCode error = framer->error(); |
| 538 SetLastError(error); | 543 SetLastError(error); |
| 539 DVLOG(1) << QuicUtils::ErrorToString(error); | 544 DVLOG(1) << QuicErrorCodeToString(error); |
| 540 } | 545 } |
| 541 | 546 |
| 542 bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(QuicTag version_tag) { | 547 bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(QuicTag version_tag) { |
| 543 return false; | 548 return false; |
| 544 } | 549 } |
| 545 | 550 |
| 546 bool QuicDispatcher::OnProtocolVersionMismatch( | 551 bool QuicDispatcher::OnProtocolVersionMismatch( |
| 547 QuicVersion /*received_version*/) { | 552 QuicVersion /*received_version*/) { |
| 548 QUIC_BUG_IF(!time_wait_list_manager_->IsConnectionIdInTimeWait( | 553 QUIC_BUG_IF(!time_wait_list_manager_->IsConnectionIdInTimeWait( |
| 549 current_connection_id_) && | 554 current_connection_id_) && |
| 550 !ShouldCreateSessionForUnknownVersion(framer_.last_version_tag())) | 555 !ShouldCreateSessionForUnknownVersion(framer_.last_version_tag())) |
| 551 << "Unexpected version mismatch: " | 556 << "Unexpected version mismatch: " |
| 552 << QuicUtils::TagToString(framer_.last_version_tag()); | 557 << QuicTagToString(framer_.last_version_tag()); |
| 553 | 558 |
| 554 // Keep processing after protocol mismatch - this will be dealt with by the | 559 // Keep processing after protocol mismatch - this will be dealt with by the |
| 555 // time wait list or connection that we will create. | 560 // time wait list or connection that we will create. |
| 556 return true; | 561 return true; |
| 557 } | 562 } |
| 558 | 563 |
| 559 void QuicDispatcher::OnPublicResetPacket( | 564 void QuicDispatcher::OnPublicResetPacket( |
| 560 const QuicPublicResetPacket& /*packet*/) { | 565 const QuicPublicResetPacket& /*packet*/) { |
| 561 DCHECK(false); | 566 DCHECK(false); |
| 562 } | 567 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 ShouldCreateOrBufferPacketForConnection(connection_id); | 717 ShouldCreateOrBufferPacketForConnection(connection_id); |
| 713 } | 718 } |
| 714 } | 719 } |
| 715 | 720 |
| 716 void QuicDispatcher::ProcessChlo() { | 721 void QuicDispatcher::ProcessChlo() { |
| 717 if (FLAGS_quic_create_session_after_insertion && | 722 if (FLAGS_quic_create_session_after_insertion && |
| 718 !buffered_packets_.HasBufferedPackets(current_connection_id_) && | 723 !buffered_packets_.HasBufferedPackets(current_connection_id_) && |
| 719 !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) { | 724 !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) { |
| 720 return; | 725 return; |
| 721 } | 726 } |
| 722 | 727 if (FLAGS_quic_allow_chlo_buffering && |
| 723 if (FLAGS_quic_limit_num_new_sessions_per_epoll_loop && | 728 FLAGS_quic_limit_num_new_sessions_per_epoll_loop && |
| 724 new_sessions_allowed_per_event_loop_ <= 0) { | 729 new_sessions_allowed_per_event_loop_ <= 0) { |
| 725 // Can't create new session any more. Wait till next event loop. | 730 // Can't create new session any more. Wait till next event loop. |
| 726 if (!buffered_packets_.HasChloForConnection(current_connection_id_)) { | 731 if (!buffered_packets_.HasChloForConnection(current_connection_id_)) { |
| 727 // Only buffer one CHLO per connection. Remove this condition check when | 732 // Only buffer one CHLO per connection. Remove this condition check when |
| 728 // --gfe2_reloadable_flag_quic_buffer_packets_after_chlo | 733 // --gfe2_reloadable_flag_quic_buffer_packets_after_chlo |
| 729 // is deprecated because after that retransmitted CHLO should be buffered | 734 // is deprecated because after that retransmitted CHLO should be buffered |
| 730 // earlier in OnUnauthenticatedPublicHeader(). | 735 // earlier in OnUnauthenticatedPublicHeader(). |
| 731 bool is_new_connection = | 736 bool is_new_connection = |
| 732 !buffered_packets_.HasBufferedPackets(current_connection_id_); | 737 !buffered_packets_.HasBufferedPackets(current_connection_id_); |
| 733 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( | 738 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 IPEndPoint current_client_address_; | 826 IPEndPoint current_client_address_; |
| 822 IPEndPoint current_server_address_; | 827 IPEndPoint current_server_address_; |
| 823 std::unique_ptr<QuicReceivedPacket> current_packet_; | 828 std::unique_ptr<QuicReceivedPacket> current_packet_; |
| 824 QuicPacketNumber packet_number_; | 829 QuicPacketNumber packet_number_; |
| 825 QuicVersion first_version_; | 830 QuicVersion first_version_; |
| 826 }; | 831 }; |
| 827 | 832 |
| 828 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, | 833 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, |
| 829 const QuicPacketHeader& header) { | 834 const QuicPacketHeader& header) { |
| 830 // TODO(rch): This logic should probably live completely inside the rejector. | 835 // TODO(rch): This logic should probably live completely inside the rejector. |
| 831 if (!FLAGS_quic_use_cheap_stateless_rejects || | 836 if (!FLAGS_quic_allow_chlo_buffering || |
| 837 !FLAGS_quic_use_cheap_stateless_rejects || |
| 832 !FLAGS_enable_quic_stateless_reject_support || | 838 !FLAGS_enable_quic_stateless_reject_support || |
| 833 header.public_header.versions.front() <= QUIC_VERSION_32 || | |
| 834 !ShouldAttemptCheapStatelessRejection()) { | 839 !ShouldAttemptCheapStatelessRejection()) { |
| 835 // Not use cheap stateless reject. | 840 // Not use cheap stateless reject. |
| 836 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), | 841 if (FLAGS_quic_allow_chlo_buffering && |
| 842 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), |
| 837 nullptr)) { | 843 nullptr)) { |
| 838 // Buffer non-CHLO packets. | 844 // Buffer non-CHLO packets. |
| 839 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, | 845 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, |
| 840 header.packet_number); | 846 header.packet_number); |
| 841 return; | 847 return; |
| 842 } | 848 } |
| 843 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, | 849 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, |
| 844 header.packet_number); | 850 header.packet_number); |
| 845 return; | 851 return; |
| 846 } | 852 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 void QuicDispatcher::DeliverPacketsToSession( | 992 void QuicDispatcher::DeliverPacketsToSession( |
| 987 const std::list<BufferedPacket>& packets, | 993 const std::list<BufferedPacket>& packets, |
| 988 QuicSession* session) { | 994 QuicSession* session) { |
| 989 for (const BufferedPacket& packet : packets) { | 995 for (const BufferedPacket& packet : packets) { |
| 990 session->ProcessUdpPacket(packet.server_address, packet.client_address, | 996 session->ProcessUdpPacket(packet.server_address, packet.client_address, |
| 991 *(packet.packet)); | 997 *(packet.packet)); |
| 992 } | 998 } |
| 993 } | 999 } |
| 994 | 1000 |
| 995 } // namespace net | 1001 } // namespace net |
| OLD | NEW |