gfe-relnote: Send IETF QUIC, HTTP/3 and QPACK error codes in CONNECTION_CLOSE frames. Protected by gfe2_reloadable_flag_quic_enable_version_draft_25_v3 and gfe2_reloadable_flag_quic_enable_version_draft_27. Map each QuicErrorCode to an appropriate IETF error code. QuicErrorCodes that are never used, or not used with CONNECTION_CLOSE frames (only internally or only with GOAWAY frames) are mapped to INTERNAL_ERROR. Add test to enforce that mapped error codes are valid transport or application error codes. PiperOrigin-RevId: 305018830 Change-Id: Ia8a9bf848c56509a480a50017a7a7080593b11ee
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc index d274c6c..71becf3 100644 --- a/quic/core/quic_framer_test.cc +++ b/quic/core/quic_framer_test.cc
@@ -7625,7 +7625,7 @@ QuicConnectionCloseFrame close_frame( framer_.transport_version(), static_cast<QuicErrorCode>( - VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x11 + VersionHasIetfQuicFrames(framer_.transport_version()) ? 0x01 : 0x05060708), "because I can", 0x05); // Set this so that it is "there" for both Google QUIC and IETF QUIC @@ -7687,8 +7687,9 @@ // frame type (IETF_CONNECTION_CLOSE frame) 0x1c, - // error code - kVarInt62OneByte + 0x11, + // IETF error code INTERNAL_ERROR = 0x01 corresponding to + // QuicErrorCode::QUIC_INTERNAL_ERROR = 0x01. + kVarInt62OneByte + 0x01, // Frame type within the CONNECTION_CLOSE frame kVarInt62OneByte + 0x05, // error details length
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc index ce24d57..38775b2 100644 --- a/quic/core/quic_types.cc +++ b/quic/core/quic_types.cc
@@ -132,303 +132,244 @@ QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode( QuicErrorCode error) { switch (error) { - // TODO(fkastenholz): Currently, all QuicError codes will map - // to application error codes and the original Google QUIC error - // code. This will change over time as we go through all calls to - // CloseConnection() and see whether the call is a Transport or an - // Application close and what the translated code should be. case QUIC_NO_ERROR: - return {true, {static_cast<uint64_t>(QUIC_NO_ERROR)}}; + return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}}; case QUIC_INTERNAL_ERROR: - return {true, {static_cast<uint64_t>(QUIC_INTERNAL_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_STREAM_DATA_AFTER_TERMINATION: - return {true, - {static_cast<uint64_t>(QUIC_STREAM_DATA_AFTER_TERMINATION)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_PACKET_HEADER: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PACKET_HEADER)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_FRAME_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_FRAME_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_MISSING_PAYLOAD: - return {true, {static_cast<uint64_t>(QUIC_MISSING_PAYLOAD)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_FEC_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_FEC_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_STREAM_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_OVERLAPPING_STREAM_DATA: - return {true, {static_cast<uint64_t>(QUIC_OVERLAPPING_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_UNENCRYPTED_STREAM_DATA: - return {true, {static_cast<uint64_t>(QUIC_UNENCRYPTED_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA: - return {true, - {static_cast<uint64_t>( - QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_MAYBE_CORRUPTED_MEMORY: - return {true, {static_cast<uint64_t>(QUIC_MAYBE_CORRUPTED_MEMORY)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_UNENCRYPTED_FEC_DATA: - return {true, {static_cast<uint64_t>(QUIC_UNENCRYPTED_FEC_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_RST_STREAM_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_RST_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_CONNECTION_CLOSE_DATA: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_CONNECTION_CLOSE_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_GOAWAY_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_GOAWAY_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_WINDOW_UPDATE_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_WINDOW_UPDATE_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_BLOCKED_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_BLOCKED_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_STOP_WAITING_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_STOP_WAITING_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_PATH_CLOSE_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_CLOSE_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_ACK_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_ACK_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_MESSAGE_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_MESSAGE_DATA)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_VERSION_NEGOTIATION_PACKET: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_VERSION_NEGOTIATION_PACKET)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_PUBLIC_RST_PACKET: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PUBLIC_RST_PACKET)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_DECRYPTION_FAILURE: - return {true, {static_cast<uint64_t>(QUIC_DECRYPTION_FAILURE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_ENCRYPTION_FAILURE: - return {true, {static_cast<uint64_t>(QUIC_ENCRYPTION_FAILURE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_PACKET_TOO_LARGE: - return {true, {static_cast<uint64_t>(QUIC_PACKET_TOO_LARGE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_PEER_GOING_AWAY: - return {true, {static_cast<uint64_t>(QUIC_PEER_GOING_AWAY)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_STREAM_ID: - return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_ID)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_PRIORITY: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PRIORITY)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_OPEN_STREAMS: - return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_OPEN_STREAMS)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_TOO_MANY_AVAILABLE_STREAMS: - return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_AVAILABLE_STREAMS)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_PUBLIC_RESET: - return {true, {static_cast<uint64_t>(QUIC_PUBLIC_RESET)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_VERSION: - return {true, {static_cast<uint64_t>(QUIC_INVALID_VERSION)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_HEADER_ID: - return {true, {static_cast<uint64_t>(QUIC_INVALID_HEADER_ID)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_NEGOTIATED_VALUE: - return {true, {static_cast<uint64_t>(QUIC_INVALID_NEGOTIATED_VALUE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_DECOMPRESSION_FAILURE: - return {true, {static_cast<uint64_t>(QUIC_DECOMPRESSION_FAILURE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_NETWORK_IDLE_TIMEOUT: - return {true, {static_cast<uint64_t>(QUIC_NETWORK_IDLE_TIMEOUT)}}; + return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}}; case QUIC_HANDSHAKE_TIMEOUT: - return {true, {static_cast<uint64_t>(QUIC_HANDSHAKE_TIMEOUT)}}; + return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}}; case QUIC_ERROR_MIGRATING_ADDRESS: - return {true, {static_cast<uint64_t>(QUIC_ERROR_MIGRATING_ADDRESS)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_ERROR_MIGRATING_PORT: - return {true, {static_cast<uint64_t>(QUIC_ERROR_MIGRATING_PORT)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_PACKET_WRITE_ERROR: - return {true, {static_cast<uint64_t>(QUIC_PACKET_WRITE_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_PACKET_READ_ERROR: - return {true, {static_cast<uint64_t>(QUIC_PACKET_READ_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_EMPTY_STREAM_FRAME_NO_FIN: - return {true, {static_cast<uint64_t>(QUIC_EMPTY_STREAM_FRAME_NO_FIN)}}; + return {true, {static_cast<uint64_t>(FRAME_ENCODING_ERROR)}}; case QUIC_INVALID_HEADERS_STREAM_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_HEADERS_STREAM_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE: - return { - true, - {static_cast<uint64_t>(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA: - return { - true, - {static_cast<uint64_t>(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)}}; + return {true, {static_cast<uint64_t>(FLOW_CONTROL_ERROR)}}; case QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA: - return {true, - {static_cast<uint64_t>(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_FLOW_CONTROL_INVALID_WINDOW: - return {true, {static_cast<uint64_t>(QUIC_FLOW_CONTROL_INVALID_WINDOW)}}; + return {true, {static_cast<uint64_t>(FLOW_CONTROL_ERROR)}}; case QUIC_CONNECTION_IP_POOLED: - return {true, {static_cast<uint64_t>(QUIC_CONNECTION_IP_POOLED)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS: - return {true, - {static_cast<uint64_t>(QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS: - return { - true, - {static_cast<uint64_t>(QUIC_TOO_MANY_OUTSTANDING_RECEIVED_PACKETS)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_CANCELLED: - return {true, {static_cast<uint64_t>(QUIC_CONNECTION_CANCELLED)}}; + return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}}; case QUIC_BAD_PACKET_LOSS_RATE: - return {true, {static_cast<uint64_t>(QUIC_BAD_PACKET_LOSS_RATE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_PUBLIC_RESETS_POST_HANDSHAKE: - return {true, {static_cast<uint64_t>(QUIC_PUBLIC_RESETS_POST_HANDSHAKE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_FAILED_TO_SERIALIZE_PACKET: - return {true, {static_cast<uint64_t>(QUIC_FAILED_TO_SERIALIZE_PACKET)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_RTOS: - return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_RTOS)}}; + return {true, {static_cast<uint64_t>(NO_IETF_QUIC_ERROR)}}; case QUIC_HANDSHAKE_FAILED: - return {true, {static_cast<uint64_t>(QUIC_HANDSHAKE_FAILED)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_TAGS_OUT_OF_ORDER: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TAGS_OUT_OF_ORDER)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_TOO_MANY_ENTRIES: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TOO_MANY_ENTRIES)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_INVALID_VALUE_LENGTH: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_INVALID_VALUE_LENGTH)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE: - return {true, - {static_cast<uint64_t>( - QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_CRYPTO_MESSAGE_TYPE: - return {true, {static_cast<uint64_t>(QUIC_INVALID_CRYPTO_MESSAGE_TYPE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_CHANNEL_ID_SIGNATURE: - return {true, {static_cast<uint64_t>(QUIC_INVALID_CHANNEL_ID_SIGNATURE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: - return {true, - {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP: - return { - true, - {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND: - return {true, - {static_cast<uint64_t>(QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_UNSUPPORTED_PROOF_DEMAND: - return {true, {static_cast<uint64_t>(QUIC_UNSUPPORTED_PROOF_DEMAND)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_INTERNAL_ERROR: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_INTERNAL_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CRYPTO_VERSION_NOT_SUPPORTED: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_VERSION_NOT_SUPPORTED)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_NO_SUPPORT: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_NO_SUPPORT)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_TOO_MANY_REJECTS: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_TOO_MANY_REJECTS)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_PROOF_INVALID: - return {true, {static_cast<uint64_t>(QUIC_PROOF_INVALID)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_DUPLICATE_TAG: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_DUPLICATE_TAG)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT: - return {true, - {static_cast<uint64_t>(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_SERVER_CONFIG_EXPIRED: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED: - return {true, - {static_cast<uint64_t>(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO: - return {true, - {static_cast<uint64_t>( - QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE: - return {true, - {static_cast<uint64_t>( - QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_CRYPTO_CHLO_TOO_LARGE: - return {true, {static_cast<uint64_t>(QUIC_CRYPTO_CHLO_TOO_LARGE)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_VERSION_NEGOTIATION_MISMATCH: - return {true, {static_cast<uint64_t>(QUIC_VERSION_NEGOTIATION_MISMATCH)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_BAD_MULTIPATH_FLAG: - return {true, {static_cast<uint64_t>(QUIC_BAD_MULTIPATH_FLAG)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_MULTIPATH_PATH_DOES_NOT_EXIST: - return {true, - {static_cast<uint64_t>(QUIC_MULTIPATH_PATH_DOES_NOT_EXIST)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_MULTIPATH_PATH_NOT_ACTIVE: - return {true, {static_cast<uint64_t>(QUIC_MULTIPATH_PATH_NOT_ACTIVE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_IP_ADDRESS_CHANGED: - return {true, {static_cast<uint64_t>(QUIC_IP_ADDRESS_CHANGED)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS: - return {true, - {static_cast<uint64_t>( - QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES: - return { - true, - {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK: - return { - true, - {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM: - return {true, - {static_cast<uint64_t>( - QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG: - return {true, - {static_cast<uint64_t>( - QUIC_CONNECTION_MIGRATION_DISABLED_BY_CONFIG)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR: - return { - true, - {static_cast<uint64_t>(QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED: - return {true, - {static_cast<uint64_t>( - QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_STREAM_DATA_INTERVALS: - return {true, - {static_cast<uint64_t>(QUIC_TOO_MANY_STREAM_DATA_INTERVALS)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_STREAM_SEQUENCER_INVALID_STATE: - return {true, - {static_cast<uint64_t>(QUIC_STREAM_SEQUENCER_INVALID_STATE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_TOO_MANY_SESSIONS_ON_SERVER: - return {true, {static_cast<uint64_t>(QUIC_TOO_MANY_SESSIONS_ON_SERVER)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_STREAM_LENGTH_OVERFLOW: - return {true, {static_cast<uint64_t>(QUIC_STREAM_LENGTH_OVERFLOW)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_MAX_DATA_FRAME_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_MAX_DATA_FRAME_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_MAX_STREAM_DATA_FRAME_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_MAX_STREAMS_DATA: - return {true, {static_cast<uint64_t>(QUIC_MAX_STREAMS_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_STREAMS_BLOCKED_DATA: - return {true, {static_cast<uint64_t>(QUIC_STREAMS_BLOCKED_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_STREAM_BLOCKED_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_STREAM_BLOCKED_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_NEW_CONNECTION_ID_DATA: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_NEW_CONNECTION_ID_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_STOP_SENDING_FRAME_DATA: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_STOP_SENDING_FRAME_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_PATH_CHALLENGE_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_CHALLENGE_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_PATH_RESPONSE_DATA: - return {true, {static_cast<uint64_t>(QUIC_INVALID_PATH_RESPONSE_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case IETF_QUIC_PROTOCOL_VIOLATION: - return {true, {static_cast<uint64_t>(IETF_QUIC_PROTOCOL_VIOLATION)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_INVALID_NEW_TOKEN: - return {true, {static_cast<uint64_t>(QUIC_INVALID_NEW_TOKEN)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM: - return {true, - {static_cast<uint64_t>( - QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM)}}; + return {true, {static_cast<uint64_t>(STREAM_STATE_ERROR)}}; case QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM: - return {true, - {static_cast<uint64_t>( - QUIC_TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_INVALID_RETIRE_CONNECTION_ID_DATA: - return {true, - {static_cast<uint64_t>(QUIC_INVALID_RETIRE_CONNECTION_ID_DATA)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_STREAMS_BLOCKED_ERROR: - return {true, {static_cast<uint64_t>(QUIC_STREAMS_BLOCKED_ERROR)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_MAX_STREAMS_ERROR: - return {true, {static_cast<uint64_t>(QUIC_MAX_STREAMS_ERROR)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_HTTP_DECODER_ERROR: - return {true, {static_cast<uint64_t>(QUIC_HTTP_DECODER_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_STALE_CONNECTION_CANCELLED: - return {true, {static_cast<uint64_t>(QUIC_STALE_CONNECTION_CANCELLED)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_IETF_GQUIC_ERROR_MISSING: - return {true, {static_cast<uint64_t>(QUIC_IETF_GQUIC_ERROR_MISSING)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM: - return {true, - {static_cast<uint64_t>( - QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES: - return {true, - {static_cast<uint64_t>(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION: - return {false, {0u}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_QPACK_DECOMPRESSION_FAILED: return { false, @@ -442,10 +383,9 @@ false, {static_cast<uint64_t>(IETF_QUIC_HTTP_QPACK_DECODER_STREAM_ERROR)}}; case QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET: - return {true, - {static_cast<uint64_t>(QUIC_STREAM_DATA_BEYOND_CLOSE_OFFSET)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_STREAM_MULTIPLE_OFFSET: - return {true, {static_cast<uint64_t>(QUIC_STREAM_MULTIPLE_OFFSET)}}; + return {true, {static_cast<uint64_t>(PROTOCOL_VIOLATION)}}; case QUIC_HTTP_FRAME_TOO_LARGE: return {false, {static_cast<uint64_t>( @@ -493,50 +433,37 @@ {static_cast<uint64_t>( QuicHttp3ErrorCode::IETF_QUIC_HTTP3_SETTINGS_ERROR)}}; case QUIC_HPACK_INDEX_VARINT_ERROR: - return {false, {static_cast<uint64_t>(QUIC_HPACK_INDEX_VARINT_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_NAME_LENGTH_VARINT_ERROR: - return {false, - {static_cast<uint64_t>(QUIC_HPACK_NAME_LENGTH_VARINT_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR: - return {false, - {static_cast<uint64_t>(QUIC_HPACK_VALUE_LENGTH_VARINT_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_NAME_TOO_LONG: - return {false, {static_cast<uint64_t>(QUIC_HPACK_NAME_TOO_LONG)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_VALUE_TOO_LONG: - return {false, {static_cast<uint64_t>(QUIC_HPACK_VALUE_TOO_LONG)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_NAME_HUFFMAN_ERROR: - return {false, {static_cast<uint64_t>(QUIC_HPACK_NAME_HUFFMAN_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_VALUE_HUFFMAN_ERROR: - return {false, {static_cast<uint64_t>(QUIC_HPACK_VALUE_HUFFMAN_ERROR)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE: - return {false, - {static_cast<uint64_t>( - QUIC_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_INVALID_INDEX: - return {false, {static_cast<uint64_t>(QUIC_HPACK_INVALID_INDEX)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_INVALID_NAME_INDEX: - return {false, {static_cast<uint64_t>(QUIC_HPACK_INVALID_NAME_INDEX)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED: - return {false, - {static_cast<uint64_t>( - QUIC_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK: - return { - false, - {static_cast<uint64_t>( - QUIC_HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING: - return {false, - {static_cast<uint64_t>( - QUIC_HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_TRUNCATED_BLOCK: - return {false, {static_cast<uint64_t>(QUIC_HPACK_TRUNCATED_BLOCK)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_FRAGMENT_TOO_LONG: - return {false, {static_cast<uint64_t>(QUIC_HPACK_FRAGMENT_TOO_LONG)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT: - return {false, - {static_cast<uint64_t>( - QUIC_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT)}}; + return {true, {static_cast<uint64_t>(INTERNAL_ERROR)}}; case QUIC_LAST_ERROR: return {false, {static_cast<uint64_t>(QUIC_LAST_ERROR)}}; }
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h index 76d3bab..9e801cd 100644 --- a/quic/core/quic_types.h +++ b/quic/core/quic_types.h
@@ -584,6 +584,8 @@ }; }; +// Convert QuicErrorCode to transport or application IETF error code +// to be used in CONNECTION_CLOSE frames. QUIC_EXPORT_PRIVATE QuicErrorCodeToIetfMapping QuicErrorCodeToTransportErrorCode(QuicErrorCode error);
diff --git a/quic/core/quic_types_test.cc b/quic/core/quic_types_test.cc index dc37c43..485c3b6 100644 --- a/quic/core/quic_types_test.cc +++ b/quic/core/quic_types_test.cc
@@ -56,6 +56,36 @@ static_cast<quic::QuicIetfTransportErrorCodes>(0x400))); } +TEST_F(QuicTypesTest, QuicErrorCodeToTransportErrorCode) { + for (int internal_error_code = 0; internal_error_code < QUIC_LAST_ERROR; + ++internal_error_code) { + std::string internal_error_code_string = + QuicErrorCodeToString(static_cast<QuicErrorCode>(internal_error_code)); + if (internal_error_code_string == "INVALID_ERROR_CODE") { + // Not a valid QuicErrorCode. + continue; + } + QuicErrorCodeToIetfMapping ietf_error_code = + QuicErrorCodeToTransportErrorCode( + static_cast<QuicErrorCode>(internal_error_code)); + if (ietf_error_code.is_transport_close_) { + QuicIetfTransportErrorCodes transport_error_code = + ietf_error_code.transport_error_code_; + bool is_valid_transport_error_code = transport_error_code <= 0x0d; + EXPECT_TRUE(is_valid_transport_error_code) << internal_error_code_string; + } else { + // Non-transport errors are application errors, either HTTP/3 or QPACK. + uint64_t application_error_code = ietf_error_code.application_error_code_; + bool is_valid_http3_error_code = + application_error_code >= 0x100 && application_error_code <= 0x110; + bool is_valid_qpack_error_code = + application_error_code >= 0x200 && application_error_code <= 0x202; + EXPECT_TRUE(is_valid_http3_error_code || is_valid_qpack_error_code) + << internal_error_code_string; + } + } +} + } // namespace } // namespace test } // namespace quic