Internal change

PiperOrigin-RevId: 388368176
diff --git a/quic/core/crypto/tls_connection.cc b/quic/core/crypto/tls_connection.cc
index beb81fc..7a66e2f 100644
--- a/quic/core/crypto/tls_connection.cc
+++ b/quic/core/crypto/tls_connection.cc
@@ -5,6 +5,7 @@
 #include "quic/core/crypto/tls_connection.h"
 
 #include "absl/strings/string_view.h"
+#include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "quic/platform/api/quic_bug_tracker.h"
 
 namespace quic {
@@ -107,6 +108,13 @@
   }
 }
 
+void TlsConnection::EnableInfoCallback() {
+  SSL_set_info_callback(
+      ssl(), +[](const SSL* ssl, int type, int value) {
+        ConnectionFromSsl(ssl)->delegate_->InfoCallback(type, value);
+      });
+}
+
 // static
 bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx(int cert_verify_mode) {
   CRYPTO_library_init();
diff --git a/quic/core/crypto/tls_connection.h b/quic/core/crypto/tls_connection.h
index 329bb33..f59eaa1 100644
--- a/quic/core/crypto/tls_connection.h
+++ b/quic/core/crypto/tls_connection.h
@@ -75,12 +75,21 @@
     // level |level|.
     virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
 
+    // Informational callback from BoringSSL. This callback is disabled by
+    // default, but can be enabled by TlsConnection::EnableInfoCallback.
+    //
+    // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+    virtual void InfoCallback(int type, int value) = 0;
+
     friend class TlsConnection;
   };
 
   TlsConnection(const TlsConnection&) = delete;
   TlsConnection& operator=(const TlsConnection&) = delete;
 
+  // Configure the SSL such that delegate_->InfoCallback will be called.
+  void EnableInfoCallback();
+
   // Functions to convert between BoringSSL's enum ssl_encryption_level_t and
   // QUIC's EncryptionLevel.
   static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 2089704..82b06d8 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -17,6 +17,8 @@
 QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_false, false)
 // A testonly restart flag that will always default to true.
 QUIC_FLAG(FLAGS_quic_restart_flag_quic_testonly_default_true, true)
+// If true and a QUIC connection is traced, add ssl events to the trace.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_trace_ssl_events, true)
 // If true, GFE will explicitly configure its signature algorithm preference.
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_set_signature_algorithm_prefs, false)
 // If true, QUIC will default enable MTU discovery at server, with a target of 1450 bytes.
diff --git a/quic/core/tls_handshaker.h b/quic/core/tls_handshaker.h
index e88e7a6..72ae099 100644
--- a/quic/core/tls_handshaker.h
+++ b/quic/core/tls_handshaker.h
@@ -163,6 +163,11 @@
   // error code corresponding to the TLS alert description |desc|.
   void SendAlert(EncryptionLevel level, uint8_t desc) override;
 
+  // Informational callback from BoringSSL. Subclasses can override it to do
+  // logging, tracing, etc.
+  // See |SSL_CTX_set_info_callback| for the meaning of |type| and |value|.
+  void InfoCallback(int /*type*/, int /*value*/) override {}
+
  private:
   // ProofVerifierCallbackImpl handles the result of an asynchronous certificate
   // verification operation.
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index db7202e..b2817b1 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -191,11 +191,15 @@
   if (GetQuicFlag(FLAGS_quic_disable_server_tls_resumption)) {
     SSL_set_options(ssl(), SSL_OP_NO_TICKET);
   }
+
+  if (GetQuicReloadableFlag(quic_trace_ssl_events) &&
+      session->connection()->context()->tracer) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_trace_ssl_events);
+    tls_connection_.EnableInfoCallback();
+  }
 }
 
-TlsServerHandshaker::~TlsServerHandshaker() {
-  CancelOutstandingCallbacks();
-}
+TlsServerHandshaker::~TlsServerHandshaker() { CancelOutstandingCallbacks(); }
 
 void TlsServerHandshaker::CancelOutstandingCallbacks() {
   if (proof_source_handle_) {
@@ -207,6 +211,40 @@
   }
 }
 
+void TlsServerHandshaker::InfoCallback(int type, int value) {
+  QuicConnectionTracer* tracer =
+      session()->connection()->context()->tracer.get();
+
+  if (tracer == nullptr) {
+    return;
+  }
+
+  if (type & SSL_CB_LOOP) {
+    tracer->PrintString(
+        absl::StrCat("SSL:ACCEPT_LOOP:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_ALERT) {
+    const char* prefix =
+        (type & SSL_CB_READ) ? "SSL:READ_ALERT:" : "SSL:WRITE_ALERT:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_alert_type_string_long(value),
+                                     ":", SSL_alert_desc_string_long(value)));
+  } else if (type & SSL_CB_EXIT) {
+    const char* prefix =
+        (value == 1) ? "SSL:ACCEPT_EXIT_OK:" : "SSL:ACCEPT_EXIT_FAIL:";
+    tracer->PrintString(absl::StrCat(prefix, SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_START) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_START:", SSL_state_string_long(ssl())));
+  } else if (type & SSL_CB_HANDSHAKE_DONE) {
+    tracer->PrintString(
+        absl::StrCat("SSL:HANDSHAKE_DONE:", SSL_state_string_long(ssl())));
+  } else {
+    QUIC_DLOG(INFO) << "Unknown event type " << type << ": "
+                    << SSL_state_string_long(ssl());
+    tracer->PrintString(
+        absl::StrCat("SSL:unknown:", value, ":", SSL_state_string_long(ssl())));
+  }
+}
+
 std::unique_ptr<ProofSourceHandle>
 TlsServerHandshaker::MaybeCreateProofSourceHandle() {
   return std::make_unique<DefaultProofSourceHandle>(this, proof_source_);
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index 9ea70a6..998cc15 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -89,6 +89,9 @@
       const std::string& hostname) const;
 
  protected:
+  // Override for tracing.
+  void InfoCallback(int type, int value) override;
+
   // Creates a proof source handle for selecting cert and computing signature.
   virtual std::unique_ptr<ProofSourceHandle> MaybeCreateProofSourceHandle();