Enable ALPS in QUIC TLS client handshake and parse ACCEPT_CH frame.

Protected by FLAGS_quic_reloadable_flag_quic_enable_alps_client.

PiperOrigin-RevId: 353406160
Change-Id: I0de0c5b43c5aa03586a02cc99684a68ec4b93ce2
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 73ae73e..55e3c76 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -38,6 +38,7 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_clip_received_error_code, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_dont_defer_sending, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_alps_client, true)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_alps_server, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_server_on_wire_ping, true)
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 862430b..e82e94d 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <string>
 
+#include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "quic/core/crypto/quic_crypto_client_config.h"
@@ -167,6 +168,19 @@
                     alpn_writer.data(), alpn_writer.length()));
     return false;
   }
+
+  // Enable ALPS.
+  if (enable_alps_) {
+    for (const std::string& alpn_string : alpns) {
+      if (SSL_add_application_settings(
+              ssl(), reinterpret_cast<const uint8_t*>(alpn_string.data()),
+              alpn_string.size(), nullptr, /* settings_len = */ 0) != 1) {
+        QUIC_BUG << "Failed to enable ALPS.";
+        return false;
+      }
+    }
+  }
+
   QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
   return true;
 }
@@ -475,6 +489,23 @@
   session()->OnAlpnSelected(received_alpn_string);
   QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
                   << "'";
+
+  // Parse ALPS extension.
+  if (enable_alps_) {
+    const uint8_t* alps_data;
+    size_t alps_length;
+    SSL_get0_peer_application_settings(ssl(), &alps_data, &alps_length);
+    if (alps_length > 0) {
+      auto error = session()->OnAlpsData(alps_data, alps_length);
+      if (error) {
+        CloseConnection(
+            QUIC_HANDSHAKE_FAILED,
+            absl::StrCat("Error processing ALPS data: ", error.value()));
+        return;
+      }
+    }
+  }
+
   state_ = HANDSHAKE_COMPLETE;
   handshaker_delegate()->OnTlsHandshakeComplete();
 }
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h
index e22ade7..71714e2 100644
--- a/quic/core/tls_client_handshaker.h
+++ b/quic/core/tls_client_handshaker.h
@@ -164,6 +164,9 @@
 
   std::unique_ptr<TransportParameters> received_transport_params_ = nullptr;
   std::unique_ptr<ApplicationState> received_application_state_ = nullptr;
+
+  // Latched value of reloadable flag quic_enable_alps_client.
+  const bool enable_alps_ = GetQuicReloadableFlag(quic_enable_alps_client);
 };
 
 }  // namespace quic