OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/ssl_client_socket_pool.h" | 5 #include "net/socket/ssl_client_socket_pool.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 client_socket_factory_(client_socket_factory), | 123 client_socket_factory_(client_socket_factory), |
124 context_(context.cert_verifier, | 124 context_(context.cert_verifier, |
125 context.channel_id_service, | 125 context.channel_id_service, |
126 context.transport_security_state, | 126 context.transport_security_state, |
127 context.cert_transparency_verifier, | 127 context.cert_transparency_verifier, |
128 context.ct_policy_enforcer, | 128 context.ct_policy_enforcer, |
129 (params->privacy_mode() == PRIVACY_MODE_ENABLED | 129 (params->privacy_mode() == PRIVACY_MODE_ENABLED |
130 ? "pm/" + context.ssl_session_cache_shard | 130 ? "pm/" + context.ssl_session_cache_shard |
131 : context.ssl_session_cache_shard)), | 131 : context.ssl_session_cache_shard)), |
132 callback_( | 132 callback_( |
133 base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))) {} | 133 base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))), |
134 version_interference_probe_(false), | |
135 version_interference_probe_error_(OK) {} | |
134 | 136 |
135 SSLConnectJob::~SSLConnectJob() { | 137 SSLConnectJob::~SSLConnectJob() { |
136 } | 138 } |
137 | 139 |
138 LoadState SSLConnectJob::GetLoadState() const { | 140 LoadState SSLConnectJob::GetLoadState() const { |
139 switch (next_state_) { | 141 switch (next_state_) { |
140 case STATE_TUNNEL_CONNECT_COMPLETE: | 142 case STATE_TUNNEL_CONNECT_COMPLETE: |
141 if (transport_socket_handle_->socket()) | 143 if (transport_socket_handle_->socket()) |
142 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; | 144 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; |
143 // else, fall through. | 145 // else, fall through. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE; | 231 next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE; |
230 transport_socket_handle_.reset(new ClientSocketHandle()); | 232 transport_socket_handle_.reset(new ClientSocketHandle()); |
231 scoped_refptr<TransportSocketParams> direct_params = | 233 scoped_refptr<TransportSocketParams> direct_params = |
232 params_->GetDirectConnectionParams(); | 234 params_->GetDirectConnectionParams(); |
233 return transport_socket_handle_->Init(group_name(), direct_params, priority(), | 235 return transport_socket_handle_->Init(group_name(), direct_params, priority(), |
234 respect_limits(), callback_, | 236 respect_limits(), callback_, |
235 transport_pool_, net_log()); | 237 transport_pool_, net_log()); |
236 } | 238 } |
237 | 239 |
238 int SSLConnectJob::DoTransportConnectComplete(int result) { | 240 int SSLConnectJob::DoTransportConnectComplete(int result) { |
239 connection_attempts_ = transport_socket_handle_->connection_attempts(); | 241 connection_attempts_.insert( |
242 connection_attempts_.end(), | |
243 transport_socket_handle_->connection_attempts().begin(), | |
244 transport_socket_handle_->connection_attempts().end()); | |
240 if (result == OK) { | 245 if (result == OK) { |
241 next_state_ = STATE_SSL_CONNECT; | 246 next_state_ = STATE_SSL_CONNECT; |
242 transport_socket_handle_->socket()->GetPeerAddress(&server_address_); | 247 transport_socket_handle_->socket()->GetPeerAddress(&server_address_); |
243 } | 248 } |
244 | 249 |
245 return result; | 250 return result; |
246 } | 251 } |
247 | 252 |
248 int SSLConnectJob::DoSOCKSConnect() { | 253 int SSLConnectJob::DoSOCKSConnect() { |
249 DCHECK(socks_pool_); | 254 DCHECK(socks_pool_); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 // Overwriting |connect_start| serves two purposes - it adjusts timing so | 319 // Overwriting |connect_start| serves two purposes - it adjusts timing so |
315 // |connect_start| doesn't include dns times, and it adjusts the time so | 320 // |connect_start| doesn't include dns times, and it adjusts the time so |
316 // as not to include time spent waiting for an idle socket. | 321 // as not to include time spent waiting for an idle socket. |
317 connect_timing_.connect_start = socket_connect_timing.connect_start; | 322 connect_timing_.connect_start = socket_connect_timing.connect_start; |
318 connect_timing_.dns_start = socket_connect_timing.dns_start; | 323 connect_timing_.dns_start = socket_connect_timing.dns_start; |
319 connect_timing_.dns_end = socket_connect_timing.dns_end; | 324 connect_timing_.dns_end = socket_connect_timing.dns_end; |
320 } | 325 } |
321 | 326 |
322 connect_timing_.ssl_start = base::TimeTicks::Now(); | 327 connect_timing_.ssl_start = base::TimeTicks::Now(); |
323 | 328 |
329 SSLConfig ssl_config = params_->ssl_config(); | |
330 if (version_interference_probe_) { | |
331 DCHECK_EQ(SSL_PROTOCOL_VERSION_TLS1_3, ssl_config.version_max); | |
332 ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; | |
333 ssl_config.version_interference_probe = true; | |
mmenke
2017/04/10 19:08:46
It seems a little bit silly that we're exposing th
davidben
2017/04/10 19:52:25
Very little magic, but some. I'd prefer the SSL se
mmenke
2017/04/10 19:55:05
That's unfortunate, but I'll defer to you on that.
| |
334 } | |
324 ssl_socket_ = client_socket_factory_->CreateSSLClientSocket( | 335 ssl_socket_ = client_socket_factory_->CreateSSLClientSocket( |
325 std::move(transport_socket_handle_), params_->host_and_port(), | 336 std::move(transport_socket_handle_), params_->host_and_port(), ssl_config, |
326 params_->ssl_config(), context_); | 337 context_); |
327 return ssl_socket_->Connect(callback_); | 338 return ssl_socket_->Connect(callback_); |
328 } | 339 } |
329 | 340 |
330 int SSLConnectJob::DoSSLConnectComplete(int result) { | 341 int SSLConnectJob::DoSSLConnectComplete(int result) { |
mmenke
2017/04/10 19:08:46
// Version interference probes should not result i
davidben
2017/04/10 19:52:25
Done.
| |
331 // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. | 342 // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. |
332 tracked_objects::ScopedTracker tracking_profile( | 343 tracked_objects::ScopedTracker tracking_profile( |
333 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 344 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
334 "462784 SSLConnectJob::DoSSLConnectComplete")); | 345 "462784 SSLConnectJob::DoSSLConnectComplete")); |
335 | 346 |
336 connect_timing_.ssl_end = base::TimeTicks::Now(); | 347 connect_timing_.ssl_end = base::TimeTicks::Now(); |
337 | 348 |
338 if (result != OK && !server_address_.address().empty()) { | 349 if (result != OK && !server_address_.address().empty()) { |
339 connection_attempts_.push_back(ConnectionAttempt(server_address_, result)); | 350 connection_attempts_.push_back(ConnectionAttempt(server_address_, result)); |
340 server_address_ = IPEndPoint(); | 351 server_address_ = IPEndPoint(); |
341 } | 352 } |
342 | 353 |
343 // If we want SPDY over ALPN, make sure it succeeded. | 354 // If we want SPDY over ALPN, make sure it succeeded. |
344 if (params_->expect_spdy() && | 355 if (params_->expect_spdy() && |
345 ssl_socket_->GetNegotiatedProtocol() != kProtoHTTP2) { | 356 ssl_socket_->GetNegotiatedProtocol() != kProtoHTTP2) { |
346 return ERR_ALPN_NEGOTIATION_FAILED; | 357 return ERR_ALPN_NEGOTIATION_FAILED; |
347 } | 358 } |
348 | 359 |
360 // Perform a TLS 1.3 version interference probe on various connection | |
361 // errors. The retry will never produce a successful connection but may map | |
362 // errors to ERR_SSL_VERSION_INTERFERENCE, which signals a probable | |
363 // version-interfering middlebox. | |
364 if (params_->ssl_config().version_max == SSL_PROTOCOL_VERSION_TLS1_3 && | |
365 !params_->ssl_config().deprecated_cipher_suites_enabled && | |
366 !version_interference_probe_) { | |
367 if (result == ERR_CONNECTION_CLOSED || result == ERR_SSL_PROTOCOL_ERROR || | |
368 result == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || | |
369 result == ERR_CONNECTION_RESET || | |
370 result == ERR_SSL_BAD_RECORD_MAC_ALERT) { | |
371 // Report the error code for each time a version interference probe is | |
372 // triggered. | |
373 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceProbeTrigger", | |
374 std::abs(result)); | |
mmenke
2017/04/10 19:08:46
I think std::abs is declared in <math>?
davidben
2017/04/10 19:52:25
cstdlib, apparently.
| |
375 net_log().AddEventWithNetErrorCode( | |
376 NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result); | |
377 | |
378 ResetStateForRetry(); | |
379 version_interference_probe_ = true; | |
380 version_interference_probe_error_ = result; | |
mmenke
2017/04/10 19:08:46
This was the error that triggered the probe, not t
davidben
2017/04/10 19:52:25
What about version_interference_error_ just so it'
mmenke
2017/04/10 19:55:06
SGTM
| |
381 next_state_ = GetInitialState(params_->GetConnectionType()); | |
382 return OK; | |
383 } | |
384 } | |
385 | |
349 const std::string& host = params_->host_and_port().host(); | 386 const std::string& host = params_->host_and_port().host(); |
350 bool is_google = | 387 bool is_google = |
351 host == "google.com" || | 388 host == "google.com" || |
352 (host.size() > 11 && host.rfind(".google.com") == host.size() - 11); | 389 (host.size() > 11 && host.rfind(".google.com") == host.size() - 11); |
353 | 390 |
354 // These are hosts that we intend to use in the initial TLS 1.3 deployment. | 391 // These are hosts that we intend to use in the initial TLS 1.3 deployment. |
355 // TLS connections to them, whether or not this browser is in the experiment | 392 // TLS connections to them, whether or not this browser is in the experiment |
356 // group, form the basis of our comparisons. | 393 // group, form the basis of our comparisons. |
357 bool tls13_supported = | 394 bool tls13_supported = |
358 (host == "drive.google.com" || host == "mail.google.com"); | 395 (host == "drive.google.com" || host == "mail.google.com"); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
443 if (is_google) { | 480 if (is_google) { |
444 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_Google", | 481 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_Google", |
445 std::abs(result)); | 482 std::abs(result)); |
446 } | 483 } |
447 | 484 |
448 if (tls13_supported) { | 485 if (tls13_supported) { |
449 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_TLS13Experiment", | 486 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_Connection_Error_TLS13Experiment", |
450 std::abs(result)); | 487 std::abs(result)); |
451 } | 488 } |
452 | 489 |
490 if (result == ERR_SSL_VERSION_INTERFERENCE) { | |
491 // Record the error code version interference was detected at. | |
492 DCHECK(version_interference_probe_); | |
493 DCHECK_NE(OK, version_interference_probe_error_); | |
494 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLVersionInterferenceError", | |
495 std::abs(version_interference_probe_error_)); | |
496 } | |
497 | |
453 if (result == OK || IsCertificateError(result)) { | 498 if (result == OK || IsCertificateError(result)) { |
454 SetSocket(std::move(ssl_socket_)); | 499 SetSocket(std::move(ssl_socket_)); |
455 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 500 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
456 error_response_info_.cert_request_info = new SSLCertRequestInfo; | 501 error_response_info_.cert_request_info = new SSLCertRequestInfo; |
457 ssl_socket_->GetSSLCertRequestInfo( | 502 ssl_socket_->GetSSLCertRequestInfo( |
458 error_response_info_.cert_request_info.get()); | 503 error_response_info_.cert_request_info.get()); |
459 } | 504 } |
460 | 505 |
461 return result; | 506 return result; |
462 } | 507 } |
(...skipping 10 matching lines...) Expand all Loading... | |
473 } | 518 } |
474 NOTREACHED(); | 519 NOTREACHED(); |
475 return STATE_NONE; | 520 return STATE_NONE; |
476 } | 521 } |
477 | 522 |
478 int SSLConnectJob::ConnectInternal() { | 523 int SSLConnectJob::ConnectInternal() { |
479 next_state_ = GetInitialState(params_->GetConnectionType()); | 524 next_state_ = GetInitialState(params_->GetConnectionType()); |
480 return DoLoop(OK); | 525 return DoLoop(OK); |
481 } | 526 } |
482 | 527 |
528 void SSLConnectJob::ResetStateForRetry() { | |
529 transport_socket_handle_.reset(); | |
530 ssl_socket_.reset(); | |
531 error_response_info_ = HttpResponseInfo(); | |
532 server_address_ = IPEndPoint(); | |
533 } | |
534 | |
483 SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory( | 535 SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory( |
484 TransportClientSocketPool* transport_pool, | 536 TransportClientSocketPool* transport_pool, |
485 SOCKSClientSocketPool* socks_pool, | 537 SOCKSClientSocketPool* socks_pool, |
486 HttpProxyClientSocketPool* http_proxy_pool, | 538 HttpProxyClientSocketPool* http_proxy_pool, |
487 ClientSocketFactory* client_socket_factory, | 539 ClientSocketFactory* client_socket_factory, |
488 const SSLClientSocketContext& context, | 540 const SSLClientSocketContext& context, |
489 NetLog* net_log) | 541 NetLog* net_log) |
490 : transport_pool_(transport_pool), | 542 : transport_pool_(transport_pool), |
491 socks_pool_(socks_pool), | 543 socks_pool_(socks_pool), |
492 http_proxy_pool_(http_proxy_pool), | 544 http_proxy_pool_(http_proxy_pool), |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
703 if (base_.CloseOneIdleSocket()) | 755 if (base_.CloseOneIdleSocket()) |
704 return true; | 756 return true; |
705 return base_.CloseOneIdleConnectionInHigherLayeredPool(); | 757 return base_.CloseOneIdleConnectionInHigherLayeredPool(); |
706 } | 758 } |
707 | 759 |
708 void SSLClientSocketPool::OnSSLConfigChanged() { | 760 void SSLClientSocketPool::OnSSLConfigChanged() { |
709 FlushWithError(ERR_NETWORK_CHANGED); | 761 FlushWithError(ERR_NETWORK_CHANGED); |
710 } | 762 } |
711 | 763 |
712 } // namespace net | 764 } // namespace net |
OLD | NEW |