Add version-aware QuicConnectionCloseFrame constructor Adds a version-aware constructor for QuicConnectionCloseFrames. Based on the version, this constructor handles generation of the correct close codes and frame types. gfe-relnote: N/A moves around existing function (some version-99 protected) PiperOrigin-RevId: 267647428 Change-Id: I24aabc9abc1b803610b34d9f8fac60133bd1368c
diff --git a/quic/core/frames/quic_connection_close_frame.cc b/quic/core/frames/quic_connection_close_frame.cc index 63e0aee..8f1fe24 100644 --- a/quic/core/frames/quic_connection_close_frame.cc +++ b/quic/core/frames/quic_connection_close_frame.cc
@@ -52,6 +52,33 @@ DCHECK_LE(transport_error_code, kMaxIetfVarInt); } +QuicConnectionCloseFrame::QuicConnectionCloseFrame( + QuicTransportVersion transport_version, + QuicErrorCode error_code, + std::string error_phrase, + uint64_t frame_type) + : extracted_error_code(error_code), error_details(error_phrase) { + if (!VersionHasIetfQuicFrames(transport_version)) { + close_type = GOOGLE_QUIC_CONNECTION_CLOSE; + quic_error_code = error_code; + transport_close_frame_type = 0; + return; + } + QuicErrorCodeToIetfMapping mapping = + QuicErrorCodeToTransportErrorCode(error_code); + if (mapping.is_transport_close_) { + // Maps to a transport close + close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; + transport_error_code = mapping.transport_error_code_; + transport_close_frame_type = frame_type; + return; + } + // Maps to an application close. + close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE; + application_error_code = mapping.application_error_code_; + transport_close_frame_type = 0; +} + std::ostream& operator<<( std::ostream& os, const QuicConnectionCloseFrame& connection_close_frame) {
diff --git a/quic/core/frames/quic_connection_close_frame.h b/quic/core/frames/quic_connection_close_frame.h index b0cef45..9b6fdd4 100644 --- a/quic/core/frames/quic_connection_close_frame.h +++ b/quic/core/frames/quic_connection_close_frame.h
@@ -10,6 +10,7 @@ #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/core/quic_versions.h" #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" namespace quic { @@ -17,6 +18,15 @@ struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame { QuicConnectionCloseFrame(); + // Builds a connection close frame based on the transport version + // and the mapping of error_code. THIS IS THE PREFERRED C'TOR + // TO USE IF YOU NEED TO CREATE A CONNECTION-CLOSE-FRAME AND + // HAVE IT BE CORRECT FOR THE VERSION AND CODE MAPPINGS. + QuicConnectionCloseFrame(QuicTransportVersion transport_version, + QuicErrorCode error_code, + std::string error_phrase, + uint64_t transport_close_frame_type); + // TODO(fkastenholz): After migration to supporting IETF QUIC, this probably // should be deprecated. QuicConnectionCloseFrame(QuicErrorCode error_code, std::string error_details);
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 269fe7f..52b5f70 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -2858,21 +2858,9 @@ SendAck(); } QuicConnectionCloseFrame* frame; - if (VersionHasIetfQuicFrames(transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(error); - if (mapping.is_transport_close_) { - frame = new QuicConnectionCloseFrame( - error, details, mapping.transport_error_code_, - framer_.current_received_frame_type()); - } else { - // Maps to an application close. - frame = new QuicConnectionCloseFrame(error, details, - mapping.application_error_code_); - } - } else { - frame = new QuicConnectionCloseFrame(error, details); - } + + frame = new QuicConnectionCloseFrame(transport_version(), error, details, + framer_.current_received_frame_type()); packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame)); packet_generator_.FlushAllQueuedFrames(); if (GetQuicReloadableFlag(quic_clear_queued_packets_on_connection_close)) {
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 9fc985f..6df0f7d 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -1457,27 +1457,9 @@ header.packet_number = QuicPacketNumber(number); QuicErrorCode kQuicErrorCode = QUIC_PEER_GOING_AWAY; - // This QuicConnectionCloseFrame will default to being for a Google QUIC - // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A, - // depending on the mapping. - QuicConnectionCloseFrame qccf(kQuicErrorCode, ""); - if (VersionHasIetfQuicFrames(peer_framer_.transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(kQuicErrorCode); - if (mapping.is_transport_close_) { - // Maps to a transport close - qccf.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - qccf.transport_error_code = mapping.transport_error_code_; - // Frame type is not important for the tests that invoke this method. - qccf.transport_close_frame_type = 0; - } else { - // Maps to an application close. - qccf.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE; - qccf.application_error_code = mapping.application_error_code_; - } - qccf.extracted_error_code = kQuicErrorCode; - } - + QuicConnectionCloseFrame qccf(peer_framer_.transport_version(), + kQuicErrorCode, "", + /*transport_close_frame_type=*/0); QuicFrames frames; frames.push_back(QuicFrame(&qccf)); return ConstructPacket(header, frames); @@ -7020,25 +7002,9 @@ // This QuicConnectionCloseFrame will default to being for a Google QUIC // close. If doing IETF QUIC then set fields appropriately for CC/T or CC/A, // depending on the mapping. - QuicConnectionCloseFrame qccf(kQuicErrorCode, ""); - if (VersionHasIetfQuicFrames(peer_framer_.transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(kQuicErrorCode); - if (mapping.is_transport_close_) { - // Maps to a transport close - qccf.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - qccf.transport_error_code = mapping.transport_error_code_; - // TODO(fkastenholz) need to change "0" to get the frame type currently - // being processed so that it can be inserted into the frame. - qccf.transport_close_frame_type = 0; - } else { - // Maps to an application close. - qccf.close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE; - qccf.application_error_code = mapping.application_error_code_; - } - // qccf.extracted_error_code = kQuicErrorCode; - } - + QuicConnectionCloseFrame qccf(peer_framer_.transport_version(), + kQuicErrorCode, "", + /*transport_close_frame_type=*/0); QuicFrames frames; frames.push_back(QuicFrame(frame1_)); frames.push_back(QuicFrame(&qccf)); @@ -8699,25 +8665,10 @@ EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective()); const QuicErrorCode kErrorCode = QUIC_INTERNAL_ERROR; std::unique_ptr<QuicConnectionCloseFrame> connection_close_frame( - new QuicConnectionCloseFrame(kErrorCode, "")); - if (VersionHasIetfQuicFrames(connection_.transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(kErrorCode); - if (mapping.is_transport_close_) { - // Maps to a transport close - connection_close_frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - connection_close_frame->transport_error_code = - mapping.transport_error_code_; - connection_close_frame->transport_close_frame_type = 0; - } else { - // Maps to an application close. - connection_close_frame->close_type = - IETF_QUIC_APPLICATION_CONNECTION_CLOSE; - connection_close_frame->application_error_code = - mapping.application_error_code_; - } - connection_close_frame->extracted_error_code = kErrorCode; - } + new QuicConnectionCloseFrame(connection_.transport_version(), kErrorCode, + "", + /*transport_close_frame_type=*/0)); + // Received 2 packets. QuicFrame frame; if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc index 94dc3bf..75524aa 100644 --- a/quic/core/quic_dispatcher.cc +++ b/quic/core/quic_dispatcher.cc
@@ -133,25 +133,9 @@ void CloseConnection(QuicErrorCode error_code, const std::string& error_details, bool ietf_quic) { - QuicConnectionCloseFrame* frame = - new QuicConnectionCloseFrame(error_code, error_details); - if (VersionHasIetfQuicFrames(framer_.transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(error_code); - if (mapping.is_transport_close_) { - // Maps to a transport close - frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - frame->transport_error_code = mapping.transport_error_code_; - // If closing the connection in the stateless terminator then there is - // no frame that is being processed. - frame->transport_close_frame_type = 0; - } else { - // Maps to an application close. - frame->close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE; - frame->application_error_code = mapping.application_error_code_; - } - frame->extracted_error_code = error_code; - } + QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame( + framer_.transport_version(), error_code, error_details, + /*transport_close_frame_type=*/0); if (!creator_.AddSavedFrame(QuicFrame(frame), NOT_RETRANSMISSION)) { QUIC_BUG << "Unable to add frame to an empty packet";
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc index ff9960f..1da89ba 100644 --- a/quic/core/quic_packet_creator_test.cc +++ b/quic/core/quic_packet_creator_test.cc
@@ -576,10 +576,9 @@ } TEST_P(QuicPacketCreatorTest, SerializeConnectionClose) { - QuicConnectionCloseFrame frame(QUIC_NO_ERROR, "error"); - if (VersionHasIetfQuicFrames(GetParam().version.transport_version)) { - frame.close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - } + QuicConnectionCloseFrame frame(GetParam().version.transport_version, + QUIC_NO_ERROR, "error", + /*transport_close_frame_type=*/0); QuicFrames frames; frames.push_back(QuicFrame(&frame));
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc index bd66cb1..c60bac2 100644 --- a/quic/core/quic_packet_generator_test.cc +++ b/quic/core/quic_packet_generator_test.cc
@@ -1291,24 +1291,10 @@ char buf[2000] = {}; QuicStringPiece error_details(buf, 2000); const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR; - QuicConnectionCloseFrame* frame = - new QuicConnectionCloseFrame(kQuicErrorCode, std::string(error_details)); - if (VersionHasIetfQuicFrames(framer_.transport_version())) { - QuicErrorCodeToIetfMapping mapping = - QuicErrorCodeToTransportErrorCode(kQuicErrorCode); - if (mapping.is_transport_close_) { - // Maps to a transport close - frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE; - frame->transport_error_code = mapping.transport_error_code_; - // Frame type is not important for the tests that invoke this method. - frame->transport_close_frame_type = 0; - } else { - // Maps to an application close. - frame->close_type = IETF_QUIC_APPLICATION_CONNECTION_CLOSE; - frame->application_error_code = mapping.application_error_code_; - } - frame->extracted_error_code = kQuicErrorCode; - } + + QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame( + framer_.transport_version(), kQuicErrorCode, std::string(error_details), + /*transport_close_frame_type=*/0); generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame), /*bundle_ack=*/false); EXPECT_TRUE(generator_.HasPendingFrames());