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 |