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 |