Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Unified Diff: net/socket/ssl_client_socket_pool.cc

Issue 2800853008: Add a dedicated error code for TLS 1.3 interference. (Closed)
Patch Set: mpearson comment Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/socket/ssl_client_socket_pool.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/socket/ssl_client_socket_pool.cc
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc
index b335e46b1f95330864f82f380a9f69f5e23153ee..a557e5be2e850cf3edf8cab9f524229f5ff0f7b0 100644
--- a/net/socket/ssl_client_socket_pool.cc
+++ b/net/socket/ssl_client_socket_pool.cc
@@ -4,6 +4,7 @@
#include "net/socket/ssl_client_socket_pool.h"
+#include <cstdlib>
#include <utility>
#include "base/bind.h"
@@ -130,7 +131,9 @@ SSLConnectJob::SSLConnectJob(const std::string& group_name,
? "pm/" + context.ssl_session_cache_shard
: context.ssl_session_cache_shard)),
callback_(
- base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))) {}
+ base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))),
+ version_interference_probe_(false),
+ version_interference_error_(OK) {}
SSLConnectJob::~SSLConnectJob() {
}
@@ -236,7 +239,10 @@ int SSLConnectJob::DoTransportConnect() {
}
int SSLConnectJob::DoTransportConnectComplete(int result) {
- connection_attempts_ = transport_socket_handle_->connection_attempts();
+ connection_attempts_.insert(
+ connection_attempts_.end(),
+ transport_socket_handle_->connection_attempts().begin(),
+ transport_socket_handle_->connection_attempts().end());
if (result == OK) {
next_state_ = STATE_SSL_CONNECT;
transport_socket_handle_->socket()->GetPeerAddress(&server_address_);
@@ -321,13 +327,22 @@ int SSLConnectJob::DoSSLConnect() {
connect_timing_.ssl_start = base::TimeTicks::Now();
+ SSLConfig ssl_config = params_->ssl_config();
+ if (version_interference_probe_) {
+ DCHECK_EQ(SSL_PROTOCOL_VERSION_TLS1_3, ssl_config.version_max);
+ ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ ssl_config.version_interference_probe = true;
+ }
ssl_socket_ = client_socket_factory_->CreateSSLClientSocket(
- std::move(transport_socket_handle_), params_->host_and_port(),
- params_->ssl_config(), context_);
+ std::move(transport_socket_handle_), params_->host_and_port(), ssl_config,
+ context_);
return ssl_socket_->Connect(callback_);
}
int SSLConnectJob::DoSSLConnectComplete(int result) {
+ // Version interference probes should not result in success.
+ DCHECK(!version_interference_probe_ || result != OK);
+
// TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
@@ -346,6 +361,32 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
return ERR_ALPN_NEGOTIATION_FAILED;
}
+ // Perform a TLS 1.3 version interference probe on various connection
+ // errors. The retry will never produce a successful connection but may map
+ // errors to ERR_SSL_VERSION_INTERFERENCE, which signals a probable
+ // version-interfering middlebox.
+ if (params_->ssl_config().version_max == SSL_PROTOCOL_VERSION_TLS1_3 &&
+ !params_->ssl_config().deprecated_cipher_suites_enabled &&
+ !version_interference_probe_) {
+ if (result == ERR_CONNECTION_CLOSED || result == ERR_SSL_PROTOCOL_ERROR ||
+ result == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
+ result == ERR_CONNECTION_RESET ||
+ result == ERR_SSL_BAD_RECORD_MAC_ALERT) {
+ // Report the error code for each time a version interference probe is
+ // triggered.
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceProbeTrigger",
+ std::abs(result));
+ net_log().AddEventWithNetErrorCode(
+ NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result);
+
+ ResetStateForRetry();
+ version_interference_probe_ = true;
+ version_interference_error_ = result;
+ next_state_ = GetInitialState(params_->GetConnectionType());
+ return OK;
+ }
+ }
+
const std::string& host = params_->host_and_port().host();
bool is_google =
host == "google.com" ||
@@ -450,6 +491,14 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
std::abs(result));
}
+ if (result == ERR_SSL_VERSION_INTERFERENCE) {
+ // Record the error code version interference was detected at.
+ DCHECK(version_interference_probe_);
+ DCHECK_NE(OK, version_interference_error_);
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceError",
+ std::abs(version_interference_error_));
+ }
+
if (result == OK || IsCertificateError(result)) {
SetSocket(std::move(ssl_socket_));
} else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
@@ -480,6 +529,13 @@ int SSLConnectJob::ConnectInternal() {
return DoLoop(OK);
}
+void SSLConnectJob::ResetStateForRetry() {
+ transport_socket_handle_.reset();
+ ssl_socket_.reset();
+ error_response_info_ = HttpResponseInfo();
+ server_address_ = IPEndPoint();
+}
+
SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
TransportClientSocketPool* transport_pool,
SOCKSClientSocketPool* socks_pool,
« no previous file with comments | « net/socket/ssl_client_socket_pool.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698