Enable ALPS in QUIC TLS server handshaker and send ACCEPT_CH data if any.

Enable ALPS exention in server even if there is no ACCEPT_CH frame to send,
to allow the client to send ALPS data if a use case arises in the future.

Protected by FLAGS_quic_reloadable_flag_quic_enable_alps_server.

PiperOrigin-RevId: 353353552
Change-Id: I1f4e173e676a63e7fcc5150bcda36302a607ddbd
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 15f6d29..aa3b43d 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_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)
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_token_based_address_validation, true)
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index ebaa0d8..48710c1 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -13,6 +13,8 @@
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "quic/core/crypto/quic_crypto_server_config.h"
 #include "quic/core/crypto/transport_parameters.h"
+#include "quic/core/http/http_encoder.h"
+#include "quic/core/http/http_frames.h"
 #include "quic/core/quic_time.h"
 #include "quic/core/quic_types.h"
 #include "quic/platform/api/quic_flag_utils.h"
@@ -958,6 +960,30 @@
     return SSL_TLSEXT_ERR_NOACK;
   }
 
+  // Enable ALPS for the selected ALPN protocol.
+  if (GetQuicReloadableFlag(quic_enable_alps_server)) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_enable_alps_server);
+
+    const uint8_t* alps_data = nullptr;
+    size_t alps_length = 0;
+    std::unique_ptr<char[]> buffer;
+
+    const std::string& origin = crypto_negotiated_params_->sni;
+    std::string accept_ch_value = GetAcceptChValueForOrigin(origin);
+    if (!accept_ch_value.empty()) {
+      AcceptChFrame frame{{{origin, accept_ch_value}}};
+      alps_length = HttpEncoder::SerializeAcceptChFrame(frame, &buffer);
+      alps_data = reinterpret_cast<const uint8_t*>(buffer.get());
+    }
+
+    if (SSL_add_application_settings(
+            ssl(), reinterpret_cast<const uint8_t*>(selected_alpn->data()),
+            selected_alpn->size(), alps_data, alps_length) != 1) {
+      QUIC_DLOG(ERROR) << "Failed to enable ALPS";
+      return SSL_TLSEXT_ERR_NOACK;
+    }
+  }
+
   session()->OnAlpnSelected(*selected_alpn);
   valid_alpn_received_ = true;
   *out_len = selected_alpn->size();