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 |