Let QuicConnection::UpdatePacketContent() return connection state.
This allows callers to correctly handle errors occurred.
Protected by quic_reloadable_flag_quic_update_packet_content_returns_connected.
PiperOrigin-RevId: 353360764
Change-Id: Ie1e9874398311cf3f3f6873bac5dc53d6b1a94d8
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 5090991..bf8cd2d 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1262,7 +1262,9 @@
// Since a stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(STREAM_FRAME);
+ if (!UpdatePacketContent(STREAM_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnStreamFrame(frame);
@@ -1300,7 +1302,9 @@
// Since a CRYPTO frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(CRYPTO_FRAME);
+ if (!UpdatePacketContent(CRYPTO_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnCryptoFrame(frame);
@@ -1325,7 +1329,9 @@
// Since an ack frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(ACK_FRAME);
+ if (!UpdatePacketContent(ACK_FRAME)) {
+ return false;
+ }
QUIC_DVLOG(1) << ENDPOINT
<< "OnAckFrameStart, largest_acked: " << largest_acked;
@@ -1459,7 +1465,9 @@
// Since a stop waiting frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(STOP_WAITING_FRAME);
+ if (!UpdatePacketContent(STOP_WAITING_FRAME)) {
+ return false;
+ }
if (no_stop_waiting_frames_) {
return true;
@@ -1492,7 +1500,9 @@
QUIC_BUG_IF(!connected_)
<< "Processing PADDING frame when connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(PADDING_FRAME);
+ if (!UpdatePacketContent(PADDING_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPaddingFrame(frame);
@@ -1504,7 +1514,9 @@
QUIC_BUG_IF(!connected_)
<< "Processing PING frame when connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(PING_FRAME);
+ if (!UpdatePacketContent(PING_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
QuicTime::Delta ping_received_delay = QuicTime::Delta::Zero();
@@ -1549,7 +1561,9 @@
// Since a reset stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(RST_STREAM_FRAME);
+ if (!UpdatePacketContent(RST_STREAM_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnRstStreamFrame(frame);
@@ -1570,7 +1584,9 @@
// Since a reset stream frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(STOP_SENDING_FRAME);
+ if (!UpdatePacketContent(STOP_SENDING_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnStopSendingFrame(frame);
@@ -1594,7 +1610,9 @@
// Only respond to the 1st PATH_CHALLENGE.
return true;
}
- UpdatePacketContent(PATH_CHALLENGE_FRAME);
+ if (!UpdatePacketContent(PATH_CHALLENGE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPathChallengeFrame(frame);
}
@@ -1630,7 +1648,9 @@
QUIC_BUG_IF(!connected_) << "Processing PATH_RESPONSE frame when connection "
"is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(PATH_RESPONSE_FRAME);
+ if (!UpdatePacketContent(PATH_RESPONSE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPathResponseFrame(frame);
}
@@ -1658,7 +1678,9 @@
// Since a connection close frame was received, this is not a connectivity
// probe. A probe only contains a PING and full padding.
- UpdatePacketContent(CONNECTION_CLOSE_FRAME);
+ if (!UpdatePacketContent(CONNECTION_CLOSE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnConnectionCloseFrame(frame);
@@ -1703,7 +1725,10 @@
QUIC_BUG_IF(!connected_)
<< "Processing MAX_STREAMS frame when connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(MAX_STREAMS_FRAME);
+ if (!UpdatePacketContent(MAX_STREAMS_FRAME)) {
+ return false;
+ }
+
if (debug_visitor_ != nullptr) {
debug_visitor_->OnMaxStreamsFrame(frame);
}
@@ -1715,7 +1740,10 @@
QUIC_BUG_IF(!connected_) << "Processing STREAMS_BLOCKED frame when "
"connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(STREAMS_BLOCKED_FRAME);
+ if (!UpdatePacketContent(STREAMS_BLOCKED_FRAME)) {
+ return false;
+ }
+
if (debug_visitor_ != nullptr) {
debug_visitor_->OnStreamsBlockedFrame(frame);
}
@@ -1729,7 +1757,9 @@
// Since a go away frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(GOAWAY_FRAME);
+ if (!UpdatePacketContent(GOAWAY_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnGoAwayFrame(frame);
@@ -1750,7 +1780,9 @@
// Since a window update frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(WINDOW_UPDATE_FRAME);
+ if (!UpdatePacketContent(WINDOW_UPDATE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnWindowUpdateFrame(
@@ -1767,7 +1799,10 @@
QUIC_BUG_IF(!connected_) << "Processing NEW_CONNECTION_ID frame when "
"connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(NEW_CONNECTION_ID_FRAME);
+ if (!UpdatePacketContent(NEW_CONNECTION_ID_FRAME)) {
+ return false;
+ }
+
if (debug_visitor_ != nullptr) {
debug_visitor_->OnNewConnectionIdFrame(frame);
}
@@ -1779,7 +1814,10 @@
QUIC_BUG_IF(!connected_) << "Processing RETIRE_CONNECTION_ID frame when "
"connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME);
+ if (!UpdatePacketContent(RETIRE_CONNECTION_ID_FRAME)) {
+ return false;
+ }
+
if (debug_visitor_ != nullptr) {
debug_visitor_->OnRetireConnectionIdFrame(frame);
}
@@ -1790,7 +1828,10 @@
QUIC_BUG_IF(!connected_)
<< "Processing NEW_TOKEN frame when connection is closed. Last frame: "
<< most_recent_frame_type_;
- UpdatePacketContent(NEW_TOKEN_FRAME);
+ if (!UpdatePacketContent(NEW_TOKEN_FRAME)) {
+ return false;
+ }
+
if (debug_visitor_ != nullptr) {
debug_visitor_->OnNewTokenFrame(frame);
}
@@ -1815,7 +1856,9 @@
// Since a message frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(MESSAGE_FRAME);
+ if (!UpdatePacketContent(MESSAGE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnMessageFrame(frame);
@@ -1846,7 +1889,9 @@
// Since a handshake done frame was received, this is not a connectivity
// probe. A probe only contains a PING and full padding.
- UpdatePacketContent(HANDSHAKE_DONE_FRAME);
+ if (!UpdatePacketContent(HANDSHAKE_DONE_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnHandshakeDoneFrame(frame);
@@ -1863,7 +1908,10 @@
if (debug_visitor_ != nullptr) {
debug_visitor_->OnAckFrequencyFrame(frame);
}
- UpdatePacketContent(ACK_FREQUENCY_FRAME);
+ if (!UpdatePacketContent(ACK_FREQUENCY_FRAME)) {
+ return false;
+ }
+
if (!can_receive_ack_frequency_frame_) {
QUIC_LOG_EVERY_N_SEC(ERROR, 120) << "Get unexpected AckFrequencyFrame.";
return false;
@@ -1888,7 +1936,9 @@
// Since a blocked frame was received, this is not a connectivity probe.
// A probe only contains a PING and full padding.
- UpdatePacketContent(BLOCKED_FRAME);
+ if (!UpdatePacketContent(BLOCKED_FRAME)) {
+ return false;
+ }
if (debug_visitor_ != nullptr) {
debug_visitor_->OnBlockedFrame(frame);
@@ -4777,19 +4827,22 @@
sent_packet_manager_.OnApplicationLimited();
}
-void QuicConnection::UpdatePacketContent(QuicFrameType type) {
+bool QuicConnection::UpdatePacketContent(QuicFrameType type) {
+ if (update_packet_content_returns_connected_) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_update_packet_content_returns_connected);
+ }
most_recent_frame_type_ = type;
if (version().HasIetfQuicFrames()) {
if (!QuicUtils::IsProbingFrame(type)) {
MaybeStartIetfPeerMigration();
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
QuicSocketAddress current_effective_peer_address =
GetEffectivePeerAddressFromCurrentPacket();
if (!count_bytes_on_alternative_path_seperately_ ||
IsDefaultPath(last_packet_destination_address_,
last_packet_source_address_)) {
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
QUIC_CODE_COUNT_N(quic_count_bytes_on_alternative_path_seperately, 3, 5);
if (type == PATH_CHALLENGE_FRAME &&
@@ -4804,7 +4857,7 @@
last_packet_destination_address_, current_effective_peer_address);
}
MaybeUpdateBytesReceivedFromAlternativeAddress(last_size_);
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
// Packet content is tracked to identify connectivity probe in non-IETF
// version, where a connectivity probe is defined as
@@ -4815,13 +4868,13 @@
// We have already learned the current packet is not a connectivity
// probing packet. Peer migration should have already been started earlier
// if needed.
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
if (type == PING_FRAME) {
if (current_packet_content_ == NO_FRAMES_RECEIVED) {
current_packet_content_ = FIRST_FRAME_IS_PING;
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
}
@@ -4851,7 +4904,7 @@
<< last_packet_destination_address_
<< ", self_address_:" << self_address_;
}
- return;
+ return !update_packet_content_returns_connected_ || connected_;
}
current_packet_content_ = NOT_PADDED_PING;
@@ -4865,6 +4918,7 @@
}
}
current_effective_peer_migration_type_ = NO_CHANGE;
+ return !update_packet_content_returns_connected_ || connected_;
}
void QuicConnection::MaybeStartIetfPeerMigration() {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 45211d2..b250810 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -54,6 +54,7 @@
#include "quic/core/uber_received_packet_manager.h"
#include "quic/platform/api/quic_containers.h"
#include "quic/platform/api/quic_export.h"
+#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_socket_address.h"
#include "common/platform/api/quiche_str_cat.h"
@@ -1450,7 +1451,8 @@
// starts effective peer migration if current packet is confirmed not a
// connectivity probe and |current_effective_peer_migration_type_| indicates
// effective peer address change.
- void UpdatePacketContent(QuicFrameType type);
+ // Returns true if connection is still alive.
+ ABSL_MUST_USE_RESULT bool UpdatePacketContent(QuicFrameType type);
// Called when last received ack frame has been processed.
// |send_stop_waiting| indicates whether a stop waiting needs to be sent.
@@ -2049,6 +2051,9 @@
bool count_bytes_on_alternative_path_seperately_ =
GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately);
+
+ bool update_packet_content_returns_connected_ =
+ GetQuicReloadableFlag(quic_update_packet_content_returns_connected);
};
} // namespace quic
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 29ad505..5643114 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -13265,6 +13265,7 @@
QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER);
}
+// Regression test for b/177312785
TEST_P(QuicConnectionTest, PeerMigrateBeforeHandshakeConfirm) {
if (!VersionHasIetfQuicFrames(version().transport_version) ||
!GetQuicReloadableFlag(quic_start_peer_migration_earlier)) {
@@ -13294,12 +13295,22 @@
// Process another packet with a different peer address on server side will
// close connection.
+ QuicAckFrame frame = InitAckFrame(1);
EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
EXPECT_CALL(visitor_,
OnConnectionClosed(_, ConnectionCloseSource::FROM_SELF));
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0u);
- ProcessFramePacketWithAddresses(MakeCryptoFrame(), kSelfAddress,
- kNewPeerAddress, ENCRYPTION_INITIAL);
+ if (!GetQuicReloadableFlag(quic_update_packet_content_returns_connected)) {
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+ EXPECT_QUIC_BUG(
+ ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
+ kNewPeerAddress, ENCRYPTION_INITIAL),
+ "");
+ } else {
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _)).Times(0);
+ ProcessFramePacketWithAddresses(QuicFrame(&frame), kSelfAddress,
+ kNewPeerAddress, ENCRYPTION_INITIAL);
+ }
EXPECT_FALSE(connection_.connected());
}
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index aa3b43d..73ae73e 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -67,6 +67,7 @@
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_use_early_select_cert, true)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_use_per_handshaker_proof_source, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_unified_iw_options, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_update_packet_content_returns_connected, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_circular_deque_for_unacked_packets_v2, true)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_encryption_level_context, true)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_write_or_buffer_data_at_level, false)