Internal change
PiperOrigin-RevId: 429370483
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h
index 3deafcc..0702707 100644
--- a/quic/core/crypto/crypto_protocol.h
+++ b/quic/core/crypto/crypto_protocol.h
@@ -429,6 +429,7 @@
const QuicTag kSRWP = TAG('S', 'R', 'W', 'P'); // Enable retransmittable on
// wire PING (ROWP) on the
// server side.
+const QuicTag kGSR0 = TAG('G', 'S', 'R', '0'); // Selective Resumption
// Client Hints triggers.
const QuicTag kGWCH = TAG('G', 'W', 'C', 'H');
diff --git a/quic/core/crypto/tls_connection.cc b/quic/core/crypto/tls_connection.cc
index 901ae66..e534f7d 100644
--- a/quic/core/crypto/tls_connection.cc
+++ b/quic/core/crypto/tls_connection.cc
@@ -120,6 +120,11 @@
});
}
+void TlsConnection::DisableTicketSupport() {
+ ssl_config_.disable_ticket_support = true;
+ SSL_set_options(ssl(), SSL_OP_NO_TICKET);
+}
+
// static
bssl::UniquePtr<SSL_CTX> TlsConnection::CreateSslCtx() {
CRYPTO_library_init();
diff --git a/quic/core/crypto/tls_connection.h b/quic/core/crypto/tls_connection.h
index a7a869a..5e80185 100644
--- a/quic/core/crypto/tls_connection.h
+++ b/quic/core/crypto/tls_connection.h
@@ -90,6 +90,11 @@
// Configure the SSL such that delegate_->InfoCallback will be called.
void EnableInfoCallback();
+ // Configure the SSL to disable session ticket support. Note that, this
+ // function simply sets the |SSL_OP_NO_TICKET| option on the SSL object, it
+ // does not check whether it is too late to do so.
+ void DisableTicketSupport();
+
// 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/http/quic_server_session_base.h b/quic/core/http/quic_server_session_base.h
index 5903de6..e6afc19 100644
--- a/quic/core/http/quic_server_session_base.h
+++ b/quic/core/http/quic_server_session_base.h
@@ -68,6 +68,8 @@
serving_region_ = serving_region;
}
+ const std::string& serving_region() const { return serving_region_; }
+
QuicSSLConfig GetSSLConfig() const override;
protected:
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc
index 55b7bf1..1f8b026 100644
--- a/quic/core/quic_crypto_server_stream.cc
+++ b/quic/core/quic_crypto_server_stream.cc
@@ -309,6 +309,11 @@
++num_server_config_update_messages_sent_;
}
+bool QuicCryptoServerStream::DisableResumption() {
+ QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+ return false;
+}
+
bool QuicCryptoServerStream::IsZeroRtt() const {
return num_handshake_messages_ == 1 &&
num_handshake_messages_with_server_nonces_ == 0;
@@ -332,6 +337,11 @@
return zero_rtt_attempted_;
}
+bool QuicCryptoServerStream::EarlyDataAttempted() const {
+ QUICHE_DCHECK(false) << "Not supported for QUIC crypto.";
+ return zero_rtt_attempted_;
+}
+
void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
CachedNetworkParameters cached_network_params) {
previous_cached_network_params_.reset(
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
index aca9e9a..05f68e6 100644
--- a/quic/core/quic_crypto_server_stream.h
+++ b/quic/core/quic_crypto_server_stream.h
@@ -34,9 +34,11 @@
bool GetBase64SHA256ClientChannelID(std::string* output) const override;
void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) override;
+ bool DisableResumption() override;
bool IsZeroRtt() const override;
bool IsResumption() const override;
bool ResumptionAttempted() const override;
+ bool EarlyDataAttempted() const override;
int NumServerConfigUpdateMessagesSent() const override;
const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
void SetPreviousCachedNetworkParams(
diff --git a/quic/core/quic_crypto_server_stream_base.h b/quic/core/quic_crypto_server_stream_base.h
index 0a2a63e..dcefdfb 100644
--- a/quic/core/quic_crypto_server_stream_base.h
+++ b/quic/core/quic_crypto_server_stream_base.h
@@ -62,6 +62,11 @@
virtual void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) = 0;
+ // Disables TLS resumption, should be called as early as possible.
+ // Return true if resumption is disabled.
+ // Return false if nothing happened, typically it means it is called too late.
+ virtual bool DisableResumption() = 0;
+
// Returns true if the connection was a successful 0-RTT resumption.
virtual bool IsZeroRtt() const = 0;
@@ -73,6 +78,10 @@
// the resumption actually occurred.
virtual bool ResumptionAttempted() const = 0;
+ // Returns true if the client attempted to use early data, as indicated by the
+ // "early_data" TLS extension. TLS only.
+ virtual bool EarlyDataAttempted() const = 0;
+
// NOTE: Indicating that the Expect-CT header should be sent here presents
// a layering violation to some extent. The Expect-CT header only applies to
// HTTP connections, while this class can be used for non-HTTP applications.
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index a16e729..dc4b39a 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -278,6 +278,14 @@
// SCUP messages aren't supported when using the TLS handshake.
}
+bool TlsServerHandshaker::DisableResumption() {
+ if (!can_disable_resumption_ || !session()->connection()->connected()) {
+ return false;
+ }
+ tls_connection_.DisableTicketSupport();
+ return true;
+}
+
bool TlsServerHandshaker::IsZeroRtt() const {
return SSL_early_data_accepted(ssl());
}
@@ -290,6 +298,14 @@
return ticket_received_;
}
+bool TlsServerHandshaker::EarlyDataAttempted() const {
+ QUIC_BUG_IF(quic_tls_early_data_attempted_too_early,
+ !select_cert_status_.has_value())
+ << "EarlyDataAttempted must be called after EarlySelectCertCallback is "
+ "started";
+ return early_data_attempted_;
+}
+
int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
// SCUP messages aren't supported when using the TLS handshake.
return 0;
@@ -881,6 +897,10 @@
ticket_received_ = SSL_early_callback_ctx_extension_get(
client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
&unused_extension_len);
+
+ early_data_attempted_ = SSL_early_callback_ctx_extension_get(
+ client_hello, TLSEXT_TYPE_early_data, &unused_extension_bytes,
+ &unused_extension_len);
}
// This callback is called very early by Boring SSL, most of the SSL_get_foo
@@ -950,6 +970,7 @@
return ssl_select_cert_error;
}
+ can_disable_resumption_ = false;
const QuicAsyncStatus status = proof_source_handle_->SelectCertificate(
session()->connection()->self_address().Normalized(),
session()->connection()->peer_address().Normalized(),
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index d2f37b0..c2ea44b 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -45,9 +45,12 @@
bool GetBase64SHA256ClientChannelID(std::string* output) const override;
void SendServerConfigUpdate(
const CachedNetworkParameters* cached_network_params) override;
+ bool DisableResumption() override;
bool IsZeroRtt() const override;
bool IsResumption() const override;
bool ResumptionAttempted() const override;
+ // Must be called after EarlySelectCertCallback is started.
+ bool EarlyDataAttempted() const override;
int NumServerConfigUpdateMessagesSent() const override;
const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
void SetPreviousCachedNetworkParams(
@@ -344,6 +347,9 @@
// indicates that the client attempted a resumption.
bool ticket_received_ = false;
+ // True if the "early_data" extension is in the client hello.
+ bool early_data_attempted_ = false;
+
// Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
bool ignore_ticket_open_ = false;
@@ -367,6 +373,7 @@
HandshakeState state_ = HANDSHAKE_START;
bool encryption_established_ = false;
bool valid_alpn_received_ = false;
+ bool can_disable_resumption_ = true;
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
crypto_negotiated_params_;
TlsServerConnection tls_connection_;