| 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 time_wait_list_manager_->ProcessPacket( | 321 time_wait_list_manager_->ProcessPacket( |
| 322 current_server_address_, current_client_address_, | 322 current_server_address_, current_client_address_, |
| 323 header.public_header.connection_id, header.packet_number, | 323 header.public_header.connection_id, header.packet_number, |
| 324 *current_packet_); | 324 *current_packet_); |
| 325 return false; | 325 return false; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Packet's connection ID is unknown. Apply the validity checks. | 328 // Packet's connection ID is unknown. Apply the validity checks. |
| 329 QuicPacketFate fate = ValidityChecks(header); | 329 QuicPacketFate fate = ValidityChecks(header); |
| 330 if (fate == kFateProcess) { | 330 if (fate == kFateProcess) { |
| 331 fate = MaybeRejectStatelessly(connection_id, header); | 331 // Execute stateless rejection logic to determine the packet fate, then |
| 332 // invoke ProcessUnauthenticatedHeaderFate. |
| 333 MaybeRejectStatelessly(connection_id, header); |
| 334 } else { |
| 335 // If the fate is already known, process it without executing stateless |
| 336 // rejection logic. |
| 337 ProcessUnauthenticatedHeaderFate(fate, connection_id, header.packet_number); |
| 332 } | 338 } |
| 333 | 339 |
| 334 // Perform whatever actions are needed on the current packet. | |
| 335 ProcessUnauthenticatedHeaderFate(fate, connection_id, header.packet_number); | |
| 336 return false; | 340 return false; |
| 337 } | 341 } |
| 338 | 342 |
| 339 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( | 343 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( |
| 340 QuicPacketFate fate, | 344 QuicPacketFate fate, |
| 341 QuicConnectionId connection_id, | 345 QuicConnectionId connection_id, |
| 342 QuicPacketNumber packet_number) { | 346 QuicPacketNumber packet_number) { |
| 343 switch (fate) { | 347 switch (fate) { |
| 344 case kFateProcess: { | 348 case kFateProcess: { |
| 345 ProcessChlo(); | 349 ProcessChlo(); |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 | 758 |
| 755 void QuicDispatcher::SetLastError(QuicErrorCode error) { | 759 void QuicDispatcher::SetLastError(QuicErrorCode error) { |
| 756 last_error_ = error; | 760 last_error_ = error; |
| 757 } | 761 } |
| 758 | 762 |
| 759 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader( | 763 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader( |
| 760 const QuicPacketPublicHeader& header) { | 764 const QuicPacketPublicHeader& header) { |
| 761 return true; | 765 return true; |
| 762 } | 766 } |
| 763 | 767 |
| 764 QuicDispatcher::QuicPacketFate QuicDispatcher::MaybeRejectStatelessly( | 768 class StatelessRejectorProcessDoneCallback |
| 765 QuicConnectionId connection_id, | 769 : public StatelessRejector::ProcessDoneCallback { |
| 766 const QuicPacketHeader& header) { | 770 public: |
| 771 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher, |
| 772 QuicPacketNumber packet_number, |
| 773 QuicVersion first_version) |
| 774 : dispatcher_(dispatcher), |
| 775 packet_number_(packet_number), |
| 776 first_version_(first_version) {} |
| 777 |
| 778 void Run(std::unique_ptr<StatelessRejector> rejector) override { |
| 779 dispatcher_->OnStatelessRejectorProcessDone(std::move(rejector), |
| 780 packet_number_, first_version_); |
| 781 } |
| 782 |
| 783 private: |
| 784 QuicDispatcher* dispatcher_; |
| 785 QuicPacketNumber packet_number_; |
| 786 QuicVersion first_version_; |
| 787 }; |
| 788 |
| 789 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, |
| 790 const QuicPacketHeader& header) { |
| 767 // TODO(rch): This logic should probably live completely inside the rejector. | 791 // TODO(rch): This logic should probably live completely inside the rejector. |
| 768 if (!FLAGS_quic_use_cheap_stateless_rejects || | 792 if (!FLAGS_quic_use_cheap_stateless_rejects || |
| 769 !FLAGS_enable_quic_stateless_reject_support || | 793 !FLAGS_enable_quic_stateless_reject_support || |
| 770 header.public_header.versions.front() <= QUIC_VERSION_32 || | 794 header.public_header.versions.front() <= QUIC_VERSION_32 || |
| 771 !ShouldAttemptCheapStatelessRejection()) { | 795 !ShouldAttemptCheapStatelessRejection()) { |
| 772 // Not use cheap stateless reject. | 796 // Not use cheap stateless reject. |
| 773 if (FLAGS_quic_buffer_packet_till_chlo && | 797 if (FLAGS_quic_buffer_packet_till_chlo && |
| 774 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), | 798 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), |
| 775 nullptr)) { | 799 nullptr)) { |
| 776 // Buffer non-CHLO packets. | 800 // Buffer non-CHLO packets. |
| 777 return kFateBuffer; | 801 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, |
| 802 header.packet_number); |
| 803 return; |
| 778 } | 804 } |
| 779 return kFateProcess; | 805 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, |
| 806 header.packet_number); |
| 807 return; |
| 780 } | 808 } |
| 781 | 809 |
| 782 StatelessRejector rejector( | 810 std::unique_ptr<StatelessRejector> rejector(new StatelessRejector( |
| 783 header.public_header.versions.front(), GetSupportedVersions(), | 811 header.public_header.versions.front(), GetSupportedVersions(), |
| 784 crypto_config_, &compressed_certs_cache_, helper()->GetClock(), | 812 crypto_config_, &compressed_certs_cache_, helper()->GetClock(), |
| 785 helper()->GetRandomGenerator(), current_packet_->length(), | 813 helper()->GetRandomGenerator(), current_packet_->length(), |
| 786 current_client_address_, current_server_address_); | 814 current_client_address_, current_server_address_)); |
| 787 ChloValidator validator(session_helper_.get(), current_server_address_, | 815 ChloValidator validator(session_helper_.get(), current_server_address_, |
| 788 &rejector); | 816 rejector.get()); |
| 789 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), | 817 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), |
| 790 &validator)) { | 818 &validator)) { |
| 791 if (!FLAGS_quic_buffer_packet_till_chlo) { | 819 if (!FLAGS_quic_buffer_packet_till_chlo) { |
| 792 QUIC_BUG | 820 QUIC_BUG |
| 793 << "Have to drop packet because buffering non-chlo packet is " | 821 << "Have to drop packet because buffering non-chlo packet is " |
| 794 "not supported while trying to do stateless reject. " | 822 "not supported while trying to do stateless reject. " |
| 795 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false" | 823 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false" |
| 796 " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"; | 824 " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"; |
| 797 return kFateDrop; | 825 ProcessUnauthenticatedHeaderFate(kFateDrop, connection_id, |
| 826 header.packet_number); |
| 827 return; |
| 798 } | 828 } |
| 799 return kFateBuffer; | 829 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, |
| 830 header.packet_number); |
| 831 return; |
| 800 } | 832 } |
| 801 | 833 |
| 802 if (!validator.can_accept()) { | 834 if (!validator.can_accept()) { |
| 803 // This CHLO is prohibited by policy. | 835 // This CHLO is prohibited by policy. |
| 804 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), | 836 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), |
| 805 time_wait_list_manager_.get()); | 837 time_wait_list_manager_.get()); |
| 806 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, | 838 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, |
| 807 validator.error_details()); | 839 validator.error_details()); |
| 808 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); | 840 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); |
| 809 return kFateTimeWait; | 841 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, |
| 842 header.packet_number); |
| 843 return; |
| 810 } | 844 } |
| 811 | 845 |
| 812 // This packet included a CHLO. See if it can be rejected statelessly. | 846 // Continue stateless rejector processing |
| 813 switch (rejector.state()) { | 847 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb( |
| 848 new StatelessRejectorProcessDoneCallback( |
| 849 this, header.packet_number, header.public_header.versions.front())); |
| 850 StatelessRejector::Process(std::move(rejector), std::move(cb)); |
| 851 } |
| 852 |
| 853 void QuicDispatcher::OnStatelessRejectorProcessDone( |
| 854 std::unique_ptr<StatelessRejector> rejector, |
| 855 QuicPacketNumber packet_number, |
| 856 QuicVersion first_version) { |
| 857 QuicPacketFate fate; |
| 858 switch (rejector->state()) { |
| 814 case StatelessRejector::FAILED: { | 859 case StatelessRejector::FAILED: { |
| 815 // There was an error processing the client hello. | 860 // There was an error processing the client hello. |
| 816 StatelessConnectionTerminator terminator( | 861 StatelessConnectionTerminator terminator(rejector->connection_id(), |
| 817 connection_id, &framer_, helper(), time_wait_list_manager_.get()); | 862 &framer_, helper(), |
| 818 terminator.CloseConnection(rejector.error(), rejector.error_details()); | 863 time_wait_list_manager_.get()); |
| 819 return kFateTimeWait; | 864 terminator.CloseConnection(rejector->error(), rejector->error_details()); |
| 865 fate = kFateTimeWait; |
| 866 break; |
| 820 } | 867 } |
| 821 | 868 |
| 822 case StatelessRejector::UNSUPPORTED: | 869 case StatelessRejector::UNSUPPORTED: |
| 823 // Cheap stateless rejects are not supported so process the packet. | 870 // Cheap stateless rejects are not supported so process the packet. |
| 824 return kFateProcess; | 871 fate = kFateProcess; |
| 872 break; |
| 825 | 873 |
| 826 case StatelessRejector::ACCEPTED: | 874 case StatelessRejector::ACCEPTED: |
| 827 // Contains a valid CHLO, so process the packet and create a connection. | 875 // Contains a valid CHLO, so process the packet and create a connection. |
| 828 return kFateProcess; | 876 fate = kFateProcess; |
| 877 break; |
| 829 | 878 |
| 830 case StatelessRejector::REJECTED: { | 879 case StatelessRejector::REJECTED: { |
| 831 DCHECK_EQ(framer_.version(), header.public_header.versions.front()); | 880 DCHECK_EQ(framer_.version(), first_version); |
| 832 StatelessConnectionTerminator terminator( | 881 StatelessConnectionTerminator terminator(rejector->connection_id(), |
| 833 connection_id, &framer_, helper(), time_wait_list_manager_.get()); | 882 &framer_, helper(), |
| 883 time_wait_list_manager_.get()); |
| 834 terminator.RejectConnection( | 884 terminator.RejectConnection( |
| 835 rejector.reply().GetSerialized().AsStringPiece()); | 885 rejector->reply().GetSerialized().AsStringPiece()); |
| 836 OnConnectionRejectedStatelessly(); | 886 OnConnectionRejectedStatelessly(); |
| 837 return kFateTimeWait; | 887 fate = kFateTimeWait; |
| 888 break; |
| 838 } | 889 } |
| 890 |
| 891 default: |
| 892 QUIC_BUG << "Rejector has invalid state " << rejector->state(); |
| 893 fate = kFateDrop; |
| 894 break; |
| 839 } | 895 } |
| 840 | 896 ProcessUnauthenticatedHeaderFate(fate, rejector->connection_id(), |
| 841 QUIC_BUG << "Rejector has unknown invalid state."; | 897 packet_number); |
| 842 return kFateDrop; | |
| 843 } | 898 } |
| 844 | 899 |
| 845 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { | 900 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { |
| 846 return version_manager_->GetSupportedVersions(); | 901 return version_manager_->GetSupportedVersions(); |
| 847 } | 902 } |
| 848 | 903 |
| 849 void QuicDispatcher::DeliverPacketsToSession( | 904 void QuicDispatcher::DeliverPacketsToSession( |
| 850 const std::list<BufferedPacket>& packets, | 905 const std::list<BufferedPacket>& packets, |
| 851 QuicServerSessionBase* session) { | 906 QuicServerSessionBase* session) { |
| 852 for (const BufferedPacket& packet : packets) { | 907 for (const BufferedPacket& packet : packets) { |
| 853 session->ProcessUdpPacket(packet.server_address, packet.client_address, | 908 session->ProcessUdpPacket(packet.server_address, packet.client_address, |
| 854 *(packet.packet)); | 909 *(packet.packet)); |
| 855 } | 910 } |
| 856 } | 911 } |
| 857 | 912 |
| 858 } // namespace net | 913 } // namespace net |
| OLD | NEW |