| 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 #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::list; |
| 24 using std::string; | 25 using std::string; |
| 25 | 26 |
| 26 namespace net { | 27 namespace net { |
| 27 | 28 |
| 28 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; | 29 typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; |
| 29 typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; | 30 typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; |
| 30 typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; | 31 typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 session_helper_(std::move(session_helper)), | 204 session_helper_(std::move(session_helper)), |
| 204 alarm_factory_(std::move(alarm_factory)), | 205 alarm_factory_(std::move(alarm_factory)), |
| 205 delete_sessions_alarm_( | 206 delete_sessions_alarm_( |
| 206 alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))), | 207 alarm_factory_->CreateAlarm(new DeleteSessionsAlarm(this))), |
| 207 buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()), | 208 buffered_packets_(this, helper_->GetClock(), alarm_factory_.get()), |
| 208 current_packet_(nullptr), | 209 current_packet_(nullptr), |
| 209 version_manager_(version_manager), | 210 version_manager_(version_manager), |
| 210 framer_(GetSupportedVersions(), | 211 framer_(GetSupportedVersions(), |
| 211 /*unused*/ QuicTime::Zero(), | 212 /*unused*/ QuicTime::Zero(), |
| 212 Perspective::IS_SERVER), | 213 Perspective::IS_SERVER), |
| 213 last_error_(QUIC_NO_ERROR) { | 214 last_error_(QUIC_NO_ERROR), |
| 215 new_sessions_allowed_per_event_loop_(0u) { |
| 214 framer_.set_visitor(this); | 216 framer_.set_visitor(this); |
| 215 } | 217 } |
| 216 | 218 |
| 217 QuicDispatcher::~QuicDispatcher() { | 219 QuicDispatcher::~QuicDispatcher() { |
| 218 base::STLDeleteValues(&session_map_); | 220 base::STLDeleteValues(&session_map_); |
| 219 base::STLDeleteElements(&closed_session_list_); | 221 base::STLDeleteElements(&closed_session_list_); |
| 220 } | 222 } |
| 221 | 223 |
| 222 void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) { | 224 void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) { |
| 223 DCHECK(writer_ == nullptr); | 225 DCHECK(writer_ == nullptr); |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 DCHECK(false); | 599 DCHECK(false); |
| 598 } | 600 } |
| 599 | 601 |
| 600 void QuicDispatcher::OnExpiredPackets( | 602 void QuicDispatcher::OnExpiredPackets( |
| 601 QuicConnectionId connection_id, | 603 QuicConnectionId connection_id, |
| 602 BufferedPacketList early_arrived_packets) { | 604 BufferedPacketList early_arrived_packets) { |
| 603 time_wait_list_manager_->AddConnectionIdToTimeWait( | 605 time_wait_list_manager_->AddConnectionIdToTimeWait( |
| 604 connection_id, framer_.version(), false, nullptr); | 606 connection_id, framer_.version(), false, nullptr); |
| 605 } | 607 } |
| 606 | 608 |
| 609 void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) { |
| 610 // Reset the counter before starting creating connections. |
| 611 new_sessions_allowed_per_event_loop_ = max_connections_to_create; |
| 612 for (; new_sessions_allowed_per_event_loop_ > 0; |
| 613 --new_sessions_allowed_per_event_loop_) { |
| 614 QuicConnectionId connection_id; |
| 615 list<BufferedPacket> packets = |
| 616 buffered_packets_.DeliverPacketsForNextConnection(&connection_id); |
| 617 if (packets.empty()) { |
| 618 return; |
| 619 } |
| 620 QuicServerSessionBase* session = |
| 621 CreateQuicSession(connection_id, packets.front().client_address); |
| 622 DVLOG(1) << "Created new session for " << connection_id; |
| 623 session_map_.insert(std::make_pair(connection_id, session)); |
| 624 DeliverPacketsToSession(packets, session); |
| 625 } |
| 626 } |
| 627 |
| 628 bool QuicDispatcher::HasChlosBuffered() const { |
| 629 return buffered_packets_.HasChlosBuffered(); |
| 630 } |
| 631 |
| 607 void QuicDispatcher::OnNewConnectionAdded(QuicConnectionId connection_id) { | 632 void QuicDispatcher::OnNewConnectionAdded(QuicConnectionId connection_id) { |
| 608 VLOG(1) << "Received packet from new connection " << connection_id; | 633 VLOG(1) << "Received packet from new connection " << connection_id; |
| 609 } | 634 } |
| 610 | 635 |
| 611 // Return true if there is any packet buffered in the store. | 636 // Return true if there is any packet buffered in the store. |
| 612 bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) { | 637 bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) { |
| 613 return buffered_packets_.HasBufferedPackets(connection_id); | 638 return buffered_packets_.HasBufferedPackets(connection_id); |
| 614 } | 639 } |
| 615 | 640 |
| 616 void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result, | 641 void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 629 | 654 |
| 630 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { | 655 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { |
| 631 return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(), | 656 return new QuicTimeWaitListManager(writer_.get(), this, helper_.get(), |
| 632 alarm_factory_.get()); | 657 alarm_factory_.get()); |
| 633 } | 658 } |
| 634 | 659 |
| 635 void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id) { | 660 void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id) { |
| 636 bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id); | 661 bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id); |
| 637 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( | 662 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( |
| 638 connection_id, *current_packet_, current_server_address_, | 663 connection_id, *current_packet_, current_server_address_, |
| 639 current_client_address_); | 664 current_client_address_, /*is_chlo=*/false); |
| 640 if (rs != EnqueuePacketResult::SUCCESS) { | 665 if (rs != EnqueuePacketResult::SUCCESS) { |
| 641 OnBufferPacketFailure(rs, connection_id); | 666 OnBufferPacketFailure(rs, connection_id); |
| 642 } else if (is_new_connection) { | 667 } else if (is_new_connection) { |
| 643 OnNewConnectionAdded(connection_id); | 668 OnNewConnectionAdded(connection_id); |
| 644 } | 669 } |
| 645 } | 670 } |
| 646 | 671 |
| 647 void QuicDispatcher::ProcessChlo() { | 672 void QuicDispatcher::ProcessChlo() { |
| 673 QUIC_BUG_IF(!FLAGS_quic_buffer_packet_till_chlo && |
| 674 FLAGS_quic_limit_num_new_sessions_per_epoll_loop) |
| 675 << "Try to limit connection creation per epoll event while not " |
| 676 "supporting packet buffer. " |
| 677 "--quic_limit_num_new_sessions_per_epoll_loop = true " |
| 678 "--quic_buffer_packet_till_chlo = false"; |
| 679 |
| 680 if (FLAGS_quic_limit_num_new_sessions_per_epoll_loop && |
| 681 FLAGS_quic_buffer_packet_till_chlo && |
| 682 new_sessions_allowed_per_event_loop_ <= 0) { |
| 683 // Can't create new session any more. Wait till next event loop. |
| 684 if (!buffered_packets_.HasChloForConnection(current_connection_id_)) { |
| 685 // Only buffer one CHLO per connection. |
| 686 bool is_new_connection = |
| 687 !buffered_packets_.HasBufferedPackets(current_connection_id_); |
| 688 EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( |
| 689 current_connection_id_, *current_packet_, current_server_address_, |
| 690 current_client_address_, /*is_chlo=*/true); |
| 691 if (rs != EnqueuePacketResult::SUCCESS) { |
| 692 OnBufferPacketFailure(rs, current_connection_id_); |
| 693 } else if (is_new_connection) { |
| 694 OnNewConnectionAdded(current_connection_id_); |
| 695 } |
| 696 } |
| 697 return; |
| 698 } |
| 699 |
| 648 // Creates a new session and process all buffered packets for this connection. | 700 // Creates a new session and process all buffered packets for this connection. |
| 649 QuicServerSessionBase* session = | 701 QuicServerSessionBase* session = |
| 650 CreateQuicSession(current_connection_id_, current_client_address_); | 702 CreateQuicSession(current_connection_id_, current_client_address_); |
| 651 if (FLAGS_quic_enforce_mtu_limit && | 703 if (FLAGS_quic_enforce_mtu_limit && |
| 652 current_packet().potentially_small_mtu()) { | 704 current_packet().potentially_small_mtu()) { |
| 653 session->connection()->set_largest_packet_size_supported( | 705 session->connection()->set_largest_packet_size_supported( |
| 654 kMinimumSupportedPacketSize); | 706 kMinimumSupportedPacketSize); |
| 655 } | 707 } |
| 656 DVLOG(1) << "Created new session for " << current_connection_id_; | 708 DVLOG(1) << "Created new session for " << current_connection_id_; |
| 657 session_map_.insert(std::make_pair(current_connection_id_, session)); | 709 session_map_.insert(std::make_pair(current_connection_id_, session)); |
| 658 std::list<BufferedPacket> packets = | 710 std::list<BufferedPacket> packets = |
| 659 buffered_packets_.DeliverPackets(current_connection_id_); | 711 buffered_packets_.DeliverPackets(current_connection_id_); |
| 660 // Check if CHLO is the first packet arrived on this connection. | 712 // Check if CHLO is the first packet arrived on this connection. |
| 661 if (FLAGS_quic_buffer_packet_till_chlo && packets.empty()) { | 713 if (FLAGS_quic_buffer_packet_till_chlo && packets.empty()) { |
| 662 OnNewConnectionAdded(current_connection_id_); | 714 OnNewConnectionAdded(current_connection_id_); |
| 663 } | 715 } |
| 664 // Process CHLO at first. | 716 // Process CHLO at first. |
| 665 session->ProcessUdpPacket(current_server_address_, current_client_address_, | 717 session->ProcessUdpPacket(current_server_address_, current_client_address_, |
| 666 *current_packet_); | 718 *current_packet_); |
| 667 | 719 |
| 668 // Deliver queued-up packets in the same order as they arrived. | 720 // Deliver queued-up packets in the same order as they arrived. |
| 669 // Do this even when flag is off because there might be still some packets | 721 // Do this even when flag is off because there might be still some packets |
| 670 // buffered in the store before flag is turned off. | 722 // buffered in the store before flag is turned off. |
| 671 DeliverPacketsToSession(packets, session); | 723 DeliverPacketsToSession(packets, session); |
| 724 if (FLAGS_quic_limit_num_new_sessions_per_epoll_loop && |
| 725 FLAGS_quic_buffer_packet_till_chlo) { |
| 726 --new_sessions_allowed_per_event_loop_; |
| 727 } |
| 672 } | 728 } |
| 673 | 729 |
| 674 bool QuicDispatcher::HandlePacketForTimeWait( | 730 bool QuicDispatcher::HandlePacketForTimeWait( |
| 675 const QuicPacketPublicHeader& header) { | 731 const QuicPacketPublicHeader& header) { |
| 676 if (header.reset_flag) { | 732 if (header.reset_flag) { |
| 677 // Public reset packets do not have packet numbers, so ignore the packet. | 733 // Public reset packets do not have packet numbers, so ignore the packet. |
| 678 return false; | 734 return false; |
| 679 } | 735 } |
| 680 | 736 |
| 681 // Switch the framer to the correct version, so that the packet number can | 737 // Switch the framer to the correct version, so that the packet number can |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 void QuicDispatcher::DeliverPacketsToSession( | 845 void QuicDispatcher::DeliverPacketsToSession( |
| 790 const std::list<BufferedPacket>& packets, | 846 const std::list<BufferedPacket>& packets, |
| 791 QuicServerSessionBase* session) { | 847 QuicServerSessionBase* session) { |
| 792 for (const BufferedPacket& packet : packets) { | 848 for (const BufferedPacket& packet : packets) { |
| 793 session->ProcessUdpPacket(packet.server_address, packet.client_address, | 849 session->ProcessUdpPacket(packet.server_address, packet.client_address, |
| 794 *(packet.packet)); | 850 *(packet.packet)); |
| 795 } | 851 } |
| 796 } | 852 } |
| 797 | 853 |
| 798 } // namespace net | 854 } // namespace net |
| OLD | NEW |