Add TLS to QuicIetfTransportErrorCodeString This CL also logs the error code string from the interop test client to help debugging handshake failures. gfe-relnote: n/a, log-only PiperOrigin-RevId: 293340850 Change-Id: Ia8cca47421b366e33c5aadd7b717af49ec59c4fc
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc index 351cd10..c0bdf1e 100644 --- a/quic/core/quic_types.cc +++ b/quic/core/quic_types.cc
@@ -6,6 +6,7 @@ #include <cstdint> +#include "third_party/boringssl/src/include/openssl/ssl.h" #include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" @@ -79,8 +80,25 @@ return #x; std::string QuicIetfTransportErrorCodeString(QuicIetfTransportErrorCodes c) { - if (static_cast<uint16_t>(c) >= 0xff00u) { - return quiche::QuicheStrCat("Private value: ", static_cast<uint16_t>(c)); + if (static_cast<uint64_t>(c) >= 0xff00u) { + return quiche::QuicheStrCat("Private(", static_cast<uint64_t>(c), ")"); + } + if (c >= CRYPTO_ERROR_FIRST && c <= CRYPTO_ERROR_LAST) { + const int tls_error = static_cast<int>(c - CRYPTO_ERROR_FIRST); + const char* tls_error_description = SSL_alert_desc_string_long(tls_error); + if (strcmp("unknown", tls_error_description) != 0) { + return quiche::QuicheStrCat("CRYPTO_ERROR(", tls_error_description, ")"); + } + // SSL_alert_desc_string_long doesn't currently support these two errors. + // TODO(dschinazi) remove this once BoringSSL supports them. + // https://boringssl-review.googlesource.com/c/boringssl/+/39784 + if (tls_error == SSL_AD_MISSING_EXTENSION) { + return "CRYPTO_ERROR(missing extension)"; + } + if (tls_error == 120) { + return "CRYPTO_ERROR(no application protocol)"; + } + return quiche::QuicheStrCat("CRYPTO_ERROR(unknown(", tls_error, "))"); } switch (c) { @@ -93,13 +111,19 @@ RETURN_STRING_LITERAL(FINAL_SIZE_ERROR); RETURN_STRING_LITERAL(FRAME_ENCODING_ERROR); RETURN_STRING_LITERAL(TRANSPORT_PARAMETER_ERROR); - RETURN_STRING_LITERAL(VERSION_NEGOTIATION_ERROR); + RETURN_STRING_LITERAL(CONNECTION_ID_LIMIT_ERROR); RETURN_STRING_LITERAL(PROTOCOL_VIOLATION); - RETURN_STRING_LITERAL(INVALID_MIGRATION); - default: - return quiche::QuicheStrCat("Unknown Transport Error Code Value: ", - static_cast<uint16_t>(c)); + RETURN_STRING_LITERAL(INVALID_TOKEN); + RETURN_STRING_LITERAL(CRYPTO_BUFFER_EXCEEDED); + // CRYPTO_ERROR is handled in the if before this switch, these cases do not + // change behavior and are only here to make the compiler happy. + case CRYPTO_ERROR_FIRST: + case CRYPTO_ERROR_LAST: + DCHECK(false) << "Unexpected error " << static_cast<uint64_t>(c); + break; } + + return quiche::QuicheStrCat("Unknown(", static_cast<uint64_t>(c), ")"); } std::ostream& operator<<(std::ostream& os,
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h index f149ed3..e027b7b 100644 --- a/quic/core/quic_types.h +++ b/quic/core/quic_types.h
@@ -562,9 +562,12 @@ FINAL_SIZE_ERROR = 0x6, FRAME_ENCODING_ERROR = 0x7, TRANSPORT_PARAMETER_ERROR = 0x8, - VERSION_NEGOTIATION_ERROR = 0x9, + CONNECTION_ID_LIMIT_ERROR = 0x9, PROTOCOL_VIOLATION = 0xA, - INVALID_MIGRATION = 0xC, + INVALID_TOKEN = 0xB, + CRYPTO_BUFFER_EXCEEDED = 0xD, + CRYPTO_ERROR_FIRST = 0x100, + CRYPTO_ERROR_LAST = 0x1FF, }; QUIC_EXPORT_PRIVATE std::string QuicIetfTransportErrorCodeString( QuicIetfTransportErrorCodes c);
diff --git a/quic/core/quic_types_test.cc b/quic/core/quic_types_test.cc index d238c78..63ebdb0 100644 --- a/quic/core/quic_types_test.cc +++ b/quic/core/quic_types_test.cc
@@ -6,6 +6,7 @@ #include <cstdint> +#include "net/third_party/quiche/src/quic/core/quic_error_codes.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h" @@ -17,7 +18,7 @@ TEST_F(QuicTypesTest, QuicIetfTransportErrorCodeString) { // QuicIetfTransportErrorCode out of bound. - for (quic::QuicErrorCode error = quic::QUIC_ENCRYPTION_FAILURE; + for (quic::QuicErrorCode error = quic::QUIC_PACKET_TOO_LARGE; error < quic::QUIC_LAST_ERROR; error = static_cast<quic::QuicErrorCode>(error + 1)) { QuicErrorCodeToIetfMapping mapping = @@ -25,8 +26,10 @@ if (mapping.is_transport_close_) { EXPECT_EQ(QuicIetfTransportErrorCodeString(mapping.transport_error_code_), quiche::QuicheStrCat( - "Unknown Transport Error Code Value: ", - static_cast<uint16_t>(mapping.transport_error_code_))); + "Unknown(", + static_cast<uint64_t>(mapping.transport_error_code_), ")")) + << " " << static_cast<uint64_t>(error) << " " + << QuicErrorCodeToString(error); } } }
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc index 9742d63..03d32a5 100644 --- a/quic/tools/quic_client_interop_test_bin.cc +++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -106,11 +106,18 @@ case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE: if (frame.transport_error_code == NO_IETF_QUIC_ERROR) { InsertFeature(Feature::kConnectionClose); + } else { + QUIC_LOG(ERROR) << "Received transport connection close " + << QuicIetfTransportErrorCodeString( + frame.transport_error_code); } break; case IETF_QUIC_APPLICATION_CONNECTION_CLOSE: if (frame.application_error_code == 0) { InsertFeature(Feature::kConnectionClose); + } else { + QUIC_LOG(ERROR) << "Received application connection close " + << frame.application_error_code; } break; }