Improve QUIC TLS error logging

This CL adds the TLS error description to our error_details and displays it in the QuicToyClient. This will facilitate debugging efforts.

gfe-relnote: improve error details, protected by TLS flags
PiperOrigin-RevId: 301396582
Change-Id: Idc39aa1c16ecd7ca32ab28099a4cfc6a7067bef8
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc
index 6282358..5d69250 100644
--- a/quic/core/quic_types.cc
+++ b/quic/core/quic_types.cc
@@ -95,15 +95,6 @@
     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, "))");
   }
 
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
index ac8bcee..1b20063 100644
--- a/quic/core/tls_handshaker.cc
+++ b/quic/core/tls_handshaker.cc
@@ -10,6 +10,7 @@
 #include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
 
 namespace quic {
@@ -89,16 +90,18 @@
 
 void TlsHandshaker::FlushFlight() {}
 
-void TlsHandshaker::SendAlert(EncryptionLevel /*level*/, uint8_t desc) {
-  // TODO(nharper): Alerts should be sent on the wire as a 16-bit QUIC error
-  // code computed to be 0x100 | desc (draft-ietf-quic-tls-14, section 4.8).
+void TlsHandshaker::SendAlert(EncryptionLevel level, uint8_t desc) {
+  // TODO(b/151676147): Alerts should be sent on the wire as a varint QUIC error
+  // code computed to be 0x100 | desc (draft-ietf-quic-tls-27, section 4.9).
   // This puts it in the range reserved for CRYPTO_ERROR
-  // (draft-ietf-quic-transport-14, section 11.3). However, according to
+  // (draft-ietf-quic-transport-27, section 20). However, according to
   // quic_error_codes.h, this QUIC implementation only sends 1-byte error codes
   // right now.
-  QUIC_DLOG(INFO) << "TLS failing handshake due to alert "
-                  << static_cast<int>(desc);
-  CloseConnection(QUIC_HANDSHAKE_FAILED, "TLS handshake failure");
+  std::string error_details = quiche::QuicheStrCat(
+      "TLS handshake failure (", EncryptionLevelToString(level), ") ",
+      static_cast<int>(desc), ": ", SSL_alert_desc_string_long(desc));
+  QUIC_DLOG(ERROR) << error_details;
+  CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
 }
 
 }  // namespace quic
diff --git a/quic/tools/quic_toy_client.cc b/quic/tools/quic_toy_client.cc
index 63a0671..5733e0b 100644
--- a/quic/tools/quic_toy_client.cc
+++ b/quic/tools/quic_toy_client.cc
@@ -242,15 +242,15 @@
   if (!client->Connect()) {
     quic::QuicErrorCode error = client->session()->error();
     if (error == quic::QUIC_INVALID_VERSION) {
-      std::cerr << "Server talks QUIC, but none of the versions supported by "
-                << "this client: " << ParsedQuicVersionVectorToString(versions)
-                << std::endl;
+      std::cerr << "Failed to negotiate version with " << host << ":" << port
+                << ". " << client->session()->error_details() << std::endl;
       // 0: No error.
       // 20: Failed to connect due to QUIC_INVALID_VERSION.
       return GetQuicFlag(FLAGS_version_mismatch_ok) ? 0 : 20;
     }
-    std::cerr << "Failed to connect to " << host << ":" << port
-              << ". Error: " << quic::QuicErrorCodeToString(error) << std::endl;
+    std::cerr << "Failed to connect to " << host << ":" << port << ". "
+              << quic::QuicErrorCodeToString(error) << " "
+              << client->session()->error_details() << std::endl;
     return 1;
   }
   std::cerr << "Connected to " << host << ":" << port << std::endl;