In QUIC, add TimeWaitConnectionInfo to record necessary information of connections which are going to be added to time wait list. Refactor only, no functional change expected, not protected. In the next change, I am going to add more info to this struct (e.g., srtt) PiperOrigin-RevId: 325285116 Change-Id: Iee053bda3f66a77bd0a5bf39d8b1fbb6f6d930b2
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc index cfad1ac..2ba39e2 100644 --- a/quic/core/quic_dispatcher.cc +++ b/quic/core/quic_dispatcher.cc
@@ -155,9 +155,9 @@ SerializeConnectionClosePacket(error_code, error_details); time_wait_list_manager_->AddConnectionIdToTimeWait( - server_connection_id_, ietf_quic, + server_connection_id_, QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, - collector_.packets()); + TimeWaitConnectionInfo(ietf_quic, collector_.packets())); } private: @@ -781,8 +781,10 @@ QUIC_CODE_COUNT(quic_v44_add_to_time_wait_list_with_stateless_reset); } time_wait_list_manager_->AddConnectionIdToTimeWait( - it->first, VersionHasIetfInvariantHeader(connection->transport_version()), - action, connection->termination_packets()); + it->first, action, + TimeWaitConnectionInfo( + VersionHasIetfInvariantHeader(connection->transport_version()), + connection->termination_packets())); session_map_.erase(it); } @@ -931,7 +933,8 @@ << ", error_code:" << error_code << ", error_details:" << error_details; time_wait_list_manager_->AddConnectionIdToTimeWait( - server_connection_id, format != GOOGLE_QUIC_PACKET, action, nullptr); + server_connection_id, action, + TimeWaitConnectionInfo(format != GOOGLE_QUIC_PACKET, nullptr)); return; } @@ -965,8 +968,9 @@ /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, use_length_prefix, /*versions=*/{})); time_wait_list_manager()->AddConnectionIdToTimeWait( - server_connection_id, /*ietf_quic=*/format != GOOGLE_QUIC_PACKET, - QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, &termination_packets); + server_connection_id, QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, + TimeWaitConnectionInfo(/*ietf_quic=*/format != GOOGLE_QUIC_PACKET, + &termination_packets)); } bool QuicDispatcher::ShouldCreateSessionForUnknownVersion(
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc index 0dcf035..282bef7 100644 --- a/quic/core/quic_dispatcher_test.cc +++ b/quic/core/quic_dispatcher_test.cc
@@ -868,7 +868,7 @@ EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id, _, _)) .Times(1); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessPacket(client_address, connection_id, true, "data"); } @@ -884,7 +884,7 @@ EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id, _, _)) .Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _)) .Times(1); @@ -903,7 +903,7 @@ QuicReceivedPacket packet2(valid_size_packet, 23, QuicTime::Zero()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); // Verify small packet is silently dropped. EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _)) @@ -1049,7 +1049,7 @@ CreateQuicSession(TestConnectionId(1), _, client_address, _, _)) .Times(0); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true, "data"); @@ -1068,7 +1068,7 @@ EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address, _, _)) .Times(0); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessFirstFlight(client_address, EmptyQuicConnectionId()); } @@ -1389,7 +1389,7 @@ EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true, version_, SerializeCHLO(), /*full_padding=*/false, @@ -1540,7 +1540,7 @@ QuicConnectionId connection_id = TestConnectionId(1); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0); EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0); - EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _)) .Times(0); ProcessPacket(client_address, connection_id, true, "data",
diff --git a/quic/core/quic_time_wait_list_manager.cc b/quic/core/quic_time_wait_list_manager.cc index 274364c..1a88048 100644 --- a/quic/core/quic_time_wait_list_manager.cc +++ b/quic/core/quic_time_wait_list_manager.cc
@@ -47,6 +47,15 @@ QuicTimeWaitListManager* time_wait_list_manager_; }; +TimeWaitConnectionInfo::TimeWaitConnectionInfo( + bool ietf_quic, + std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) + : ietf_quic(ietf_quic) { + if (termination_packets != nullptr) { + this->termination_packets.swap(*termination_packets); + } +} + QuicTimeWaitListManager::QuicTimeWaitListManager( QuicPacketWriter* writer, Visitor* visitor, @@ -68,11 +77,11 @@ void QuicTimeWaitListManager::AddConnectionIdToTimeWait( QuicConnectionId connection_id, - bool ietf_quic, TimeWaitAction action, - std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) { - DCHECK(action != SEND_TERMINATION_PACKETS || termination_packets != nullptr); - DCHECK(action != DO_NOTHING || ietf_quic); + TimeWaitConnectionInfo info) { + DCHECK(action != SEND_TERMINATION_PACKETS || + !info.termination_packets.empty()); + DCHECK(action != DO_NOTHING || info.ietf_quic); int num_packets = 0; auto it = connection_id_map_.find(connection_id); const bool new_connection_id = it == connection_id_map_.end(); @@ -85,11 +94,8 @@ GetQuicFlag(FLAGS_quic_time_wait_list_max_connections); DCHECK(connection_id_map_.empty() || num_connections() < static_cast<size_t>(max_connections)); - ConnectionIdData data(num_packets, ietf_quic, clock_->ApproximateNow(), - action); - if (termination_packets != nullptr) { - data.termination_packets.swap(*termination_packets); - } + ConnectionIdData data(num_packets, clock_->ApproximateNow(), action, + std::move(info)); connection_id_map_.emplace(std::make_pair(connection_id, std::move(data))); if (new_connection_id) { visitor_->OnConnectionAddedToTimeWaitList(connection_id); @@ -135,39 +141,39 @@ QUIC_DLOG(INFO) << "Processing " << connection_id << " in time wait state: " << "header format=" << header_format - << " ietf=" << connection_data->ietf_quic + << " ietf=" << connection_data->info.ietf_quic << ", action=" << connection_data->action << ", number termination packets=" - << connection_data->termination_packets.size(); + << connection_data->info.termination_packets.size(); switch (connection_data->action) { case SEND_TERMINATION_PACKETS: - if (connection_data->termination_packets.empty()) { + if (connection_data->info.termination_packets.empty()) { QUIC_BUG << "There are no termination packets."; return; } switch (header_format) { case IETF_QUIC_LONG_HEADER_PACKET: - if (!connection_data->ietf_quic) { + if (!connection_data->info.ietf_quic) { QUIC_CODE_COUNT(quic_received_long_header_packet_for_gquic); } break; case IETF_QUIC_SHORT_HEADER_PACKET: - if (!connection_data->ietf_quic) { + if (!connection_data->info.ietf_quic) { QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic); } // Send stateless reset in response to short header packets. SendPublicReset(self_address, peer_address, connection_id, - connection_data->ietf_quic, + connection_data->info.ietf_quic, std::move(packet_context)); return; case GOOGLE_QUIC_PACKET: - if (connection_data->ietf_quic) { + if (connection_data->info.ietf_quic) { QUIC_CODE_COUNT(quic_received_gquic_packet_for_ietf_quic); } break; } - for (const auto& packet : connection_data->termination_packets) { + for (const auto& packet : connection_data->info.termination_packets) { SendOrQueuePacket(std::make_unique<QueuedPacket>( self_address, peer_address, packet->Clone()), packet_context.get()); @@ -175,11 +181,11 @@ return; case SEND_CONNECTION_CLOSE_PACKETS: - if (connection_data->termination_packets.empty()) { + if (connection_data->info.termination_packets.empty()) { QUIC_BUG << "There are no termination packets."; return; } - for (const auto& packet : connection_data->termination_packets) { + for (const auto& packet : connection_data->info.termination_packets) { SendOrQueuePacket(std::make_unique<QueuedPacket>( self_address, peer_address, packet->Clone()), packet_context.get()); @@ -191,11 +197,12 @@ QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet); } SendPublicReset(self_address, peer_address, connection_id, - connection_data->ietf_quic, std::move(packet_context)); + connection_data->info.ietf_quic, + std::move(packet_context)); return; case DO_NOTHING: QUIC_CODE_COUNT(quic_time_wait_list_do_nothing); - DCHECK(connection_data->ietf_quic); + DCHECK(connection_data->info.ietf_quic); } } @@ -394,13 +401,13 @@ QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData( int num_packets, - bool ietf_quic, QuicTime time_added, - TimeWaitAction action) + TimeWaitAction action, + TimeWaitConnectionInfo info) : num_packets(num_packets), - ietf_quic(ietf_quic), time_added(time_added), - action(action) {} + action(action), + info(std::move(info)) {} QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData( ConnectionIdData&& other) = default;
diff --git a/quic/core/quic_time_wait_list_manager.h b/quic/core/quic_time_wait_list_manager.h index dcbc528..429566b 100644 --- a/quic/core/quic_time_wait_list_manager.h +++ b/quic/core/quic_time_wait_list_manager.h
@@ -26,6 +26,22 @@ class QuicTimeWaitListManagerPeer; } // namespace test +// TimeWaitConnectionInfo comprises information of a connection which is in the +// time wait list. +struct QUIC_EXPORT_PRIVATE TimeWaitConnectionInfo { + TimeWaitConnectionInfo( + bool ietf_quic, + std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets); + + TimeWaitConnectionInfo(const TimeWaitConnectionInfo& other) = delete; + TimeWaitConnectionInfo(TimeWaitConnectionInfo&& other) = default; + + ~TimeWaitConnectionInfo() = default; + + bool ietf_quic; + std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; +}; + // Maintains a list of all connection_ids that have been recently closed. A // connection_id lives in this state for time_wait_period_. All packets received // for connection_ids in this state are handed over to the @@ -78,11 +94,9 @@ // will be move from |termination_packets| and will become owned by the // manager. |action| specifies what the time wait list manager should do when // processing packets of the connection. - virtual void AddConnectionIdToTimeWait( - QuicConnectionId connection_id, - bool ietf_quic, - TimeWaitAction action, - std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets); + virtual void AddConnectionIdToTimeWait(QuicConnectionId connection_id, + TimeWaitAction action, + TimeWaitConnectionInfo info); // Returns true if the connection_id is in time wait state, false otherwise. // Packets received for this connection_id should not lead to creation of new @@ -234,9 +248,9 @@ // connection_id. struct QUIC_NO_EXPORT ConnectionIdData { ConnectionIdData(int num_packets, - bool ietf_quic, QuicTime time_added, - TimeWaitAction action); + TimeWaitAction action, + TimeWaitConnectionInfo info); ConnectionIdData(const ConnectionIdData& other) = delete; ConnectionIdData(ConnectionIdData&& other); @@ -244,11 +258,9 @@ ~ConnectionIdData(); int num_packets; - bool ietf_quic; QuicTime time_added; - // These packets may contain CONNECTION_CLOSE frames, or SREJ messages. - std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; TimeWaitAction action; + TimeWaitConnectionInfo info; }; // QuicLinkedHashMap allows lookup by ConnectionId and traversal in add order.
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc index 2f764de..34c2b1e 100644 --- a/quic/core/quic_time_wait_list_manager_test.cc +++ b/quic/core/quic_time_wait_list_manager_test.cc
@@ -153,8 +153,8 @@ termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>( new QuicEncryptedPacket(nullptr, 0, false))); time_wait_list_manager_.AddConnectionIdToTimeWait( - connection_id, false, QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, - &termination_packets); + connection_id, QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, + TimeWaitConnectionInfo(false, &termination_packets)); } void AddConnectionId( @@ -163,8 +163,9 @@ QuicTimeWaitListManager::TimeWaitAction action, std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) { time_wait_list_manager_.AddConnectionIdToTimeWait( - connection_id, VersionHasIetfInvariantHeader(version.transport_version), - action, packets); + connection_id, action, + TimeWaitConnectionInfo( + VersionHasIetfInvariantHeader(version.transport_version), packets)); } bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) { @@ -630,8 +631,8 @@ std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( new char[kConnectionCloseLength], kConnectionCloseLength, true))); time_wait_list_manager_.AddConnectionIdToTimeWait( - connection_id_, /*ietf_quic=*/true, - QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, &termination_packets); + connection_id_, QuicTimeWaitListManager::SEND_TERMINATION_PACKETS, + TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets)); // Termination packet is not encrypted, instead, send stateless reset. EXPECT_CALL(writer_, @@ -654,9 +655,8 @@ new char[kConnectionCloseLength], kConnectionCloseLength, true))); // Add a CONNECTION_CLOSE termination packet. time_wait_list_manager_.AddConnectionIdToTimeWait( - connection_id_, /*ietf_quic=*/true, - QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS, - &termination_packets); + connection_id_, QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS, + TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets)); EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, self_address_.host(), peer_address_, _)) .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
diff --git a/quic/test_tools/mock_quic_time_wait_list_manager.cc b/quic/test_tools/mock_quic_time_wait_list_manager.cc index ec63558..310a22b 100644 --- a/quic/test_tools/mock_quic_time_wait_list_manager.cc +++ b/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -18,9 +18,9 @@ : QuicTimeWaitListManager(writer, visitor, clock, alarm_factory) { // Though AddConnectionIdToTimeWait is mocked, we want to retain its // functionality. - EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _)) + EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _)) .Times(testing::AnyNumber()); - ON_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _)) + ON_CALL(*this, AddConnectionIdToTimeWait(_, _, _)) .WillByDefault( Invoke(this, &MockTimeWaitListManager:: QuicTimeWaitListManager_AddConnectionIdToTimeWait));
diff --git a/quic/test_tools/mock_quic_time_wait_list_manager.h b/quic/test_tools/mock_quic_time_wait_list_manager.h index 3dae5ad..24c261f 100644 --- a/quic/test_tools/mock_quic_time_wait_list_manager.h +++ b/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -22,18 +22,16 @@ MOCK_METHOD(void, AddConnectionIdToTimeWait, (QuicConnectionId connection_id, - bool ietf_quic, QuicTimeWaitListManager::TimeWaitAction action, - std::vector<std::unique_ptr<QuicEncryptedPacket>>*), + quic::TimeWaitConnectionInfo info), (override)); void QuicTimeWaitListManager_AddConnectionIdToTimeWait( QuicConnectionId connection_id, - bool ietf_quic, QuicTimeWaitListManager::TimeWaitAction action, - std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) { - QuicTimeWaitListManager::AddConnectionIdToTimeWait( - connection_id, ietf_quic, action, termination_packets); + quic::TimeWaitConnectionInfo info) { + QuicTimeWaitListManager::AddConnectionIdToTimeWait(connection_id, action, + std::move(info)); } MOCK_METHOD(void,