| 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" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "net/quic/core/crypto/quic_random.h" | 13 #include "net/quic/core/crypto/quic_random.h" |
| 14 #include "net/quic/core/quic_bug_tracker.h" | 14 #include "net/quic/core/quic_bug_tracker.h" |
| 15 #include "net/quic/core/quic_flags.h" | 15 #include "net/quic/core/quic_flags.h" |
| 16 #include "net/quic/core/quic_utils.h" | 16 #include "net/quic/core/quic_utils.h" |
| 17 |
| 17 #include "net/tools/quic/chlo_extractor.h" | 18 #include "net/tools/quic/chlo_extractor.h" |
| 18 #include "net/tools/quic/quic_per_connection_packet_writer.h" | 19 #include "net/tools/quic/quic_per_connection_packet_writer.h" |
| 19 #include "net/tools/quic/quic_simple_server_session.h" | 20 #include "net/tools/quic/quic_simple_server_session.h" |
| 21 #include "net/tools/quic/quic_simple_server_session.h" |
| 20 #include "net/tools/quic/quic_time_wait_list_manager.h" | 22 #include "net/tools/quic/quic_time_wait_list_manager.h" |
| 21 #include "net/tools/quic/stateless_rejector.h" | 23 #include "net/tools/quic/stateless_rejector.h" |
| 22 | 24 |
| 23 using base::StringPiece; | 25 using base::StringPiece; |
| 24 using std::list; | 26 using std::list; |
| 25 using std::string; | 27 using std::string; |
| 26 | 28 |
| 27 namespace net { | 29 namespace net { |
| 28 | 30 |
| 29 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; | 31 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 // Set as the visitor of |creator_| to collect any generated packets. | 150 // Set as the visitor of |creator_| to collect any generated packets. |
| 149 PacketCollector collector_; | 151 PacketCollector collector_; |
| 150 QuicPacketCreator creator_; | 152 QuicPacketCreator creator_; |
| 151 QuicTimeWaitListManager* time_wait_list_manager_; | 153 QuicTimeWaitListManager* time_wait_list_manager_; |
| 152 }; | 154 }; |
| 153 | 155 |
| 154 // Class which sits between the ChloExtractor and the StatelessRejector | 156 // Class which sits between the ChloExtractor and the StatelessRejector |
| 155 // to give the QuicDispatcher a chance to apply policy checks to the CHLO. | 157 // to give the QuicDispatcher a chance to apply policy checks to the CHLO. |
| 156 class ChloValidator : public ChloExtractor::Delegate { | 158 class ChloValidator : public ChloExtractor::Delegate { |
| 157 public: | 159 public: |
| 158 ChloValidator(QuicServerSessionBase::Helper* helper, | 160 ChloValidator(QuicCryptoServerStream::Helper* helper, |
| 159 IPEndPoint self_address, | 161 IPEndPoint self_address, |
| 160 StatelessRejector* rejector) | 162 StatelessRejector* rejector) |
| 161 : helper_(helper), | 163 : helper_(helper), |
| 162 self_address_(self_address), | 164 self_address_(self_address), |
| 163 rejector_(rejector), | 165 rejector_(rejector), |
| 164 can_accept_(false) {} | 166 can_accept_(false) {} |
| 165 | 167 |
| 166 // ChloExtractor::Delegate implementation. | 168 // ChloExtractor::Delegate implementation. |
| 167 void OnChlo(QuicVersion version, | 169 void OnChlo(QuicVersion version, |
| 168 QuicConnectionId connection_id, | 170 QuicConnectionId connection_id, |
| 169 const CryptoHandshakeMessage& chlo) override { | 171 const CryptoHandshakeMessage& chlo) override { |
| 170 if (helper_->CanAcceptClientHello(chlo, self_address_, &error_details_)) { | 172 if (helper_->CanAcceptClientHello(chlo, self_address_, &error_details_)) { |
| 171 can_accept_ = true; | 173 can_accept_ = true; |
| 172 rejector_->OnChlo(version, connection_id, | 174 rejector_->OnChlo(version, connection_id, |
| 173 helper_->GenerateConnectionIdForReject(connection_id), | 175 helper_->GenerateConnectionIdForReject(connection_id), |
| 174 chlo); | 176 chlo); |
| 175 } | 177 } |
| 176 } | 178 } |
| 177 | 179 |
| 178 bool can_accept() const { return can_accept_; } | 180 bool can_accept() const { return can_accept_; } |
| 179 | 181 |
| 180 const string& error_details() const { return error_details_; } | 182 const string& error_details() const { return error_details_; } |
| 181 | 183 |
| 182 private: | 184 private: |
| 183 QuicServerSessionBase::Helper* helper_; // Unowned. | 185 QuicCryptoServerStream::Helper* helper_; // Unowned. |
| 184 IPEndPoint self_address_; | 186 IPEndPoint self_address_; |
| 185 StatelessRejector* rejector_; // Unowned. | 187 StatelessRejector* rejector_; // Unowned. |
| 186 bool can_accept_; | 188 bool can_accept_; |
| 187 string error_details_; | 189 string error_details_; |
| 188 }; | 190 }; |
| 189 | 191 |
| 190 } // namespace | 192 } // namespace |
| 191 | 193 |
| 192 QuicDispatcher::QuicDispatcher( | 194 QuicDispatcher::QuicDispatcher( |
| 193 const QuicConfig& config, | 195 const QuicConfig& config, |
| 194 const QuicCryptoServerConfig* crypto_config, | 196 const QuicCryptoServerConfig* crypto_config, |
| 195 QuicVersionManager* version_manager, | 197 QuicVersionManager* version_manager, |
| 196 std::unique_ptr<QuicConnectionHelperInterface> helper, | 198 std::unique_ptr<QuicConnectionHelperInterface> helper, |
| 197 std::unique_ptr<QuicServerSessionBase::Helper> session_helper, | 199 std::unique_ptr<QuicCryptoServerStream::Helper> session_helper, |
| 198 std::unique_ptr<QuicAlarmFactory> alarm_factory) | 200 std::unique_ptr<QuicAlarmFactory> alarm_factory) |
| 199 : config_(config), | 201 : config_(config), |
| 200 crypto_config_(crypto_config), | 202 crypto_config_(crypto_config), |
| 201 compressed_certs_cache_( | 203 compressed_certs_cache_( |
| 202 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), | 204 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), |
| 203 helper_(std::move(helper)), | 205 helper_(std::move(helper)), |
| 204 session_helper_(std::move(session_helper)), | 206 session_helper_(std::move(session_helper)), |
| 205 alarm_factory_(std::move(alarm_factory)), | 207 alarm_factory_(std::move(alarm_factory)), |
| 206 delete_sessions_alarm_( | 208 delete_sessions_alarm_( |
| 207 alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))), | 209 alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))), |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 if (time_wait_list_manager_->IsConnectionIdInTimeWait( | 320 if (time_wait_list_manager_->IsConnectionIdInTimeWait( |
| 319 header.public_header.connection_id)) { | 321 header.public_header.connection_id)) { |
| 320 // This connection ID is already in time-wait state. | 322 // This connection ID is already in time-wait state. |
| 321 time_wait_list_manager_->ProcessPacket( | 323 time_wait_list_manager_->ProcessPacket( |
| 322 current_server_address_, current_client_address_, | 324 current_server_address_, current_client_address_, |
| 323 header.public_header.connection_id, header.packet_number, | 325 header.public_header.connection_id, header.packet_number, |
| 324 *current_packet_); | 326 *current_packet_); |
| 325 return false; | 327 return false; |
| 326 } | 328 } |
| 327 | 329 |
| 328 // Packet's connection ID is unknown. | 330 // Packet's connection ID is unknown. Apply the validity checks. |
| 329 // Apply the validity checks. | |
| 330 QuicPacketFate fate = ValidityChecks(header); | 331 QuicPacketFate fate = ValidityChecks(header); |
| 331 if (fate == kFateProcess) { | 332 if (fate == kFateProcess) { |
| 332 fate = MaybeRejectStatelessly(connection_id, header); | 333 // Execute stateless rejection logic to determine the packet fate, then |
| 334 // invoke ProcessUnauthenticatedHeaderFate. |
| 335 MaybeRejectStatelessly(connection_id, header); |
| 336 } else { |
| 337 // If the fate is already known, process it without executing stateless |
| 338 // rejection logic. |
| 339 ProcessUnauthenticatedHeaderFate(fate, connection_id, header.packet_number); |
| 333 } | 340 } |
| 341 |
| 342 return false; |
| 343 } |
| 344 |
| 345 void QuicDispatcher::ProcessUnauthenticatedHeaderFate( |
| 346 QuicPacketFate fate, |
| 347 QuicConnectionId connection_id, |
| 348 QuicPacketNumber packet_number) { |
| 334 switch (fate) { | 349 switch (fate) { |
| 335 case kFateProcess: { | 350 case kFateProcess: { |
| 336 ProcessChlo(); | 351 ProcessChlo(); |
| 337 break; | 352 break; |
| 338 } | 353 } |
| 339 case kFateTimeWait: | 354 case kFateTimeWait: |
| 340 // MaybeRejectStatelessly might have already added the connection to | 355 // MaybeRejectStatelessly might have already added the connection to |
| 341 // time wait, in which case it should not be added again. | 356 // time wait, in which case it should not be added again. |
| 342 if (!FLAGS_quic_use_cheap_stateless_rejects || | 357 if (!FLAGS_quic_use_cheap_stateless_rejects || |
| 343 !time_wait_list_manager_->IsConnectionIdInTimeWait( | 358 !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { |
| 344 header.public_header.connection_id)) { | |
| 345 // Add this connection_id to the time-wait state, to safely reject | 359 // Add this connection_id to the time-wait state, to safely reject |
| 346 // future packets. | 360 // future packets. |
| 347 DVLOG(1) << "Adding connection ID " << connection_id | 361 DVLOG(1) << "Adding connection ID " << connection_id |
| 348 << "to time-wait list."; | 362 << "to time-wait list."; |
| 349 time_wait_list_manager_->AddConnectionIdToTimeWait( | 363 time_wait_list_manager_->AddConnectionIdToTimeWait( |
| 350 connection_id, framer_.version(), | 364 connection_id, framer_.version(), |
| 351 /*connection_rejected_statelessly=*/false, nullptr); | 365 /*connection_rejected_statelessly=*/false, nullptr); |
| 352 } | 366 } |
| 353 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait( | 367 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
| 354 header.public_header.connection_id)); | |
| 355 time_wait_list_manager_->ProcessPacket( | 368 time_wait_list_manager_->ProcessPacket( |
| 356 current_server_address_, current_client_address_, | 369 current_server_address_, current_client_address_, connection_id, |
| 357 header.public_header.connection_id, header.packet_number, | 370 packet_number, *current_packet_); |
| 358 *current_packet_); | |
| 359 break; | 371 break; |
| 360 case kFateBuffer: | 372 case kFateBuffer: |
| 361 // This packet is a non-CHLO packet which has arrived out of order. | 373 // This packet is a non-CHLO packet which has arrived out of order. |
| 362 // Buffer it. | 374 // Buffer it. |
| 363 BufferEarlyPacket(connection_id); | 375 BufferEarlyPacket(connection_id); |
| 364 break; | 376 break; |
| 365 case kFateDrop: | 377 case kFateDrop: |
| 366 // Do nothing with the packet. | 378 // Do nothing with the packet. |
| 367 break; | 379 break; |
| 368 } | 380 } |
| 369 | |
| 370 return false; | |
| 371 } | 381 } |
| 372 | 382 |
| 373 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks( | 383 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks( |
| 374 const QuicPacketHeader& header) { | 384 const QuicPacketHeader& header) { |
| 375 // To have all the checks work properly without tears, insert any new check | 385 // To have all the checks work properly without tears, insert any new check |
| 376 // into the framework of this method in the section for checks that return the | 386 // into the framework of this method in the section for checks that return the |
| 377 // check's fate value. The sections for checks must be ordered with the | 387 // check's fate value. The sections for checks must be ordered with the |
| 378 // highest priority fate first. | 388 // highest priority fate first. |
| 379 | 389 |
| 380 // Checks that return kFateDrop. | 390 // Checks that return kFateDrop. |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 | 760 |
| 751 void QuicDispatcher::SetLastError(QuicErrorCode error) { | 761 void QuicDispatcher::SetLastError(QuicErrorCode error) { |
| 752 last_error_ = error; | 762 last_error_ = error; |
| 753 } | 763 } |
| 754 | 764 |
| 755 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader( | 765 bool QuicDispatcher::OnUnauthenticatedUnknownPublicHeader( |
| 756 const QuicPacketPublicHeader& header) { | 766 const QuicPacketPublicHeader& header) { |
| 757 return true; | 767 return true; |
| 758 } | 768 } |
| 759 | 769 |
| 760 QuicDispatcher::QuicPacketFate QuicDispatcher::MaybeRejectStatelessly( | 770 class StatelessRejectorProcessDoneCallback |
| 761 QuicConnectionId connection_id, | 771 : public StatelessRejector::ProcessDoneCallback { |
| 762 const QuicPacketHeader& header) { | 772 public: |
| 773 StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher, |
| 774 QuicPacketNumber packet_number, |
| 775 QuicVersion first_version) |
| 776 : dispatcher_(dispatcher), |
| 777 packet_number_(packet_number), |
| 778 first_version_(first_version) {} |
| 779 |
| 780 void Run(std::unique_ptr<StatelessRejector> rejector) override { |
| 781 dispatcher_->OnStatelessRejectorProcessDone(std::move(rejector), |
| 782 packet_number_, first_version_); |
| 783 } |
| 784 |
| 785 private: |
| 786 QuicDispatcher* dispatcher_; |
| 787 QuicPacketNumber packet_number_; |
| 788 QuicVersion first_version_; |
| 789 }; |
| 790 |
| 791 void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id, |
| 792 const QuicPacketHeader& header) { |
| 763 // TODO(rch): This logic should probably live completely inside the rejector. | 793 // TODO(rch): This logic should probably live completely inside the rejector. |
| 764 if (!FLAGS_quic_use_cheap_stateless_rejects || | 794 if (!FLAGS_quic_use_cheap_stateless_rejects || |
| 765 !FLAGS_enable_quic_stateless_reject_support || | 795 !FLAGS_enable_quic_stateless_reject_support || |
| 766 header.public_header.versions.front() <= QUIC_VERSION_32 || | 796 header.public_header.versions.front() <= QUIC_VERSION_32 || |
| 767 !ShouldAttemptCheapStatelessRejection()) { | 797 !ShouldAttemptCheapStatelessRejection()) { |
| 768 // Not use cheap stateless reject. | 798 // Not use cheap stateless reject. |
| 769 if (FLAGS_quic_buffer_packet_till_chlo && | 799 if (FLAGS_quic_buffer_packet_till_chlo && |
| 770 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), | 800 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), |
| 771 nullptr)) { | 801 nullptr)) { |
| 772 // Buffer non-CHLO packets. | 802 // Buffer non-CHLO packets. |
| 773 return kFateBuffer; | 803 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, |
| 804 header.packet_number); |
| 805 return; |
| 774 } | 806 } |
| 775 return kFateProcess; | 807 ProcessUnauthenticatedHeaderFate(kFateProcess, connection_id, |
| 808 header.packet_number); |
| 809 return; |
| 776 } | 810 } |
| 777 | 811 |
| 778 StatelessRejector rejector( | 812 std::unique_ptr<StatelessRejector> rejector(new StatelessRejector( |
| 779 header.public_header.versions.front(), GetSupportedVersions(), | 813 header.public_header.versions.front(), GetSupportedVersions(), |
| 780 crypto_config_, &compressed_certs_cache_, helper()->GetClock(), | 814 crypto_config_, &compressed_certs_cache_, helper()->GetClock(), |
| 781 helper()->GetRandomGenerator(), current_packet_->length(), | 815 helper()->GetRandomGenerator(), current_packet_->length(), |
| 782 current_client_address_, current_server_address_); | 816 current_client_address_, current_server_address_)); |
| 783 ChloValidator validator(session_helper_.get(), current_server_address_, | 817 ChloValidator validator(session_helper_.get(), current_server_address_, |
| 784 &rejector); | 818 rejector.get()); |
| 785 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), | 819 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), |
| 786 &validator)) { | 820 &validator)) { |
| 787 if (!FLAGS_quic_buffer_packet_till_chlo) { | 821 if (!FLAGS_quic_buffer_packet_till_chlo) { |
| 788 QUIC_BUG | 822 QUIC_BUG |
| 789 << "Have to drop packet because buffering non-chlo packet is " | 823 << "Have to drop packet because buffering non-chlo packet is " |
| 790 "not supported while trying to do stateless reject. " | 824 "not supported while trying to do stateless reject. " |
| 791 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false" | 825 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false" |
| 792 " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"; | 826 " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"; |
| 793 return kFateDrop; | 827 ProcessUnauthenticatedHeaderFate(kFateDrop, connection_id, |
| 828 header.packet_number); |
| 829 return; |
| 794 } | 830 } |
| 795 return kFateBuffer; | 831 ProcessUnauthenticatedHeaderFate(kFateBuffer, connection_id, |
| 832 header.packet_number); |
| 833 return; |
| 796 } | 834 } |
| 797 | 835 |
| 798 if (!validator.can_accept()) { | 836 if (!validator.can_accept()) { |
| 799 // This CHLO is prohibited by policy. | 837 // This CHLO is prohibited by policy. |
| 800 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), | 838 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), |
| 801 time_wait_list_manager_.get()); | 839 time_wait_list_manager_.get()); |
| 802 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, | 840 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, |
| 803 validator.error_details()); | 841 validator.error_details()); |
| 804 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); | 842 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); |
| 805 return kFateTimeWait; | 843 ProcessUnauthenticatedHeaderFate(kFateTimeWait, connection_id, |
| 844 header.packet_number); |
| 845 return; |
| 806 } | 846 } |
| 807 | 847 |
| 808 // This packet included a CHLO. See if it can be rejected statelessly. | 848 // Continue stateless rejector processing |
| 809 switch (rejector.state()) { | 849 std::unique_ptr<StatelessRejectorProcessDoneCallback> cb( |
| 850 new StatelessRejectorProcessDoneCallback( |
| 851 this, header.packet_number, header.public_header.versions.front())); |
| 852 StatelessRejector::Process(std::move(rejector), std::move(cb)); |
| 853 } |
| 854 |
| 855 void QuicDispatcher::OnStatelessRejectorProcessDone( |
| 856 std::unique_ptr<StatelessRejector> rejector, |
| 857 QuicPacketNumber packet_number, |
| 858 QuicVersion first_version) { |
| 859 QuicPacketFate fate; |
| 860 switch (rejector->state()) { |
| 810 case StatelessRejector::FAILED: { | 861 case StatelessRejector::FAILED: { |
| 811 // There was an error processing the client hello. | 862 // There was an error processing the client hello. |
| 812 StatelessConnectionTerminator terminator( | 863 StatelessConnectionTerminator terminator(rejector->connection_id(), |
| 813 connection_id, &framer_, helper(), time_wait_list_manager_.get()); | 864 &framer_, helper(), |
| 814 terminator.CloseConnection(rejector.error(), rejector.error_details()); | 865 time_wait_list_manager_.get()); |
| 815 return kFateTimeWait; | 866 terminator.CloseConnection(rejector->error(), rejector->error_details()); |
| 867 fate = kFateTimeWait; |
| 868 break; |
| 816 } | 869 } |
| 817 | 870 |
| 818 case StatelessRejector::UNSUPPORTED: | 871 case StatelessRejector::UNSUPPORTED: |
| 819 // Cheap stateless rejects are not supported so process the packet. | 872 // Cheap stateless rejects are not supported so process the packet. |
| 820 return kFateProcess; | 873 fate = kFateProcess; |
| 874 break; |
| 821 | 875 |
| 822 case StatelessRejector::ACCEPTED: | 876 case StatelessRejector::ACCEPTED: |
| 823 // Contains a valid CHLO, so process the packet and create a connection. | 877 // Contains a valid CHLO, so process the packet and create a connection. |
| 824 return kFateProcess; | 878 fate = kFateProcess; |
| 879 break; |
| 825 | 880 |
| 826 case StatelessRejector::REJECTED: { | 881 case StatelessRejector::REJECTED: { |
| 827 DCHECK_EQ(framer_.version(), header.public_header.versions.front()); | 882 DCHECK_EQ(framer_.version(), first_version); |
| 828 StatelessConnectionTerminator terminator( | 883 StatelessConnectionTerminator terminator(rejector->connection_id(), |
| 829 connection_id, &framer_, helper(), time_wait_list_manager_.get()); | 884 &framer_, helper(), |
| 885 time_wait_list_manager_.get()); |
| 830 terminator.RejectConnection( | 886 terminator.RejectConnection( |
| 831 rejector.reply().GetSerialized().AsStringPiece()); | 887 rejector->reply().GetSerialized().AsStringPiece()); |
| 832 OnConnectionRejectedStatelessly(); | 888 OnConnectionRejectedStatelessly(); |
| 833 return kFateTimeWait; | 889 fate = kFateTimeWait; |
| 890 break; |
| 834 } | 891 } |
| 892 |
| 893 default: |
| 894 QUIC_BUG << "Rejector has invalid state " << rejector->state(); |
| 895 fate = kFateDrop; |
| 896 break; |
| 835 } | 897 } |
| 836 | 898 ProcessUnauthenticatedHeaderFate(fate, rejector->connection_id(), |
| 837 QUIC_BUG << "Rejector has unknown invalid state."; | 899 packet_number); |
| 838 return kFateDrop; | |
| 839 } | 900 } |
| 840 | 901 |
| 841 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { | 902 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { |
| 842 return version_manager_->GetSupportedVersions(); | 903 return version_manager_->GetSupportedVersions(); |
| 843 } | 904 } |
| 844 | 905 |
| 845 void QuicDispatcher::DeliverPacketsToSession( | 906 void QuicDispatcher::DeliverPacketsToSession( |
| 846 const std::list<BufferedPacket>& packets, | 907 const std::list<BufferedPacket>& packets, |
| 847 QuicServerSessionBase* session) { | 908 QuicServerSessionBase* session) { |
| 848 for (const BufferedPacket& packet : packets) { | 909 for (const BufferedPacket& packet : packets) { |
| 849 session->ProcessUdpPacket(packet.server_address, packet.client_address, | 910 session->ProcessUdpPacket(packet.server_address, packet.client_address, |
| 850 *(packet.packet)); | 911 *(packet.packet)); |
| 851 } | 912 } |
| 852 } | 913 } |
| 853 | 914 |
| 854 } // namespace net | 915 } // namespace net |
| OLD | NEW |