| 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 current_client_address_, *current_packet_); | 272 current_client_address_, *current_packet_); |
| 273 return false; | 273 return false; |
| 274 } | 274 } |
| 275 | 275 |
| 276 if (FLAGS_quic_buffer_packets_after_chlo && | 276 if (FLAGS_quic_buffer_packets_after_chlo && |
| 277 buffered_packets_.HasChloForConnection(connection_id)) { | 277 buffered_packets_.HasChloForConnection(connection_id)) { |
| 278 BufferEarlyPacket(connection_id); | 278 BufferEarlyPacket(connection_id); |
| 279 return false; | 279 return false; |
| 280 } | 280 } |
| 281 | 281 |
| 282 // Check if we are buffering packets for this connection ID |
| 283 if (FLAGS_enable_async_get_proof && |
| 284 (temporarily_buffered_connections_.find(connection_id) != |
| 285 temporarily_buffered_connections_.end())) { |
| 286 // This packet was received while the a CHLO for the same connection ID was |
| 287 // being processed. Buffer it. |
| 288 BufferEarlyPacket(connection_id); |
| 289 return false; |
| 290 } |
| 291 |
| 282 if (!OnUnauthenticatedUnknownPublicHeader(header)) { | 292 if (!OnUnauthenticatedUnknownPublicHeader(header)) { |
| 283 return false; | 293 return false; |
| 284 } | 294 } |
| 285 | 295 |
| 286 // If the packet is a public reset for a connection ID that is not active, | 296 // If the packet is a public reset for a connection ID that is not active, |
| 287 // there is nothing we must do or can do. | 297 // there is nothing we must do or can do. |
| 288 if (header.reset_flag) { | 298 if (header.reset_flag) { |
| 289 return false; | 299 return false; |
| 290 } | 300 } |
| 291 | 301 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( | 361 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( |
| 352 QuicPacketFate fate, | 362 QuicPacketFate fate, |
| 353 QuicConnectionId connection_id, | 363 QuicConnectionId connection_id, |
| 354 QuicPacketNumber packet_number) { | 364 QuicPacketNumber packet_number) { |
| 355 switch (fate) { | 365 switch (fate) { |
| 356 case kFateProcess: { | 366 case kFateProcess: { |
| 357 ProcessChlo(); | 367 ProcessChlo(); |
| 358 break; | 368 break; |
| 359 } | 369 } |
| 360 case kFateTimeWait: | 370 case kFateTimeWait: |
| 361 // MaybeRejectStatelessly might have already added the connection to | 371 // MaybeRejectStatelessly or OnExpiredPackets might have already added the |
| 362 // time wait, in which case it should not be added again. | 372 // connection to time wait, in which case it should not be added again. |
| 363 if (!FLAGS_quic_use_cheap_stateless_rejects || | 373 if (!FLAGS_quic_use_cheap_stateless_rejects || |
| 364 !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { | 374 !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { |
| 365 // Add this connection_id to the time-wait state, to safely reject | 375 // Add this connection_id to the time-wait state, to safely reject |
| 366 // future packets. | 376 // future packets. |
| 367 DVLOG(1) << "Adding connection ID " << connection_id | 377 DVLOG(1) << "Adding connection ID " << connection_id |
| 368 << "to time-wait list."; | 378 << "to time-wait list."; |
| 369 time_wait_list_manager_->AddConnectionIdToTimeWait( | 379 time_wait_list_manager_->AddConnectionIdToTimeWait( |
| 370 connection_id, framer_.version(), | 380 connection_id, framer_.version(), |
| 371 /*connection_rejected_statelessly=*/false, nullptr); | 381 /*connection_rejected_statelessly=*/false, nullptr); |
| 372 } | 382 } |
| 373 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 383 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 374 time_wait_list_manager_->ProcessPacket( | 384 time_wait_list_manager_->ProcessPacket( |
| 375 current_server_address_, current_client_address_, connection_id, | 385 current_server_address_, current_client_address_, connection_id, |
| 376 packet_number, *current_packet_); | 386 packet_number, *current_packet_); |
| 387 |
| 388 if (FLAGS_enable_async_get_proof) { |
| 389 // Any packets which were buffered while the stateless rejector logic |
| 390 // was running should be discarded. Do not inform the time wait list |
| 391 // manager, which should already have a made a decision about sending a |
| 392 // reject based on the CHLO alone. |
| 393 buffered_packets_.DiscardPackets(connection_id); |
| 394 } |
| 395 |
| 377 break; | 396 break; |
| 378 case kFateBuffer: | 397 case kFateBuffer: |
| 379 // This packet is a non-CHLO packet which has arrived out of order. | 398 // This packet is a non-CHLO packet which has arrived before the |
| 380 // Buffer it. | 399 // corresponding CHLO, *or* this packet was received while the |
| 400 // corresponding CHLO was being processed. Buffer it. |
| 381 BufferEarlyPacket(connection_id); | 401 BufferEarlyPacket(connection_id); |
| 382 break; | 402 break; |
| 383 case kFateDrop: | 403 case kFateDrop: |
| 384 // Do nothing with the packet. | 404 // Do nothing with the packet. |
| 385 break; | 405 break; |
| 386 } | 406 } |
| 387 } | 407 } |
| 388 | 408 |
| 389 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks( | 409 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks( |
| 390 const QuicPacketHeader& header) { | 410 const QuicPacketHeader& header) { |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 return true; | 803 return true; |
| 784 } | 804 } |
| 785 | 805 |
| 786 class StatelessRejectorProcessDoneCallback | 806 class StatelessRejectorProcessDoneCallback |
| 787 : public StatelessRejector::ProcessDoneCallback { | 807 : public StatelessRejector::ProcessDoneCallback { |
| 788 public: | 808 public: |
| 789 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher, | 809 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher, |
| 790 QuicPacketNumber packet_number, | 810 QuicPacketNumber packet_number, |
| 791 QuicVersion first_version) | 811 QuicVersion first_version) |
| 792 : dispatcher_(dispatcher), | 812 : dispatcher_(dispatcher), |
| 813 current_client_address_(dispatcher->current_client_address_), |
| 814 current_server_address_(dispatcher->current_server_address_), |
| 815 current_packet_( |
| 816 dispatcher->current_packet_->Clone()), // Note: copies the packet |
| 793 packet_number_(packet_number), | 817 packet_number_(packet_number), |
| 794 first_version_(first_version) {} | 818 first_version_(first_version) {} |
| 795 | 819 |
| 796 void Run(std::unique_ptr<StatelessRejector> rejector) override { | 820 void Run(std::unique_ptr<StatelessRejector> rejector) override { |
| 797 dispatcher_->OnStatelessRejectorProcessDone(std::move(rejector), | 821 dispatcher_->OnStatelessRejectorProcessDone( |
| 798 packet_number_, first_version_); | 822 std::move(rejector), current_client_address_, current_server_address_, |
| 823 std::move(current_packet_), packet_number_, first_version_); |
| 799 } | 824 } |
| 800 | 825 |
| 801 private: | 826 private: |
| 802 QuicDispatcher* dispatcher_; | 827 QuicDispatcher* dispatcher_; |
| 828 IPEndPoint current_client_address_; |
| 829 IPEndPoint current_server_address_; |
| 830 std::unique_ptr<QuicReceivedPacket> current_packet_; |
| 803 QuicPacketNumber packet_number_; | 831 QuicPacketNumber packet_number_; |
| 804 QuicVersion first_version_; | 832 QuicVersion first_version_; |
| 805 }; | 833 }; |
| 806 | 834 |
| 807 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, | 835 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, |
| 808 const QuicPacketHeader& header) { | 836 const QuicPacketHeader& header) { |
| 809 // TODO(rch): This logic should probably live completely inside the rejector. | 837 // TODO(rch): This logic should probably live completely inside the rejector. |
| 810 if (!FLAGS_quic_use_cheap_stateless_rejects || | 838 if (!FLAGS_quic_use_cheap_stateless_rejects || |
| 811 !FLAGS_enable_quic_stateless_reject_support || | 839 !FLAGS_enable_quic_stateless_reject_support || |
| 812 header.public_header.versions.front() <= QUIC_VERSION_32 || | 840 header.public_header.versions.front() <= QUIC_VERSION_32 || |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), | 882 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), |
| 855 time_wait_list_manager_.get()); | 883 time_wait_list_manager_.get()); |
| 856 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, | 884 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, |
| 857 validator.error_details()); | 885 validator.error_details()); |
| 858 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); | 886 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); |
| 859 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, | 887 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, |
| 860 header.packet_number); | 888 header.packet_number); |
| 861 return; | 889 return; |
| 862 } | 890 } |
| 863 | 891 |
| 892 // If we were able to make a decision about this CHLO based purely on the |
| 893 // information available in OnChlo, just invoke the done callback immediately. |
| 894 if (rejector->state() != StatelessRejector::UNKNOWN) { |
| 895 ProcessStatelessRejectorState(std::move(rejector), header.packet_number, |
| 896 header.public_header.versions.front()); |
| 897 return; |
| 898 } |
| 899 |
| 900 // Insert into set of connection IDs to buffer |
| 901 if (FLAGS_enable_async_get_proof) { |
| 902 const bool ok = |
| 903 temporarily_buffered_connections_.insert(connection_id).second; |
| 904 QUIC_BUG_IF(!ok) |
| 905 << "Processing multiple stateless rejections for connection ID " |
| 906 << connection_id; |
| 907 } |
| 908 |
| 864 // Continue stateless rejector processing | 909 // Continue stateless rejector processing |
| 865 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb( | 910 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb( |
| 866 new StatelessRejectorProcessDoneCallback( | 911 new StatelessRejectorProcessDoneCallback( |
| 867 this, header.packet_number, header.public_header.versions.front())); | 912 this, header.packet_number, header.public_header.versions.front())); |
| 868 StatelessRejector::Process(std::move(rejector), std::move(cb)); | 913 StatelessRejector::Process(std::move(rejector), std::move(cb)); |
| 869 } | 914 } |
| 870 | 915 |
| 871 void QuicDispatcher::OnStatelessRejectorProcessDone( | 916 void QuicDispatcher::OnStatelessRejectorProcessDone( |
| 872 std::unique_ptr<StatelessRejector> rejector, | 917 std::unique_ptr<StatelessRejector> rejector, |
| 918 const IPEndPoint& current_client_address, |
| 919 const IPEndPoint& current_server_address, |
| 920 std::unique_ptr<QuicReceivedPacket> current_packet, |
| 921 QuicPacketNumber packet_number, |
| 922 QuicVersion first_version) { |
| 923 if (FLAGS_enable_async_get_proof) { |
| 924 // Stop buffering packets on this connection |
| 925 const auto num_erased = |
| 926 temporarily_buffered_connections_.erase(rejector->connection_id()); |
| 927 QUIC_BUG_IF(num_erased != 1) << "Completing stateless rejection logic for " |
| 928 "non-buffered connection ID " |
| 929 << rejector->connection_id(); |
| 930 |
| 931 // If this connection has gone into time-wait during the async processing, |
| 932 // don't proceed. |
| 933 if (time_wait_list_manager_->IsConnectionIdInTimeWait( |
| 934 rejector->connection_id())) { |
| 935 time_wait_list_manager_->ProcessPacket( |
| 936 current_server_address, current_client_address, |
| 937 rejector->connection_id(), packet_number, *current_packet); |
| 938 return; |
| 939 } |
| 940 } |
| 941 |
| 942 // Reset current_* to correspond to the packet which initiated the stateless |
| 943 // reject logic. |
| 944 current_client_address_ = current_client_address; |
| 945 current_server_address_ = current_server_address; |
| 946 current_packet_ = current_packet.get(); |
| 947 current_connection_id_ = rejector->connection_id(); |
| 948 |
| 949 ProcessStatelessRejectorState(std::move(rejector), packet_number, |
| 950 first_version); |
| 951 } |
| 952 |
| 953 void QuicDispatcher::ProcessStatelessRejectorState( |
| 954 std::unique_ptr<StatelessRejector> rejector, |
| 873 QuicPacketNumber packet_number, | 955 QuicPacketNumber packet_number, |
| 874 QuicVersion first_version) { | 956 QuicVersion first_version) { |
| 875 QuicPacketFate fate; | 957 QuicPacketFate fate; |
| 876 switch (rejector->state()) { | 958 switch (rejector->state()) { |
| 877 case StatelessRejector::FAILED: { | 959 case StatelessRejector::FAILED: { |
| 878 // There was an error processing the client hello. | 960 // There was an error processing the client hello. |
| 879 StatelessConnectionTerminator terminator(rejector->connection_id(), | 961 StatelessConnectionTerminator terminator(rejector->connection_id(), |
| 880 &framer_, helper(), | 962 &framer_, helper(), |
| 881 time_wait_list_manager_.get()); | 963 time_wait_list_manager_.get()); |
| 882 terminator.CloseConnection(rejector->error(), rejector->error_details()); | 964 terminator.CloseConnection(rejector->error(), rejector->error_details()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 void QuicDispatcher::DeliverPacketsToSession( | 1004 void QuicDispatcher::DeliverPacketsToSession( |
| 923 const std::list<BufferedPacket>& packets, | 1005 const std::list<BufferedPacket>& packets, |
| 924 QuicServerSessionBase* session) { | 1006 QuicServerSessionBase* session) { |
| 925 for (const BufferedPacket& packet : packets) { | 1007 for (const BufferedPacket& packet : packets) { |
| 926 session->ProcessUdpPacket(packet.server_address, packet.client_address, | 1008 session->ProcessUdpPacket(packet.server_address, packet.client_address, |
| 927 *(packet.packet)); | 1009 *(packet.packet)); |
| 928 } | 1010 } |
| 929 } | 1011 } |
| 930 | 1012 |
| 931 } // namespace net | 1013 } // namespace net |
| OLD | NEW |