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/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 #include "url/gurl.h" | 67 #include "url/gurl.h" |
68 #include "url/url_canon.h" | 68 #include "url/url_canon.h" |
69 | 69 |
70 namespace net { | 70 namespace net { |
71 | 71 |
72 namespace { | 72 namespace { |
73 | 73 |
74 std::unique_ptr<base::Value> NetLogSSLVersionFallbackCallback( | 74 std::unique_ptr<base::Value> NetLogSSLVersionFallbackCallback( |
75 const GURL* url, | 75 const GURL* url, |
76 int net_error, | 76 int net_error, |
77 SSLFailureState ssl_failure_state, | |
78 uint16_t version_before, | 77 uint16_t version_before, |
79 uint16_t version_after, | 78 uint16_t version_after, |
80 NetLogCaptureMode /* capture_mode */) { | 79 NetLogCaptureMode /* capture_mode */) { |
81 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 80 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
82 dict->SetString("host_and_port", GetHostAndPort(*url)); | 81 dict->SetString("host_and_port", GetHostAndPort(*url)); |
83 dict->SetInteger("net_error", net_error); | 82 dict->SetInteger("net_error", net_error); |
84 dict->SetInteger("ssl_failure_state", ssl_failure_state); | |
85 dict->SetInteger("version_before", version_before); | 83 dict->SetInteger("version_before", version_before); |
86 dict->SetInteger("version_after", version_after); | 84 dict->SetInteger("version_after", version_after); |
87 return std::move(dict); | 85 return std::move(dict); |
88 } | 86 } |
89 | 87 |
90 std::unique_ptr<base::Value> NetLogSSLCipherFallbackCallback( | 88 std::unique_ptr<base::Value> NetLogSSLCipherFallbackCallback( |
91 const GURL* url, | 89 const GURL* url, |
92 int net_error, | 90 int net_error, |
93 NetLogCaptureMode /* capture_mode */) { | 91 NetLogCaptureMode /* capture_mode */) { |
94 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 92 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
95 dict->SetString("host_and_port", GetHostAndPort(*url)); | 93 dict->SetString("host_and_port", GetHostAndPort(*url)); |
96 dict->SetInteger("net_error", net_error); | 94 dict->SetInteger("net_error", net_error); |
97 return std::move(dict); | 95 return std::move(dict); |
98 } | 96 } |
99 | 97 |
100 } // namespace | 98 } // namespace |
101 | 99 |
102 //----------------------------------------------------------------------------- | 100 //----------------------------------------------------------------------------- |
103 | 101 |
104 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, | 102 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, |
105 HttpNetworkSession* session) | 103 HttpNetworkSession* session) |
106 : pending_auth_target_(HttpAuth::AUTH_NONE), | 104 : pending_auth_target_(HttpAuth::AUTH_NONE), |
107 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, | 105 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, |
108 base::Unretained(this))), | 106 base::Unretained(this))), |
109 session_(session), | 107 session_(session), |
110 request_(NULL), | 108 request_(NULL), |
111 priority_(priority), | 109 priority_(priority), |
112 headers_valid_(false), | 110 headers_valid_(false), |
113 server_ssl_failure_state_(SSL_FAILURE_NONE), | |
114 fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), | 111 fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), |
115 fallback_failure_state_(SSL_FAILURE_NONE), | |
116 request_headers_(), | 112 request_headers_(), |
117 read_buf_len_(0), | 113 read_buf_len_(0), |
118 total_received_bytes_(0), | 114 total_received_bytes_(0), |
119 total_sent_bytes_(0), | 115 total_sent_bytes_(0), |
120 next_state_(STATE_NONE), | 116 next_state_(STATE_NONE), |
121 establishing_tunnel_(false), | 117 establishing_tunnel_(false), |
122 websocket_handshake_stream_base_create_helper_(NULL), | 118 websocket_handshake_stream_base_create_helper_(NULL), |
123 net_error_details_() { | 119 net_error_details_() { |
124 } | 120 } |
125 | 121 |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 } | 489 } |
494 | 490 |
495 void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady( | 491 void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady( |
496 const SSLConfig& used_ssl_config, | 492 const SSLConfig& used_ssl_config, |
497 const ProxyInfo& used_proxy_info, | 493 const ProxyInfo& used_proxy_info, |
498 WebSocketHandshakeStreamBase* stream) { | 494 WebSocketHandshakeStreamBase* stream) { |
499 OnStreamReady(used_ssl_config, used_proxy_info, stream); | 495 OnStreamReady(used_ssl_config, used_proxy_info, stream); |
500 } | 496 } |
501 | 497 |
502 void HttpNetworkTransaction::OnStreamFailed(int result, | 498 void HttpNetworkTransaction::OnStreamFailed(int result, |
503 const SSLConfig& used_ssl_config, | 499 const SSLConfig& used_ssl_config) { |
504 SSLFailureState ssl_failure_state) { | |
505 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 500 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
506 DCHECK_NE(OK, result); | 501 DCHECK_NE(OK, result); |
507 DCHECK(stream_request_.get()); | 502 DCHECK(stream_request_.get()); |
508 DCHECK(!stream_.get()); | 503 DCHECK(!stream_.get()); |
509 server_ssl_config_ = used_ssl_config; | 504 server_ssl_config_ = used_ssl_config; |
510 server_ssl_failure_state_ = ssl_failure_state; | |
511 | 505 |
512 OnIOComplete(result); | 506 OnIOComplete(result); |
513 } | 507 } |
514 | 508 |
515 void HttpNetworkTransaction::OnCertificateError( | 509 void HttpNetworkTransaction::OnCertificateError( |
516 int result, | 510 int result, |
517 const SSLConfig& used_ssl_config, | 511 const SSLConfig& used_ssl_config, |
518 const SSLInfo& ssl_info) { | 512 const SSLInfo& ssl_info) { |
519 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | 513 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); |
520 DCHECK_NE(OK, result); | 514 DCHECK_NE(OK, result); |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1480 // connection. |fallback_error_code_| is initialised to | 1474 // connection. |fallback_error_code_| is initialised to |
1481 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. | 1475 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. |
1482 error = fallback_error_code_; | 1476 error = fallback_error_code_; |
1483 break; | 1477 break; |
1484 } | 1478 } |
1485 | 1479 |
1486 if (should_fallback) { | 1480 if (should_fallback) { |
1487 net_log_.AddEvent( | 1481 net_log_.AddEvent( |
1488 NetLog::TYPE_SSL_VERSION_FALLBACK, | 1482 NetLog::TYPE_SSL_VERSION_FALLBACK, |
1489 base::Bind(&NetLogSSLVersionFallbackCallback, &request_->url, error, | 1483 base::Bind(&NetLogSSLVersionFallbackCallback, &request_->url, error, |
1490 server_ssl_failure_state_, server_ssl_config_.version_max, | 1484 server_ssl_config_.version_max, version_max)); |
1491 version_max)); | |
1492 fallback_error_code_ = error; | 1485 fallback_error_code_ = error; |
1493 fallback_failure_state_ = server_ssl_failure_state_; | |
1494 server_ssl_config_.version_max = version_max; | 1486 server_ssl_config_.version_max = version_max; |
1495 server_ssl_config_.version_fallback = true; | 1487 server_ssl_config_.version_fallback = true; |
1496 ResetConnectionAndRequestForResend(); | 1488 ResetConnectionAndRequestForResend(); |
1497 error = OK; | 1489 error = OK; |
1498 } | 1490 } |
1499 | 1491 |
1500 return error; | 1492 return error; |
1501 } | 1493 } |
1502 | 1494 |
1503 // This method determines whether it is safe to resend the request after an | 1495 // This method determines whether it is safe to resend the request after an |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1575 referred_token_binding_key_.reset(); | 1567 referred_token_binding_key_.reset(); |
1576 } | 1568 } |
1577 | 1569 |
1578 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { | 1570 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { |
1579 if (stream_) | 1571 if (stream_) |
1580 stream_->PopulateNetErrorDetails(&net_error_details_); | 1572 stream_->PopulateNetErrorDetails(&net_error_details_); |
1581 stream_.reset(); | 1573 stream_.reset(); |
1582 } | 1574 } |
1583 | 1575 |
1584 void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) { | 1576 void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) { |
1585 if (result != OK && result != ERR_SSL_INAPPROPRIATE_FALLBACK) | |
1586 return; | |
1587 | |
1588 const std::string& host = request_->url.host(); | |
1589 bool is_google = base::EndsWith(host, "google.com", | |
1590 base::CompareCase::SENSITIVE) && | |
1591 (host.size() == 10 || host[host.size() - 11] == '.'); | |
1592 if (is_google) { | |
1593 // Some fraction of successful connections use the fallback, but only due to | |
1594 // a spurious network failure. To estimate this fraction, compare handshakes | |
1595 // to Google servers which succeed against those that fail with an | |
1596 // inappropriate_fallback alert. Google servers are known to implement | |
1597 // FALLBACK_SCSV, so a spurious network failure while connecting would | |
1598 // trigger the fallback, successfully connect, but fail with this alert. | |
1599 UMA_HISTOGRAM_BOOLEAN("Net.GoogleConnectionInappropriateFallback", | |
1600 result == ERR_SSL_INAPPROPRIATE_FALLBACK); | |
1601 } | |
1602 | |
1603 if (result != OK) | 1577 if (result != OK) |
1604 return; | 1578 return; |
1605 | 1579 |
1606 // Note: these values are used in histograms, so new values must be appended. | |
1607 enum FallbackVersion { | |
1608 FALLBACK_NONE = 0, // SSL version fallback did not occur. | |
1609 // Obsolete: FALLBACK_SSL3 = 1, | |
1610 FALLBACK_TLS1 = 2, // Fell back to TLS 1.0. | |
1611 FALLBACK_TLS1_1 = 3, // Fell back to TLS 1.1. | |
1612 FALLBACK_MAX, | |
1613 }; | |
1614 | |
1615 FallbackVersion fallback = FALLBACK_NONE; | |
1616 if (server_ssl_config_.version_fallback) { | |
1617 switch (server_ssl_config_.version_max) { | |
1618 case SSL_PROTOCOL_VERSION_TLS1: | |
1619 fallback = FALLBACK_TLS1; | |
1620 break; | |
1621 case SSL_PROTOCOL_VERSION_TLS1_1: | |
1622 fallback = FALLBACK_TLS1_1; | |
1623 break; | |
1624 default: | |
1625 NOTREACHED(); | |
1626 } | |
1627 } | |
1628 UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLVersionFallback2", fallback, | |
1629 FALLBACK_MAX); | |
1630 | |
1631 // Google servers are known to implement TLS 1.2 and FALLBACK_SCSV, so it | |
1632 // should be impossible to successfully connect to them with the fallback. | |
1633 // This helps estimate intolerant locally-configured SSL MITMs. | |
1634 if (is_google) { | |
1635 UMA_HISTOGRAM_ENUMERATION("Net.GoogleConnectionUsedSSLVersionFallback2", | |
1636 fallback, FALLBACK_MAX); | |
1637 } | |
1638 | |
1639 UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2", | 1580 UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2", |
1640 server_ssl_config_.deprecated_cipher_suites_enabled); | 1581 server_ssl_config_.deprecated_cipher_suites_enabled); |
davidben
2016/06/24 00:33:28
Left this around for now. I didn't end up using it
| |
1641 | |
1642 if (server_ssl_config_.version_fallback) { | |
1643 // Record the error code which triggered the fallback and the state the | |
1644 // handshake was in. | |
1645 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLFallbackErrorCode", | |
1646 -fallback_error_code_); | |
1647 UMA_HISTOGRAM_ENUMERATION("Net.SSLFallbackFailureState", | |
1648 fallback_failure_state_, SSL_FAILURE_MAX); | |
1649 } | |
1650 } | 1582 } |
1651 | 1583 |
1652 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | 1584 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { |
1653 return response_.headers.get(); | 1585 return response_.headers.get(); |
1654 } | 1586 } |
1655 | 1587 |
1656 bool HttpNetworkTransaction::ShouldResendRequest() const { | 1588 bool HttpNetworkTransaction::ShouldResendRequest() const { |
1657 bool connection_is_proven = stream_->IsConnectionReused(); | 1589 bool connection_is_proven = stream_->IsConnectionReused(); |
1658 bool has_received_headers = GetResponseHeaders() != NULL; | 1590 bool has_received_headers = GetResponseHeaders() != NULL; |
1659 | 1591 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1797 DCHECK(stream_request_); | 1729 DCHECK(stream_request_); |
1798 | 1730 |
1799 // Since the transaction can restart with auth credentials, it may create a | 1731 // Since the transaction can restart with auth credentials, it may create a |
1800 // stream more than once. Accumulate all of the connection attempts across | 1732 // stream more than once. Accumulate all of the connection attempts across |
1801 // those streams by appending them to the vector: | 1733 // those streams by appending them to the vector: |
1802 for (const auto& attempt : stream_request_->connection_attempts()) | 1734 for (const auto& attempt : stream_request_->connection_attempts()) |
1803 connection_attempts_.push_back(attempt); | 1735 connection_attempts_.push_back(attempt); |
1804 } | 1736 } |
1805 | 1737 |
1806 } // namespace net | 1738 } // namespace net |
OLD | NEW |