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

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

Issue 2236973002: Landing Recent QUIC changes until 4AM, Aug 7, 2016 UTC-4 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: flip quic_sequencer_buffer_retire_block_in_time to true Created 4 years, 4 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/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 #include "net/tools/quic/chlo_extractor.h" 17 #include "net/tools/quic/chlo_extractor.h"
18 #include "net/tools/quic/quic_per_connection_packet_writer.h" 18 #include "net/tools/quic/quic_per_connection_packet_writer.h"
19 #include "net/tools/quic/quic_simple_server_session.h" 19 #include "net/tools/quic/quic_simple_server_session.h"
20 #include "net/tools/quic/quic_time_wait_list_manager.h" 20 #include "net/tools/quic/quic_time_wait_list_manager.h"
21 #include "net/tools/quic/stateless_rejector.h" 21 #include "net/tools/quic/stateless_rejector.h"
22 22
23 using base::StringPiece; 23 using base::StringPiece;
24 using std::string; 24 using std::string;
25 25
26 namespace net { 26 namespace net {
27 27
28 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket;
29 typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList;
30 typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult;
31
28 namespace { 32 namespace {
29 33
30 // An alarm that informs the QuicDispatcher to delete old sessions. 34 // An alarm that informs the QuicDispatcher to delete old sessions.
31 class DeleteSessionsAlarm : public QuicAlarm::Delegate { 35 class DeleteSessionsAlarm : public QuicAlarm::Delegate {
32 public: 36 public:
33 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) 37 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
34 : dispatcher_(dispatcher) {} 38 : dispatcher_(dispatcher) {}
35 39
36 void OnAlarm() override { dispatcher_->DeleteSessions(); } 40 void OnAlarm() override { dispatcher_->DeleteSessions(); }
37 41
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 324 }
321 325
322 // Packet's connection ID is unknown. 326 // Packet's connection ID is unknown.
323 // Apply the validity checks. 327 // Apply the validity checks.
324 QuicPacketFate fate = ValidityChecks(header); 328 QuicPacketFate fate = ValidityChecks(header);
325 if (fate == kFateProcess) { 329 if (fate == kFateProcess) {
326 fate = MaybeRejectStatelessly(connection_id, header); 330 fate = MaybeRejectStatelessly(connection_id, header);
327 } 331 }
328 switch (fate) { 332 switch (fate) {
329 case kFateProcess: { 333 case kFateProcess: {
330 // Create a session and process the packet. 334 ProcessChlo();
331 QuicServerSessionBase* session =
332 CreateQuicSession(connection_id, current_client_address_);
333 DVLOG(1) << "Created new session for " << connection_id;
334 session_map_.insert(std::make_pair(connection_id, session));
335 session->ProcessUdpPacket(current_server_address_,
336 current_client_address_, *current_packet_);
337 std::list<QuicBufferedPacketStore::BufferedPacket> packets =
338 buffered_packets_.DeliverPackets(connection_id);
339 for (const auto& packet : packets) {
340 SessionMap::iterator it = session_map_.find(connection_id);
341 if (it == session_map_.end()) {
342 break;
343 }
344 it->second->ProcessUdpPacket(packet.server_address,
345 packet.client_address, *packet.packet);
346 }
347 break; 335 break;
348 } 336 }
349 case kFateTimeWait: 337 case kFateTimeWait:
350 // MaybeRejectStatelessly might have already added the connection to 338 // MaybeRejectStatelessly might have already added the connection to
351 // time wait, in which case it should not be added again. 339 // time wait, in which case it should not be added again.
352 if (!FLAGS_quic_use_cheap_stateless_rejects || 340 if (!FLAGS_quic_use_cheap_stateless_rejects ||
353 !time_wait_list_manager_->IsConnectionIdInTimeWait( 341 !time_wait_list_manager_->IsConnectionIdInTimeWait(
354 header.public_header.connection_id)) { 342 header.public_header.connection_id)) {
355 // Add this connection_id to the time-wait state, to safely reject 343 // Add this connection_id to the time-wait state, to safely reject
356 // future packets. 344 // future packets.
357 DVLOG(1) << "Adding connection ID " << connection_id 345 DVLOG(1) << "Adding connection ID " << connection_id
358 << "to time-wait list."; 346 << "to time-wait list.";
359 time_wait_list_manager_->AddConnectionIdToTimeWait( 347 time_wait_list_manager_->AddConnectionIdToTimeWait(
360 connection_id, framer_.version(), 348 connection_id, framer_.version(),
361 /*connection_rejected_statelessly=*/false, nullptr); 349 /*connection_rejected_statelessly=*/false, nullptr);
362 } 350 }
363 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait( 351 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
364 header.public_header.connection_id)); 352 header.public_header.connection_id));
365 time_wait_list_manager_->ProcessPacket( 353 time_wait_list_manager_->ProcessPacket(
366 current_server_address_, current_client_address_, 354 current_server_address_, current_client_address_,
367 header.public_header.connection_id, header.packet_number, 355 header.public_header.connection_id, header.packet_number,
368 *current_packet_); 356 *current_packet_);
369 break; 357 break;
358 case kFateBuffer:
359 // This packet is a non-CHLO packet which has arrived out of order.
360 // Buffer it.
361 BufferEarlyPacket(connection_id);
362 break;
370 case kFateDrop: 363 case kFateDrop:
371 // Do nothing with the packet. 364 // Do nothing with the packet.
372 break; 365 break;
373 } 366 }
374 367
375 return false; 368 return false;
376 } 369 }
377 370
378 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks( 371 QuicDispatcher::QuicPacketFate QuicDispatcher::ValidityChecks(
379 const QuicPacketHeader& header) { 372 const QuicPacketHeader& header) {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 DCHECK(false); 592 DCHECK(false);
600 return false; 593 return false;
601 } 594 }
602 595
603 void QuicDispatcher::OnPacketComplete() { 596 void QuicDispatcher::OnPacketComplete() {
604 DCHECK(false); 597 DCHECK(false);
605 } 598 }
606 599
607 void QuicDispatcher::OnExpiredPackets( 600 void QuicDispatcher::OnExpiredPackets(
608 QuicConnectionId connection_id, 601 QuicConnectionId connection_id,
609 QuicBufferedPacketStore::BufferedPacketList early_arrived_packets) {} 602 BufferedPacketList early_arrived_packets) {
603 time_wait_list_manager_->AddConnectionIdToTimeWait(
604 connection_id, framer_.version(), false, nullptr);
605 }
606
607 void QuicDispatcher::OnNewConnectionAdded(QuicConnectionId connection_id) {
608 VLOG(1) << "Received packet from new connection " << connection_id;
609 }
610
611 // Return true if there is any packet buffered in the store.
612 bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) {
613 return buffered_packets_.HasBufferedPackets(connection_id);
614 }
615
616 void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result,
617 QuicConnectionId connection_id) {
618 DVLOG(1) << "Fail to buffer packet on connection " << connection_id
619 << " because of " << result;
620 }
610 621
611 void QuicDispatcher::OnConnectionRejectedStatelessly() {} 622 void QuicDispatcher::OnConnectionRejectedStatelessly() {}
612 623
613 void QuicDispatcher::OnConnectionClosedStatelessly(QuicErrorCode error) {} 624 void QuicDispatcher::OnConnectionClosedStatelessly(QuicErrorCode error) {}
614 625
615 bool QuicDispatcher::ShouldAttemptCheapStatelessRejection() { 626 bool QuicDispatcher::ShouldAttemptCheapStatelessRejection() {
616 return true; 627 return true;
617 } 628 }
618 629
619 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { 630 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
620 return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(), 631 return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(),
621 alarm_factory_.get()); 632 alarm_factory_.get());
622 } 633 }
623 634
635 void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id) {
636 bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id);
637 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
638 connection_id, *current_packet_, current_server_address_,
639 current_client_address_);
640 if (rs != EnqueuePacketResult::SUCCESS) {
641 OnBufferPacketFailure(rs, connection_id);
642 } else if (is_new_connection) {
643 OnNewConnectionAdded(connection_id);
644 }
645 }
646
647 void QuicDispatcher::ProcessChlo() {
648 // Creates a new session and process all buffered packets for this connection.
649 QuicServerSessionBase* session =
650 CreateQuicSession(current_connection_id_, current_client_address_);
651 DVLOG(1) << "Created new session for " << current_connection_id_;
652 session_map_.insert(std::make_pair(current_connection_id_, session));
653 std::list<BufferedPacket> packets =
654 buffered_packets_.DeliverPackets(current_connection_id_);
655 // Check if CHLO is the first packet arrived on this connection.
656 if (FLAGS_quic_buffer_packet_till_chlo && packets.empty()) {
657 OnNewConnectionAdded(current_connection_id_);
658 }
659 // Process CHLO at first.
660 session->ProcessUdpPacket(current_server_address_, current_client_address_,
661 *current_packet_);
662
663 // Deliver queued-up packets in the same order as they arrived.
664 // Do this even when flag is off because there might be still some packets
665 // buffered in the store before flag is turned off.
666 for (const BufferedPacket& packet : packets) {
667 session->ProcessUdpPacket(packet.server_address, packet.client_address,
668 *(packet.packet));
669 }
670 }
671
624 bool QuicDispatcher::HandlePacketForTimeWait( 672 bool QuicDispatcher::HandlePacketForTimeWait(
625 const QuicPacketPublicHeader& header) { 673 const QuicPacketPublicHeader& header) {
626 if (header.reset_flag) { 674 if (header.reset_flag) {
627 // Public reset packets do not have packet numbers, so ignore the packet. 675 // Public reset packets do not have packet numbers, so ignore the packet.
628 return false; 676 return false;
629 } 677 }
630 678
631 // Switch the framer to the correct version, so that the packet number can 679 // Switch the framer to the correct version, so that the packet number can
632 // be parsed correctly. 680 // be parsed correctly.
633 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId( 681 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId(
(...skipping 18 matching lines...) Expand all
652 } 700 }
653 701
654 QuicDispatcher::QuicPacketFate QuicDispatcher::MaybeRejectStatelessly( 702 QuicDispatcher::QuicPacketFate QuicDispatcher::MaybeRejectStatelessly(
655 QuicConnectionId connection_id, 703 QuicConnectionId connection_id,
656 const QuicPacketHeader& header) { 704 const QuicPacketHeader& header) {
657 // TODO(rch): This logic should probably live completely inside the rejector. 705 // TODO(rch): This logic should probably live completely inside the rejector.
658 if (!FLAGS_quic_use_cheap_stateless_rejects || 706 if (!FLAGS_quic_use_cheap_stateless_rejects ||
659 !FLAGS_enable_quic_stateless_reject_support || 707 !FLAGS_enable_quic_stateless_reject_support ||
660 header.public_header.versions.front() <= QUIC_VERSION_32 || 708 header.public_header.versions.front() <= QUIC_VERSION_32 ||
661 !ShouldAttemptCheapStatelessRejection()) { 709 !ShouldAttemptCheapStatelessRejection()) {
710 // Not use cheap stateless reject.
711 if (FLAGS_quic_buffer_packet_till_chlo &&
712 !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
713 nullptr)) {
714 // Buffer non-CHLO packets.
715 return kFateBuffer;
716 }
662 return kFateProcess; 717 return kFateProcess;
663 } 718 }
664 719
665 StatelessRejector rejector(header.public_header.versions.front(), 720 StatelessRejector rejector(
666 GetSupportedVersions(), crypto_config_, 721 header.public_header.versions.front(), GetSupportedVersions(),
667 &compressed_certs_cache_, helper()->GetClock(), 722 crypto_config_, &compressed_certs_cache_, helper()->GetClock(),
668 helper()->GetRandomGenerator(), 723 helper()->GetRandomGenerator(), current_packet_->length(),
669 current_client_address_, current_server_address_); 724 current_client_address_, current_server_address_);
670 ChloValidator validator(session_helper_.get(), current_server_address_, 725 ChloValidator validator(session_helper_.get(), current_server_address_,
671 &rejector); 726 &rejector);
672 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), 727 if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
673 &validator)) { 728 &validator)) {
674 DVLOG(1) << "Buffering undecryptable packet."; 729 if (!FLAGS_quic_buffer_packet_till_chlo) {
675 buffered_packets_.EnqueuePacket(connection_id, *current_packet_, 730 QUIC_BUG
676 current_server_address_, 731 << "Have to drop packet because buffering non-chlo packet is "
677 current_client_address_); 732 "not supported while trying to do stateless reject. "
678 return kFateDrop; 733 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false"
734 " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true";
735 return kFateDrop;
736 }
737 return kFateBuffer;
679 } 738 }
680 739
681 if (!validator.can_accept()) { 740 if (!validator.can_accept()) {
682 // This CHLO is prohibited by policy. 741 // This CHLO is prohibited by policy.
683 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(), 742 StatelessConnectionTerminator terminator(connection_id, &framer_, helper(),
684 time_wait_list_manager_.get()); 743 time_wait_list_manager_.get());
685 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED, 744 terminator.CloseConnection(QUIC_HANDSHAKE_FAILED,
686 validator.error_details()); 745 validator.error_details());
687 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED); 746 OnConnectionClosedStatelessly(QUIC_HANDSHAKE_FAILED);
688 return kFateTimeWait; 747 return kFateTimeWait;
(...skipping 30 matching lines...) Expand all
719 778
720 QUIC_BUG << "Rejector has unknown invalid state."; 779 QUIC_BUG << "Rejector has unknown invalid state.";
721 return kFateDrop; 780 return kFateDrop;
722 } 781 }
723 782
724 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() { 783 const QuicVersionVector& QuicDispatcher::GetSupportedVersions() {
725 return version_manager_->GetSupportedVersions(); 784 return version_manager_->GetSupportedVersions();
726 } 785 }
727 786
728 } // namespace net 787 } // 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