| 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/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #endif | 52 #endif |
| 53 | 53 |
| 54 #if defined(USE_OPENSSL) | 54 #if defined(USE_OPENSSL) |
| 55 #include <openssl/aead.h> | 55 #include <openssl/aead.h> |
| 56 #include "crypto/openssl_util.h" | 56 #include "crypto/openssl_util.h" |
| 57 #else | 57 #else |
| 58 #include "base/cpu.h" | 58 #include "base/cpu.h" |
| 59 #endif | 59 #endif |
| 60 | 60 |
| 61 using std::min; | 61 using std::min; |
| 62 using NetworkHandle = net::NetworkChangeNotifier::NetworkHandle; |
| 62 | 63 |
| 63 namespace net { | 64 namespace net { |
| 64 | 65 |
| 65 namespace { | 66 namespace { |
| 66 | 67 |
| 67 enum CreateSessionFailure { | 68 enum CreateSessionFailure { |
| 68 CREATION_ERROR_CONNECTING_SOCKET, | 69 CREATION_ERROR_CONNECTING_SOCKET, |
| 69 CREATION_ERROR_SETTING_RECEIVE_BUFFER, | 70 CREATION_ERROR_SETTING_RECEIVE_BUFFER, |
| 70 CREATION_ERROR_SETTING_SEND_BUFFER, | 71 CREATION_ERROR_SETTING_SEND_BUFFER, |
| 71 CREATION_ERROR_MAX | 72 CREATION_ERROR_MAX |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 int max_disabled_reasons, | 585 int max_disabled_reasons, |
| 585 int threshold_public_resets_post_handshake, | 586 int threshold_public_resets_post_handshake, |
| 586 int threshold_timeouts_with_open_streams, | 587 int threshold_timeouts_with_open_streams, |
| 587 int socket_receive_buffer_size, | 588 int socket_receive_buffer_size, |
| 588 bool delay_tcp_race, | 589 bool delay_tcp_race, |
| 589 int max_server_configs_stored_in_properties, | 590 int max_server_configs_stored_in_properties, |
| 590 bool close_sessions_on_ip_change, | 591 bool close_sessions_on_ip_change, |
| 591 bool disable_quic_on_timeout_with_open_streams, | 592 bool disable_quic_on_timeout_with_open_streams, |
| 592 int idle_connection_timeout_seconds, | 593 int idle_connection_timeout_seconds, |
| 593 bool migrate_sessions_on_network_change, | 594 bool migrate_sessions_on_network_change, |
| 595 bool migrate_sessions_early, |
| 594 const QuicTagVector& connection_options) | 596 const QuicTagVector& connection_options) |
| 595 : require_confirmation_(true), | 597 : require_confirmation_(true), |
| 596 host_resolver_(host_resolver), | 598 host_resolver_(host_resolver), |
| 597 client_socket_factory_(client_socket_factory), | 599 client_socket_factory_(client_socket_factory), |
| 598 http_server_properties_(http_server_properties), | 600 http_server_properties_(http_server_properties), |
| 599 transport_security_state_(transport_security_state), | 601 transport_security_state_(transport_security_state), |
| 600 cert_transparency_verifier_(cert_transparency_verifier), | 602 cert_transparency_verifier_(cert_transparency_verifier), |
| 601 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), | 603 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), |
| 602 random_generator_(random_generator), | 604 random_generator_(random_generator), |
| 603 clock_(clock), | 605 clock_(clock), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 633 threshold_public_resets_post_handshake), | 635 threshold_public_resets_post_handshake), |
| 634 socket_receive_buffer_size_(socket_receive_buffer_size), | 636 socket_receive_buffer_size_(socket_receive_buffer_size), |
| 635 delay_tcp_race_(delay_tcp_race), | 637 delay_tcp_race_(delay_tcp_race), |
| 636 yield_after_packets_(kQuicYieldAfterPacketsRead), | 638 yield_after_packets_(kQuicYieldAfterPacketsRead), |
| 637 yield_after_duration_(QuicTime::Delta::FromMilliseconds( | 639 yield_after_duration_(QuicTime::Delta::FromMilliseconds( |
| 638 kQuicYieldAfterDurationMilliseconds)), | 640 kQuicYieldAfterDurationMilliseconds)), |
| 639 close_sessions_on_ip_change_(close_sessions_on_ip_change), | 641 close_sessions_on_ip_change_(close_sessions_on_ip_change), |
| 640 migrate_sessions_on_network_change_( | 642 migrate_sessions_on_network_change_( |
| 641 migrate_sessions_on_network_change && | 643 migrate_sessions_on_network_change && |
| 642 NetworkChangeNotifier::AreNetworkHandlesSupported()), | 644 NetworkChangeNotifier::AreNetworkHandlesSupported()), |
| 645 migrate_sessions_early_(migrate_sessions_early && |
| 646 migrate_sessions_on_network_change_), |
| 643 port_seed_(random_generator_->RandUint64()), | 647 port_seed_(random_generator_->RandUint64()), |
| 644 check_persisted_supports_quic_(true), | 648 check_persisted_supports_quic_(true), |
| 645 has_initialized_data_(false), | 649 has_initialized_data_(false), |
| 646 task_runner_(nullptr), | 650 task_runner_(nullptr), |
| 647 weak_factory_(this) { | 651 weak_factory_(this) { |
| 648 if (disable_quic_on_timeout_with_open_streams) | 652 if (disable_quic_on_timeout_with_open_streams) |
| 649 threshold_timeouts_with_open_streams_ = 1; | 653 threshold_timeouts_with_open_streams_ = 1; |
| 650 DCHECK(transport_security_state_); | 654 DCHECK(transport_security_state_); |
| 651 DCHECK(http_server_properties_); | 655 DCHECK(http_server_properties_); |
| 652 crypto_config_.set_user_agent_id(user_agent_id); | 656 crypto_config_.set_user_agent_id(user_agent_id); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 673 if (!IsEcdsaSupported()) | 677 if (!IsEcdsaSupported()) |
| 674 crypto_config_.DisableEcdsa(); | 678 crypto_config_.DisableEcdsa(); |
| 675 // When disk cache is used to store the server configs, HttpCache code calls | 679 // When disk cache is used to store the server configs, HttpCache code calls |
| 676 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't | 680 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't |
| 677 // created. | 681 // created. |
| 678 if (max_server_configs_stored_in_properties > 0) { | 682 if (max_server_configs_stored_in_properties > 0) { |
| 679 quic_server_info_factory_.reset( | 683 quic_server_info_factory_.reset( |
| 680 new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); | 684 new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); |
| 681 } | 685 } |
| 682 | 686 |
| 683 DCHECK( | 687 // migrate_sessions_early_ should only be set to true if |
| 684 !(close_sessions_on_ip_change_ && migrate_sessions_on_network_change_)); | 688 // migrate_sessions_on_network_change_ is set to true. |
| 689 DCHECK(migrate_sessions_on_network_change_ || !migrate_sessions_early_); |
| 690 // close_sessions_on_ip_change_ and migrate_sessions_on_network_change_ should |
| 691 // never be simultaneously set to true. |
| 692 DCHECK(!close_sessions_on_ip_change_ || !migrate_sessions_on_network_change_); |
| 685 if (migrate_sessions_on_network_change_) { | 693 if (migrate_sessions_on_network_change_) { |
| 686 NetworkChangeNotifier::AddNetworkObserver(this); | 694 NetworkChangeNotifier::AddNetworkObserver(this); |
| 687 } else if (close_sessions_on_ip_change_) { | 695 } else if (close_sessions_on_ip_change_) { |
| 688 NetworkChangeNotifier::AddIPAddressObserver(this); | 696 NetworkChangeNotifier::AddIPAddressObserver(this); |
| 689 } | 697 } |
| 690 } | 698 } |
| 691 | 699 |
| 692 QuicStreamFactory::~QuicStreamFactory() { | 700 QuicStreamFactory::~QuicStreamFactory() { |
| 693 CloseAllSessions(ERR_ABORTED, QUIC_CONNECTION_CANCELLED); | 701 CloseAllSessions(ERR_ABORTED, QUIC_CONNECTION_CANCELLED); |
| 694 while (!all_sessions_.empty()) { | 702 while (!all_sessions_.empty()) { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 | 1189 |
| 1182 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { | 1190 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { |
| 1183 crypto_config_.ClearCachedStates(); | 1191 crypto_config_.ClearCachedStates(); |
| 1184 } | 1192 } |
| 1185 | 1193 |
| 1186 void QuicStreamFactory::OnIPAddressChanged() { | 1194 void QuicStreamFactory::OnIPAddressChanged() { |
| 1187 CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED); | 1195 CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED); |
| 1188 set_require_confirmation(true); | 1196 set_require_confirmation(true); |
| 1189 } | 1197 } |
| 1190 | 1198 |
| 1191 void QuicStreamFactory::OnNetworkConnected( | 1199 void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) {} |
| 1192 NetworkChangeNotifier::NetworkHandle network) {} | |
| 1193 | 1200 |
| 1194 void QuicStreamFactory::OnNetworkMadeDefault( | 1201 void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) {} |
| 1195 NetworkChangeNotifier::NetworkHandle network) {} | |
| 1196 | 1202 |
| 1197 void QuicStreamFactory::OnNetworkDisconnected( | 1203 void QuicStreamFactory::OnNetworkDisconnected(NetworkHandle network) { |
| 1198 NetworkChangeNotifier::NetworkHandle network) { | |
| 1199 MaybeMigrateOrCloseSessions(network, /*force_close=*/true); | 1204 MaybeMigrateOrCloseSessions(network, /*force_close=*/true); |
| 1200 set_require_confirmation(true); | 1205 set_require_confirmation(true); |
| 1201 } | 1206 } |
| 1202 | 1207 |
| 1203 // This method is expected to only be called when migrating from Cellular to | 1208 // This method is expected to only be called when migrating from Cellular to |
| 1204 // WiFi on Android. | 1209 // WiFi on Android. |
| 1205 void QuicStreamFactory::OnNetworkSoonToDisconnect( | 1210 void QuicStreamFactory::OnNetworkSoonToDisconnect(NetworkHandle network) { |
| 1206 NetworkChangeNotifier::NetworkHandle network) { | |
| 1207 MaybeMigrateOrCloseSessions(network, /*force_close=*/false); | 1211 MaybeMigrateOrCloseSessions(network, /*force_close=*/false); |
| 1208 } | 1212 } |
| 1209 | 1213 |
| 1210 NetworkChangeNotifier::NetworkHandle QuicStreamFactory::FindAlternateNetwork( | 1214 NetworkHandle QuicStreamFactory::FindAlternateNetwork( |
| 1211 NetworkChangeNotifier::NetworkHandle old_network) { | 1215 NetworkHandle old_network) { |
| 1212 // Find a new network that sessions bound to |old_network| can be migrated to. | 1216 // Find a new network that sessions bound to |old_network| can be migrated to. |
| 1213 NetworkChangeNotifier::NetworkList network_list; | 1217 NetworkChangeNotifier::NetworkList network_list; |
| 1214 NetworkChangeNotifier::GetConnectedNetworks(&network_list); | 1218 NetworkChangeNotifier::GetConnectedNetworks(&network_list); |
| 1215 for (NetworkChangeNotifier::NetworkHandle new_network : network_list) { | 1219 for (NetworkHandle new_network : network_list) { |
| 1216 if (new_network != old_network) { | 1220 if (new_network != old_network) { |
| 1217 return new_network; | 1221 return new_network; |
| 1218 } | 1222 } |
| 1219 } | 1223 } |
| 1220 return NetworkChangeNotifier::kInvalidNetworkHandle; | 1224 return NetworkChangeNotifier::kInvalidNetworkHandle; |
| 1221 } | 1225 } |
| 1222 | 1226 |
| 1223 void QuicStreamFactory::MaybeMigrateOrCloseSessions( | 1227 void QuicStreamFactory::MaybeMigrateOrCloseSessions(NetworkHandle network, |
| 1224 NetworkChangeNotifier::NetworkHandle network, | 1228 bool force_close) { |
| 1225 bool force_close) { | |
| 1226 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); | 1229 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); |
| 1227 NetworkChangeNotifier::NetworkHandle new_network = | 1230 NetworkHandle new_network = FindAlternateNetwork(network); |
| 1228 FindAlternateNetwork(network); | |
| 1229 | 1231 |
| 1230 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); | 1232 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); |
| 1231 while (it != all_sessions_.end()) { | 1233 while (it != all_sessions_.end()) { |
| 1232 QuicChromiumClientSession* session = it->first; | 1234 QuicChromiumClientSession* session = it->first; |
| 1233 QuicServerId server_id = it->second; | 1235 QuicServerId server_id = it->second; |
| 1234 ++it; | 1236 ++it; |
| 1235 | 1237 |
| 1236 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { | 1238 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { |
| 1237 // If session is not bound to |network|, move on. | 1239 // If session is not bound to |network|, move on. |
| 1238 HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED); | 1240 HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1254 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); | 1256 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); |
| 1255 } | 1257 } |
| 1256 continue; | 1258 continue; |
| 1257 } | 1259 } |
| 1258 MigrateSessionToNetwork(session, new_network); | 1260 MigrateSessionToNetwork(session, new_network); |
| 1259 } | 1261 } |
| 1260 } | 1262 } |
| 1261 | 1263 |
| 1262 void QuicStreamFactory::MaybeMigrateSessionEarly( | 1264 void QuicStreamFactory::MaybeMigrateSessionEarly( |
| 1263 QuicChromiumClientSession* session) { | 1265 QuicChromiumClientSession* session) { |
| 1264 if (session->GetNumActiveStreams() == 0) { | 1266 if (!migrate_sessions_early_) { |
| 1265 return; | 1267 return; |
| 1266 } | 1268 } |
| 1267 NetworkChangeNotifier::NetworkHandle current_network = | 1269 NetworkHandle new_network = |
| 1268 session->GetDefaultSocket()->GetBoundNetwork(); | 1270 FindAlternateNetwork(session->GetDefaultSocket()->GetBoundNetwork()); |
| 1269 NetworkChangeNotifier::NetworkHandle new_network = | |
| 1270 FindAlternateNetwork(current_network); | |
| 1271 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { | 1271 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
| 1272 // No alternate network found. | 1272 // No alternate network found. |
| 1273 return; | 1273 return; |
| 1274 } | 1274 } |
| 1275 OnSessionGoingAway(session); | 1275 OnSessionGoingAway(session); |
| 1276 MigrateSessionToNetwork(session, new_network); | 1276 MigrateSessionToNetwork(session, new_network); |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 void QuicStreamFactory::MigrateSessionToNetwork( | 1279 void QuicStreamFactory::MigrateSessionToNetwork( |
| 1280 QuicChromiumClientSession* session, | 1280 QuicChromiumClientSession* session, |
| 1281 NetworkChangeNotifier::NetworkHandle new_network) { | 1281 NetworkHandle new_network) { |
| 1282 // Use OS-specified port for socket (DEFAULT_BIND) instead of | 1282 // Use OS-specified port for socket (DEFAULT_BIND) instead of |
| 1283 // using the PortSuggester since the connection is being migrated | 1283 // using the PortSuggester since the connection is being migrated |
| 1284 // and not being newly created. | 1284 // and not being newly created. |
| 1285 scoped_ptr<DatagramClientSocket> socket( | 1285 scoped_ptr<DatagramClientSocket> socket( |
| 1286 client_socket_factory_->CreateDatagramClientSocket( | 1286 client_socket_factory_->CreateDatagramClientSocket( |
| 1287 DatagramSocket::DEFAULT_BIND, RandIntCallback(), | 1287 DatagramSocket::DEFAULT_BIND, RandIntCallback(), |
| 1288 session->net_log().net_log(), session->net_log().source())); | 1288 session->net_log().net_log(), session->net_log().source())); |
| 1289 QuicConnection* connection = session->connection(); | 1289 QuicConnection* connection = session->connection(); |
| 1290 if (ConfigureSocket(socket.get(), connection->peer_address(), new_network) != | 1290 if (ConfigureSocket(socket.get(), connection->peer_address(), new_network) != |
| 1291 OK) { | 1291 OK) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. | 1334 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. |
| 1335 if (active_sessions_.empty()) | 1335 if (active_sessions_.empty()) |
| 1336 return false; | 1336 return false; |
| 1337 return ContainsKey(active_sessions_, server_id); | 1337 return ContainsKey(active_sessions_, server_id); |
| 1338 } | 1338 } |
| 1339 | 1339 |
| 1340 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | 1340 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
| 1341 return ContainsKey(active_jobs_, key); | 1341 return ContainsKey(active_jobs_, key); |
| 1342 } | 1342 } |
| 1343 | 1343 |
| 1344 int QuicStreamFactory::ConfigureSocket( | 1344 int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket, |
| 1345 DatagramClientSocket* socket, | 1345 IPEndPoint addr, |
| 1346 IPEndPoint addr, | 1346 NetworkHandle network) { |
| 1347 NetworkChangeNotifier::NetworkHandle network) { | |
| 1348 if (enable_non_blocking_io_ && | 1347 if (enable_non_blocking_io_ && |
| 1349 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { | 1348 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { |
| 1350 #if defined(OS_WIN) | 1349 #if defined(OS_WIN) |
| 1351 static_cast<UDPClientSocket*>(socket)->UseNonBlockingIO(); | 1350 static_cast<UDPClientSocket*>(socket)->UseNonBlockingIO(); |
| 1352 #endif | 1351 #endif |
| 1353 } | 1352 } |
| 1354 | 1353 |
| 1355 // If caller leaves network unspecified, use current default. | 1354 // If caller leaves network unspecified, use current default. |
| 1356 int rv; | 1355 int rv; |
| 1357 if (migrate_sessions_on_network_change_) { | 1356 if (migrate_sessions_on_network_change_) { |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1654 // Since the session was active, there's no longer an | 1653 // Since the session was active, there's no longer an |
| 1655 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1654 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
| 1656 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1655 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
| 1657 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1656 // it as recently broken, which means that 0-RTT will be disabled but we'll |
| 1658 // still race. | 1657 // still race. |
| 1659 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1658 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
| 1660 alternative_service); | 1659 alternative_service); |
| 1661 } | 1660 } |
| 1662 | 1661 |
| 1663 } // namespace net | 1662 } // namespace net |
| OLD | NEW |