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

Side by Side Diff: net/tools/quic/quic_dispatcher.cc

Issue 2850573002: Landing Recent QUIC changes until 3:35 PM, Apr 26, 2017 UTC-4 (Closed)
Patch Set: Remove Disconnect from ~QuicTestClient Created 3 years, 7 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/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_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/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/macros.h" 9 #include "base/macros.h"
10 #include "net/quic/core/crypto/quic_random.h" 10 #include "net/quic/core/crypto/quic_random.h"
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 framer_.set_version(version); 329 framer_.set_version(version);
330 return true; 330 return true;
331 } 331 }
332 332
333 bool QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) { 333 bool QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
334 QuicConnectionId connection_id = header.public_header.connection_id; 334 QuicConnectionId connection_id = header.public_header.connection_id;
335 335
336 if (time_wait_list_manager_->IsConnectionIdInTimeWait( 336 if (time_wait_list_manager_->IsConnectionIdInTimeWait(
337 header.public_header.connection_id)) { 337 header.public_header.connection_id)) {
338 // This connection ID is already in time-wait state. 338 // This connection ID is already in time-wait state.
339 time_wait_list_manager_->ProcessPacket( 339 time_wait_list_manager_->ProcessPacket(current_server_address_,
340 current_server_address_, current_client_address_, 340 current_client_address_,
341 header.public_header.connection_id, header.packet_number, 341 header.public_header.connection_id);
342 *current_packet_);
343 return false; 342 return false;
344 } 343 }
345 344
346 // Packet's connection ID is unknown. Apply the validity checks. 345 // Packet's connection ID is unknown. Apply the validity checks.
347 QuicPacketFate fate = ValidityChecks(header); 346 QuicPacketFate fate = ValidityChecks(header);
348 if (fate == kFateProcess) { 347 if (fate == kFateProcess) {
349 // Execute stateless rejection logic to determine the packet fate, then 348 // Execute stateless rejection logic to determine the packet fate, then
350 // invoke ProcessUnauthenticatedHeaderFate. 349 // invoke ProcessUnauthenticatedHeaderFate.
351 MaybeRejectStatelessly(connection_id, header); 350 MaybeRejectStatelessly(connection_id,
351 header.public_header.versions.front());
352 } else { 352 } else {
353 // If the fate is already known, process it without executing stateless 353 // If the fate is already known, process it without executing stateless
354 // rejection logic. 354 // rejection logic.
355 ProcessUnauthenticatedHeaderFate(fate, connection_id, header.packet_number); 355 ProcessUnauthenticatedHeaderFate(fate, connection_id);
356 } 356 }
357 357
358 return false; 358 return false;
359 } 359 }
360 360
361 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( 361 void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
362 QuicPacketFate fate, 362 QuicPacketFate fate,
363 QuicConnectionId connection_id, 363 QuicConnectionId connection_id) {
364 QuicPacketNumber packet_number) {
365 switch (fate) { 364 switch (fate) {
366 case kFateProcess: { 365 case kFateProcess: {
367 ProcessChlo(packet_number); 366 ProcessChlo();
368 break; 367 break;
369 } 368 }
370 case kFateTimeWait: 369 case kFateTimeWait:
371 // MaybeRejectStatelessly or OnExpiredPackets might have already added the 370 // MaybeRejectStatelessly or OnExpiredPackets might have already added the
372 // connection to time wait, in which case it should not be added again. 371 // connection to time wait, in which case it should not be added again.
373 if (!FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects || 372 if (!FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects ||
374 !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { 373 !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
375 // Add this connection_id to the time-wait state, to safely reject 374 // Add this connection_id to the time-wait state, to safely reject
376 // future packets. 375 // future packets.
377 QUIC_DLOG(INFO) << "Adding connection ID " << connection_id 376 QUIC_DLOG(INFO) << "Adding connection ID " << connection_id
378 << "to time-wait list."; 377 << "to time-wait list.";
379 time_wait_list_manager_->AddConnectionIdToTimeWait( 378 time_wait_list_manager_->AddConnectionIdToTimeWait(
380 connection_id, framer_.version(), 379 connection_id, framer_.version(),
381 /*connection_rejected_statelessly=*/false, nullptr); 380 /*connection_rejected_statelessly=*/false, nullptr);
382 } 381 }
383 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); 382 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
384 time_wait_list_manager_->ProcessPacket( 383 time_wait_list_manager_->ProcessPacket(
385 current_server_address_, current_client_address_, connection_id, 384 current_server_address_, current_client_address_, connection_id);
386 packet_number, *current_packet_);
387 385
388 // Any packets which were buffered while the stateless rejector logic was 386 // Any packets which were buffered while the stateless rejector logic was
389 // running should be discarded. Do not inform the time wait list manager, 387 // running should be discarded. Do not inform the time wait list manager,
390 // which should already have a made a decision about sending a reject 388 // which should already have a made a decision about sending a reject
391 // based on the CHLO alone. 389 // based on the CHLO alone.
392 buffered_packets_.DiscardPackets(connection_id); 390 buffered_packets_.DiscardPackets(connection_id);
393 break; 391 break;
394 case kFateBuffer: 392 case kFateBuffer:
395 // This packet is a non-CHLO packet which has arrived before the 393 // This packet is a non-CHLO packet which has arrived before the
396 // corresponding CHLO, *or* this packet was received while the 394 // corresponding CHLO, *or* this packet was received while the
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 connection_id, *current_packet_, current_server_address_, 708 connection_id, *current_packet_, current_server_address_,
711 current_client_address_, /*is_chlo=*/false); 709 current_client_address_, /*is_chlo=*/false);
712 if (rs != EnqueuePacketResult::SUCCESS) { 710 if (rs != EnqueuePacketResult::SUCCESS) {
713 OnBufferPacketFailure(rs, connection_id); 711 OnBufferPacketFailure(rs, connection_id);
714 } else if (!FLAGS_quic_reloadable_flag_quic_create_session_after_insertion && 712 } else if (!FLAGS_quic_reloadable_flag_quic_create_session_after_insertion &&
715 is_new_connection) { 713 is_new_connection) {
716 ShouldCreateOrBufferPacketForConnection(connection_id); 714 ShouldCreateOrBufferPacketForConnection(connection_id);
717 } 715 }
718 } 716 }
719 717
720 void QuicDispatcher::ProcessChlo(QuicPacketNumber packet_number) { 718 void QuicDispatcher::ProcessChlo() {
721 if (!accept_new_connections_) { 719 if (!accept_new_connections_) {
722 // Don't any create new connection. 720 // Don't any create new connection.
723 time_wait_list_manager()->AddConnectionIdToTimeWait( 721 time_wait_list_manager()->AddConnectionIdToTimeWait(
724 current_connection_id(), framer()->version(), 722 current_connection_id(), framer()->version(),
725 /*connection_rejected_statelessly=*/false, 723 /*connection_rejected_statelessly=*/false,
726 /*termination_packets=*/nullptr); 724 /*termination_packets=*/nullptr);
727 // This will trigger sending Public Reset packet. 725 // This will trigger sending Public Reset packet.
728 time_wait_list_manager()->ProcessPacket( 726 time_wait_list_manager()->ProcessPacket(current_server_address(),
729 current_server_address(), current_client_address(), 727 current_client_address(),
730 current_connection_id(), packet_number, current_packet()); 728 current_connection_id());
731 return; 729 return;
732 } 730 }
733 if (FLAGS_quic_reloadable_flag_quic_create_session_after_insertion && 731 if (FLAGS_quic_reloadable_flag_quic_create_session_after_insertion &&
734 !buffered_packets_.HasBufferedPackets(current_connection_id_) && 732 !buffered_packets_.HasBufferedPackets(current_connection_id_) &&
735 !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) { 733 !ShouldCreateOrBufferPacketForConnection(current_connection_id_)) {
736 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_create_session_after_insertion, 734 QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_create_session_after_insertion,
737 2, 5); 735 2, 5);
738 return; 736 return;
739 } 737 }
740 if (FLAGS_quic_allow_chlo_buffering && 738 if (FLAGS_quic_allow_chlo_buffering &&
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 806
809 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader( 807 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader(
810 const QuicPacketPublicHeader& header) { 808 const QuicPacketPublicHeader& header) {
811 return true; 809 return true;
812 } 810 }
813 811
814 class StatelessRejectorProcessDoneCallback 812 class StatelessRejectorProcessDoneCallback
815 : public StatelessRejector::ProcessDoneCallback { 813 : public StatelessRejector::ProcessDoneCallback {
816 public: 814 public:
817 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher, 815 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher,
818 QuicPacketNumber packet_number,
819 QuicVersion first_version) 816 QuicVersion first_version)
820 : dispatcher_(dispatcher), 817 : dispatcher_(dispatcher),
821 current_client_address_(dispatcher->current_client_address_), 818 current_client_address_(dispatcher->current_client_address_),
822 current_server_address_(dispatcher->current_server_address_), 819 current_server_address_(dispatcher->current_server_address_),
823 current_packet_( 820 current_packet_(
824 dispatcher->current_packet_->Clone()), // Note: copies the packet 821 dispatcher->current_packet_->Clone()), // Note: copies the packet
825 packet_number_(packet_number),
826 first_version_(first_version) {} 822 first_version_(first_version) {}
827 823
828 void Run(std::unique_ptr<StatelessRejector> rejector) override { 824 void Run(std::unique_ptr<StatelessRejector> rejector) override {
829 dispatcher_->OnStatelessRejectorProcessDone( 825 dispatcher_->OnStatelessRejectorProcessDone(
830 std::move(rejector), current_client_address_, current_server_address_, 826 std::move(rejector), current_client_address_, current_server_address_,
831 std::move(current_packet_), packet_number_, first_version_); 827 std::move(current_packet_), first_version_);
832 } 828 }
833 829
834 private: 830 private:
835 QuicDispatcher* dispatcher_; 831 QuicDispatcher* dispatcher_;
836 QuicSocketAddress current_client_address_; 832 QuicSocketAddress current_client_address_;
837 QuicSocketAddress current_server_address_; 833 QuicSocketAddress current_server_address_;
838 std::unique_ptr<QuicReceivedPacket> current_packet_; 834 std::unique_ptr<QuicReceivedPacket> current_packet_;
839 QuicPacketNumber packet_number_;
840 QuicVersion first_version_; 835 QuicVersion first_version_;
841 }; 836 };
842 837
843 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, 838 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
844 const QuicPacketHeader& header) { 839 QuicVersion version) {
845 // TODO(rch): This logic should probably live completely inside the rejector. 840 // TODO(rch): This logic should probably live completely inside the rejector.
846 if (!FLAGS_quic_allow_chlo_buffering || 841 if (!FLAGS_quic_allow_chlo_buffering ||
847 !FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects || 842 !FLAGS_quic_reloadable_flag_quic_use_cheap_stateless_rejects ||
848 !FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support || 843 !FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support ||
849 !ShouldAttemptCheapStatelessRejection()) { 844 !ShouldAttemptCheapStatelessRejection()) {
850 // Not use cheap stateless reject. 845 // Not use cheap stateless reject.
851 if (FLAGS_quic_allow_chlo_buffering && 846 if (FLAGS_quic_allow_chlo_buffering &&
852 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), 847 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
853 nullptr)) { 848 nullptr)) {
854 // Buffer non-CHLO packets. 849 // Buffer non-CHLO packets.
855 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, 850 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
856 header.packet_number);
857 return; 851 return;
858 } 852 }
859 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, 853 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id);
860 header.packet_number);
861 return; 854 return;
862 } 855 }
863 856
864 std::unique_ptr<StatelessRejector> rejector(new StatelessRejector( 857 std::unique_ptr<StatelessRejector> rejector(new StatelessRejector(
865 header.public_header.versions.front(), GetSupportedVersions(), 858 version, GetSupportedVersions(), crypto_config_, &compressed_certs_cache_,
866 crypto_config_, &compressed_certs_cache_, helper()->GetClock(), 859 helper()->GetClock(), helper()->GetRandomGenerator(),
867 helper()->GetRandomGenerator(), current_packet_->length(), 860 current_packet_->length(), current_client_address_,
868 current_client_address_, current_server_address_)); 861 current_server_address_));
869 ChloValidator validator(session_helper_.get(), current_server_address_, 862 ChloValidator validator(session_helper_.get(), current_server_address_,
870 rejector.get()); 863 rejector.get());
871 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), 864 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
872 &validator)) { 865 &validator)) {
873 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, 866 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id);
874 header.packet_number);
875 return; 867 return;
876 } 868 }
877 869
878 if (!validator.can_accept()) { 870 if (!validator.can_accept()) {
879 // This CHLO is prohibited by policy. 871 // This CHLO is prohibited by policy.
880 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), 872 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(),
881 time_wait_list_manager_.get()); 873 time_wait_list_manager_.get());
882 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, 874 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED,
883 validator.error_details()); 875 validator.error_details());
884 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); 876 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED);
885 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, 877 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id);
886 header.packet_number);
887 return; 878 return;
888 } 879 }
889 880
890 // If we were able to make a decision about this CHLO based purely on the 881 // If we were able to make a decision about this CHLO based purely on the
891 // information available in OnChlo, just invoke the done callback immediately. 882 // information available in OnChlo, just invoke the done callback immediately.
892 if (rejector->state() != StatelessRejector::UNKNOWN) { 883 if (rejector->state() != StatelessRejector::UNKNOWN) {
893 ProcessStatelessRejectorState(std::move(rejector), header.packet_number, 884 ProcessStatelessRejectorState(std::move(rejector), version);
894 header.public_header.versions.front());
895 return; 885 return;
896 } 886 }
897 887
898 // Insert into set of connection IDs to buffer 888 // Insert into set of connection IDs to buffer
899 const bool ok = 889 const bool ok =
900 temporarily_buffered_connections_.insert(connection_id).second; 890 temporarily_buffered_connections_.insert(connection_id).second;
901 QUIC_BUG_IF(!ok) 891 QUIC_BUG_IF(!ok)
902 << "Processing multiple stateless rejections for connection ID " 892 << "Processing multiple stateless rejections for connection ID "
903 << connection_id; 893 << connection_id;
904 894
905 // Continue stateless rejector processing 895 // Continue stateless rejector processing
906 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb( 896 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb(
907 new StatelessRejectorProcessDoneCallback( 897 new StatelessRejectorProcessDoneCallback(this, version));
908 this, header.packet_number, header.public_header.versions.front()));
909 StatelessRejector::Process(std::move(rejector), std::move(cb)); 898 StatelessRejector::Process(std::move(rejector), std::move(cb));
910 } 899 }
911 900
912 void QuicDispatcher::OnStatelessRejectorProcessDone( 901 void QuicDispatcher::OnStatelessRejectorProcessDone(
913 std::unique_ptr<StatelessRejector> rejector, 902 std::unique_ptr<StatelessRejector> rejector,
914 const QuicSocketAddress& current_client_address, 903 const QuicSocketAddress& current_client_address,
915 const QuicSocketAddress& current_server_address, 904 const QuicSocketAddress& current_server_address,
916 std::unique_ptr<QuicReceivedPacket> current_packet, 905 std::unique_ptr<QuicReceivedPacket> current_packet,
917 QuicPacketNumber packet_number,
918 QuicVersion first_version) { 906 QuicVersion first_version) {
919 // Stop buffering packets on this connection 907 // Stop buffering packets on this connection
920 const auto num_erased = 908 const auto num_erased =
921 temporarily_buffered_connections_.erase(rejector->connection_id()); 909 temporarily_buffered_connections_.erase(rejector->connection_id());
922 QUIC_BUG_IF(num_erased != 1) << "Completing stateless rejection logic for " 910 QUIC_BUG_IF(num_erased != 1) << "Completing stateless rejection logic for "
923 "non-buffered connection ID " 911 "non-buffered connection ID "
924 << rejector->connection_id(); 912 << rejector->connection_id();
925 913
926 // If this connection has gone into time-wait during the async processing, 914 // If this connection has gone into time-wait during the async processing,
927 // don't proceed. 915 // don't proceed.
928 if (time_wait_list_manager_->IsConnectionIdInTimeWait( 916 if (time_wait_list_manager_->IsConnectionIdInTimeWait(
929 rejector->connection_id())) { 917 rejector->connection_id())) {
930 time_wait_list_manager_->ProcessPacket( 918 time_wait_list_manager_->ProcessPacket(current_server_address,
931 current_server_address, current_client_address, 919 current_client_address,
932 rejector->connection_id(), packet_number, *current_packet); 920 rejector->connection_id());
933 return; 921 return;
934 } 922 }
935 923
936 // Reset current_* to correspond to the packet which initiated the stateless 924 // Reset current_* to correspond to the packet which initiated the stateless
937 // reject logic. 925 // reject logic.
938 current_client_address_ = current_client_address; 926 current_client_address_ = current_client_address;
939 current_server_address_ = current_server_address; 927 current_server_address_ = current_server_address;
940 current_packet_ = current_packet.get(); 928 current_packet_ = current_packet.get();
941 current_connection_id_ = rejector->connection_id(); 929 current_connection_id_ = rejector->connection_id();
942 930
943 ProcessStatelessRejectorState(std::move(rejector), packet_number, 931 ProcessStatelessRejectorState(std::move(rejector), first_version);
944 first_version);
945 } 932 }
946 933
947 void QuicDispatcher::ProcessStatelessRejectorState( 934 void QuicDispatcher::ProcessStatelessRejectorState(
948 std::unique_ptr<StatelessRejector> rejector, 935 std::unique_ptr<StatelessRejector> rejector,
949 QuicPacketNumber packet_number,
950 QuicVersion first_version) { 936 QuicVersion first_version) {
951 QuicPacketFate fate; 937 QuicPacketFate fate;
952 switch (rejector->state()) { 938 switch (rejector->state()) {
953 case StatelessRejector::FAILED: { 939 case StatelessRejector::FAILED: {
954 // There was an error processing the client hello. 940 // There was an error processing the client hello.
955 StatelessConnectionTerminator terminator(rejector->connection_id(), 941 StatelessConnectionTerminator terminator(rejector->connection_id(),
956 &framer_, helper(), 942 &framer_, helper(),
957 time_wait_list_manager_.get()); 943 time_wait_list_manager_.get());
958 terminator.CloseConnection(rejector->error(), rejector->error_details()); 944 terminator.CloseConnection(rejector->error(), rejector->error_details());
959 fate = kFateTimeWait; 945 fate = kFateTimeWait;
(...skipping 21 matching lines...) Expand all
981 OnConnectionRejectedStatelessly(); 967 OnConnectionRejectedStatelessly();
982 fate = kFateTimeWait; 968 fate = kFateTimeWait;
983 break; 969 break;
984 } 970 }
985 971
986 default: 972 default:
987 QUIC_BUG << "Rejector has invalid state " << rejector->state(); 973 QUIC_BUG << "Rejector has invalid state " << rejector->state();
988 fate = kFateDrop; 974 fate = kFateDrop;
989 break; 975 break;
990 } 976 }
991 ProcessUnauthenticatedHeaderFate(fate, rejector->connection_id(), 977 ProcessUnauthenticatedHeaderFate(fate, rejector->connection_id());
992 packet_number);
993 } 978 }
994 979
995 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { 980 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() {
996 return version_manager_->GetSupportedVersions(); 981 return version_manager_->GetSupportedVersions();
997 } 982 }
998 983
999 void QuicDispatcher::DeliverPacketsToSession( 984 void QuicDispatcher::DeliverPacketsToSession(
1000 const std::list<BufferedPacket>& packets, 985 const std::list<BufferedPacket>& packets,
1001 QuicSession* session) { 986 QuicSession* session) {
1002 for (const BufferedPacket& packet : packets) { 987 for (const BufferedPacket& packet : packets) {
1003 session->ProcessUdpPacket(packet.server_address, packet.client_address, 988 session->ProcessUdpPacket(packet.server_address, packet.client_address,
1004 *(packet.packet)); 989 *(packet.packet));
1005 } 990 }
1006 } 991 }
1007 992
1008 } // namespace net 993 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698