Remove IETF QUIC Application Close frame, replace with Connection Close
This CL removes the IETF QUIC Application Close frame and replaces it with the Connection Close frame. QuicConnectionCloseFrame::close_type indicates whether the frame is a Google QUIC Connection Close, IETF QUIC Connection Close/Transport or IETF QUIC Connection Close/Application.
The QuicFramer::...ApplicationCloseFrame... methods are removed.
gfe-relnote: N/A affects only IETF-QUIC/V99 code. Application Close was IETF-QUIC only.
PiperOrigin-RevId: 242881293
Change-Id: I783cbf4e5f27d2e5abe3e8b518006de03c815e1a
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index c24a23c..f99b60f 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -588,28 +588,30 @@
QuicTransportVersion version,
const QuicConnectionCloseFrame& frame) {
if (version == QUIC_VERSION_99) {
+ // TODO(fkastenholz): For complete support of IETF QUIC CONNECTION_CLOSE,
+ // check if the frame is a Transport close and if the frame's
+ // extracted_error_code is not QUIC_IETF_GQUIC_ERROR_MISSING. If so,
+ // extend the error string to include " QuicErrorCode: #"
+ if (frame.close_type == IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+ // Application close variant does not include the transport close frame
+ // type field.
+ return QuicDataWriter::GetVarInt62Len(
+ TruncatedErrorStringSize(frame.error_details)) +
+ kQuicFrameTypeSize + kQuicIetfQuicErrorCodeSize;
+ }
+ QUIC_BUG_IF(frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE)
+ << "IETF QUIC Connection close and QuicConnectionCloseFrame type is "
+ "not IETF ConnectionClose";
return QuicDataWriter::GetVarInt62Len(
TruncatedErrorStringSize(frame.error_details)) +
QuicDataWriter::GetVarInt62Len(frame.transport_close_frame_type) +
kQuicFrameTypeSize + kQuicIetfQuicErrorCodeSize;
}
+ // Not version 99/IETF QUIC, return Google QUIC CONNECTION CLOSE frame size.
return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize;
}
// static
-size_t QuicFramer::GetMinApplicationCloseFrameSize(
- QuicTransportVersion version,
- const QuicApplicationCloseFrame& frame) {
- if (version != QUIC_VERSION_99) {
- QUIC_BUG << "In version " << version
- << " - not 99 - and tried to serialize ApplicationClose.";
- }
- return QuicDataWriter::GetVarInt62Len(
- TruncatedErrorStringSize(frame.error_details)) +
- kQuicFrameTypeSize + kQuicIetfQuicErrorCodeSize;
-}
-
-// static
size_t QuicFramer::GetMinGoAwayFrameSize() {
return kQuicFrameTypeSize + kQuicErrorCodeSize + kQuicErrorDetailsLengthSize +
kQuicMaxStreamIdSize;
@@ -721,11 +723,6 @@
return GetWindowUpdateFrameSize(version, *frame.window_update_frame);
case BLOCKED_FRAME:
return GetBlockedFrameSize(version, *frame.blocked_frame);
- case APPLICATION_CLOSE_FRAME:
- return GetMinApplicationCloseFrameSize(version,
- *frame.application_close_frame) +
- TruncatedErrorStringSize(
- frame.application_close_frame->error_details);
case NEW_CONNECTION_ID_FRAME:
return GetNewConnectionIdFrameSize(*frame.new_connection_id_frame);
case RETIRE_CONNECTION_ID_FRAME:
@@ -1027,10 +1024,6 @@
return 0;
}
break;
- case APPLICATION_CLOSE_FRAME:
- set_detailed_error(
- "Attempt to append APPLICATION_CLOSE frame and not in version 99.");
- return RaiseError(QUIC_INTERNAL_ERROR);
case NEW_CONNECTION_ID_FRAME:
set_detailed_error(
"Attempt to append NEW_CONNECTION_ID frame and not in version 99.");
@@ -1144,9 +1137,10 @@
}
break;
case CONNECTION_CLOSE_FRAME:
- if (!AppendConnectionCloseFrame(*frame.connection_close_frame,
- writer)) {
- QUIC_BUG << "AppendConnectionCloseFrame failed: " << detailed_error();
+ if (!AppendIetfConnectionCloseFrame(*frame.connection_close_frame,
+ writer)) {
+ QUIC_BUG << "AppendIetfConnectionCloseFrame failed: "
+ << detailed_error();
return 0;
}
break;
@@ -1175,14 +1169,6 @@
return 0;
}
break;
- case APPLICATION_CLOSE_FRAME:
- if (!AppendApplicationCloseFrame(*frame.application_close_frame,
- writer)) {
- QUIC_BUG << "AppendApplicationCloseFrame failed: "
- << detailed_error();
- return 0;
- }
- break;
case MAX_STREAM_ID_FRAME:
if (!AppendMaxStreamsFrame(frame.max_stream_id_frame, writer)) {
QUIC_BUG << "AppendMaxStreamsFrame failed" << detailed_error();
@@ -2906,11 +2892,7 @@
case IETF_CONNECTION_CLOSE: {
QuicConnectionCloseFrame frame;
if (!ProcessIetfConnectionCloseFrame(
- reader,
- ((frame_type == IETF_CONNECTION_CLOSE)
- ? IETF_QUIC_TRANSPORT_CONNECTION_CLOSE
- : IETF_QUIC_APPLICATION_CONNECTION_CLOSE),
- &frame)) {
+ reader, IETF_QUIC_TRANSPORT_CONNECTION_CLOSE, &frame)) {
return RaiseError(QUIC_INVALID_CONNECTION_CLOSE_DATA);
}
if (!visitor_->OnConnectionCloseFrame(frame)) {
@@ -2921,8 +2903,9 @@
break;
}
case IETF_APPLICATION_CLOSE: {
- QuicApplicationCloseFrame frame;
- if (!ProcessApplicationCloseFrame(reader, &frame)) {
+ QuicConnectionCloseFrame frame;
+ if (!ProcessIetfConnectionCloseFrame(
+ reader, IETF_QUIC_APPLICATION_CONNECTION_CLOSE, &frame)) {
return RaiseError(QUIC_INVALID_APPLICATION_CLOSE_DATA);
}
if (!visitor_->OnApplicationCloseFrame(frame)) {
@@ -4238,11 +4221,6 @@
case MTU_DISCOVERY_FRAME:
type_byte = static_cast<uint8_t>(PING_FRAME);
break;
-
- case APPLICATION_CLOSE_FRAME:
- set_detailed_error(
- "Attempt to append APPLICATION_CLOSE frame and not in version 99.");
- return RaiseError(QUIC_INTERNAL_ERROR);
case NEW_CONNECTION_ID_FRAME:
set_detailed_error(
"Attempt to append NEW_CONNECTION_ID frame and not in version 99.");
@@ -4299,7 +4277,17 @@
type_byte = IETF_RST_STREAM;
break;
case CONNECTION_CLOSE_FRAME:
- type_byte = IETF_CONNECTION_CLOSE;
+ switch (frame.connection_close_frame->close_type) {
+ case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
+ type_byte = IETF_APPLICATION_CLOSE;
+ break;
+ case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
+ type_byte = IETF_CONNECTION_CLOSE;
+ break;
+ default:
+ set_detailed_error("Invalid QuicConnectionCloseFrame type.");
+ return RaiseError(QUIC_INTERNAL_ERROR);
+ }
break;
case GOAWAY_FRAME:
set_detailed_error(
@@ -4342,9 +4330,6 @@
// The path MTU discovery frame is encoded as a PING frame on the wire.
type_byte = IETF_PING;
break;
- case APPLICATION_CLOSE_FRAME:
- type_byte = IETF_APPLICATION_CLOSE;
- break;
case NEW_CONNECTION_ID_FRAME:
type_byte = IETF_NEW_CONNECTION_ID;
break;
@@ -5187,16 +5172,31 @@
bool QuicFramer::AppendIetfConnectionCloseFrame(
const QuicConnectionCloseFrame& frame,
QuicDataWriter* writer) {
+ if (frame.close_type != IETF_QUIC_TRANSPORT_CONNECTION_CLOSE &&
+ frame.close_type != IETF_QUIC_APPLICATION_CONNECTION_CLOSE) {
+ QUIC_BUG << "Invalid close_type for writing IETF CONNECTION CLOSE.";
+ set_detailed_error("Invalid close_type for writing IETF CONNECTION CLOSE.");
+ return false;
+ }
+
if (!writer->WriteUInt16(frame.application_error_code)) {
set_detailed_error("Can not write connection close frame error code");
return false;
}
- if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
- set_detailed_error("Writing frame type failed.");
- return false;
+ if (frame.close_type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+ // Write the frame-type of the frame causing the error only
+ // if it's a CONNECTION_CLOSE/Transport.
+ if (!writer->WriteVarInt62(frame.transport_close_frame_type)) {
+ set_detailed_error("Writing frame type failed.");
+ return false;
+ }
}
+ // TODO(fkastenholz): For full IETF CONNECTION CLOSE support,
+ // if this is a Transport CONNECTION_CLOSE and the extended
+ // error is not QUIC_IETF_GQUIC_ERROR_MISSING then append the extended
+ // "QuicErrorCode: #" string to the phrase.
if (!writer->WriteStringPieceVarInt62(
TruncateErrorString(frame.error_details))) {
set_detailed_error("Can not write connection close phrase");
@@ -5205,22 +5205,6 @@
return true;
}
-bool QuicFramer::AppendApplicationCloseFrame(
- const QuicApplicationCloseFrame& frame,
- QuicDataWriter* writer) {
- if (!writer->WriteUInt16(static_cast<const uint16_t>(frame.error_code))) {
- set_detailed_error("Can not write application close frame error code");
- return false;
- }
-
- if (!writer->WriteStringPieceVarInt62(
- TruncateErrorString(frame.error_details))) {
- set_detailed_error("Can not write application close phrase");
- return false;
- }
- return true;
-}
-
bool QuicFramer::ProcessIetfConnectionCloseFrame(
QuicDataReader* reader,
QuicConnectionCloseType type,
@@ -5233,9 +5217,13 @@
}
frame->transport_error_code = static_cast<QuicIetfTransportErrorCodes>(code);
- if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
- set_detailed_error("Unable to read connection close frame type.");
- return false;
+ if (type == IETF_QUIC_TRANSPORT_CONNECTION_CLOSE) {
+ // The frame-type of the frame causing the error is present only
+ // if it's a CONNECTION_CLOSE/Transport.
+ if (!reader->ReadVarInt62(&frame->transport_close_frame_type)) {
+ set_detailed_error("Unable to read connection close frame type.");
+ return false;
+ }
}
uint64_t phrase_length;
@@ -5248,31 +5236,9 @@
set_detailed_error("Unable to read connection close error details.");
return false;
}
- frame->error_details = std::string(phrase);
-
- return true;
-}
-
-bool QuicFramer::ProcessApplicationCloseFrame(
- QuicDataReader* reader,
- QuicApplicationCloseFrame* frame) {
- uint16_t code;
- if (!reader->ReadUInt16(&code)) {
- set_detailed_error("Unable to read application close error code.");
- return false;
- }
- frame->error_code = static_cast<QuicErrorCode>(code);
-
- uint64_t phrase_length;
- if (!reader->ReadVarInt62(&phrase_length)) {
- set_detailed_error("Unable to read application close error details.");
- return false;
- }
- QuicStringPiece phrase;
- if (!reader->ReadStringPiece(&phrase, static_cast<size_t>(phrase_length))) {
- set_detailed_error("Unable to read application close error details.");
- return false;
- }
+ // TODO(fkastenholz): when full support is done, add code here
+ // to extract the extended error code from the reason phrase
+ // and set it into frame->extracted_error_code.
frame->error_details = std::string(phrase);
return true;