| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 namespace { | 66 namespace { |
| 67 | 67 |
| 68 enum CreateSessionFailure { | 68 enum CreateSessionFailure { |
| 69 CREATION_ERROR_CONNECTING_SOCKET, | 69 CREATION_ERROR_CONNECTING_SOCKET, |
| 70 CREATION_ERROR_SETTING_RECEIVE_BUFFER, | 70 CREATION_ERROR_SETTING_RECEIVE_BUFFER, |
| 71 CREATION_ERROR_SETTING_SEND_BUFFER, | 71 CREATION_ERROR_SETTING_SEND_BUFFER, |
| 72 CREATION_ERROR_MAX | 72 CREATION_ERROR_MAX |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 enum QuicConnectionMigrationStatus { |
| 76 MIGRATION_STATUS_NO_MIGRATABLE_STREAMS, |
| 77 MIGRATION_STATUS_ALREADY_MIGRATED, |
| 78 MIGRATION_STATUS_INTERNAL_ERROR, |
| 79 MIGRATION_STATUS_TOO_MANY_CHANGES, |
| 80 MIGRATION_STATUS_SUCCESS, |
| 81 MIGRATION_STATUS_MAX |
| 82 }; |
| 83 |
| 75 // The maximum receive window sizes for QUIC sessions and streams. | 84 // The maximum receive window sizes for QUIC sessions and streams. |
| 76 const int32_t kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB | 85 const int32_t kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB |
| 77 const int32_t kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB | 86 const int32_t kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB |
| 78 | 87 |
| 79 // Set the maximum number of undecryptable packets the connection will store. | 88 // Set the maximum number of undecryptable packets the connection will store. |
| 80 const int32_t kMaxUndecryptablePackets = 100; | 89 const int32_t kMaxUndecryptablePackets = 100; |
| 81 | 90 |
| 82 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { | 91 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { |
| 83 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, | 92 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, |
| 84 CREATION_ERROR_MAX); | 93 CREATION_ERROR_MAX); |
| 85 } | 94 } |
| 86 | 95 |
| 96 void HistogramMigrationStatus(enum QuicConnectionMigrationStatus status) { |
| 97 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration", status, |
| 98 MIGRATION_STATUS_MAX); |
| 99 } |
| 100 |
| 87 bool IsEcdsaSupported() { | 101 bool IsEcdsaSupported() { |
| 88 #if defined(OS_WIN) | 102 #if defined(OS_WIN) |
| 89 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 103 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 90 return false; | 104 return false; |
| 91 #endif | 105 #endif |
| 92 | 106 |
| 93 return true; | 107 return true; |
| 94 } | 108 } |
| 95 | 109 |
| 96 QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options, | 110 QuicConfig InitializeQuicConfig(const QuicTagVector& connection_options, |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 int max_number_of_lossy_connections, | 583 int max_number_of_lossy_connections, |
| 570 float packet_loss_threshold, | 584 float packet_loss_threshold, |
| 571 int max_disabled_reasons, | 585 int max_disabled_reasons, |
| 572 int threshold_public_resets_post_handshake, | 586 int threshold_public_resets_post_handshake, |
| 573 int threshold_timeouts_with_open_streams, | 587 int threshold_timeouts_with_open_streams, |
| 574 int socket_receive_buffer_size, | 588 int socket_receive_buffer_size, |
| 575 bool delay_tcp_race, | 589 bool delay_tcp_race, |
| 576 bool store_server_configs_in_properties, | 590 bool store_server_configs_in_properties, |
| 577 bool close_sessions_on_ip_change, | 591 bool close_sessions_on_ip_change, |
| 578 int idle_connection_timeout_seconds, | 592 int idle_connection_timeout_seconds, |
| 593 bool migrate_sessions_on_network_change, |
| 579 const QuicTagVector& connection_options) | 594 const QuicTagVector& connection_options) |
| 580 : require_confirmation_(true), | 595 : require_confirmation_(true), |
| 581 host_resolver_(host_resolver), | 596 host_resolver_(host_resolver), |
| 582 client_socket_factory_(client_socket_factory), | 597 client_socket_factory_(client_socket_factory), |
| 583 http_server_properties_(http_server_properties), | 598 http_server_properties_(http_server_properties), |
| 584 transport_security_state_(transport_security_state), | 599 transport_security_state_(transport_security_state), |
| 585 cert_transparency_verifier_(cert_transparency_verifier), | 600 cert_transparency_verifier_(cert_transparency_verifier), |
| 586 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), | 601 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), |
| 587 random_generator_(random_generator), | 602 random_generator_(random_generator), |
| 588 clock_(clock), | 603 clock_(clock), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 616 threshold_timeouts_with_open_streams), | 631 threshold_timeouts_with_open_streams), |
| 617 threshold_public_resets_post_handshake_( | 632 threshold_public_resets_post_handshake_( |
| 618 threshold_public_resets_post_handshake), | 633 threshold_public_resets_post_handshake), |
| 619 socket_receive_buffer_size_(socket_receive_buffer_size), | 634 socket_receive_buffer_size_(socket_receive_buffer_size), |
| 620 delay_tcp_race_(delay_tcp_race), | 635 delay_tcp_race_(delay_tcp_race), |
| 621 yield_after_packets_(kQuicYieldAfterPacketsRead), | 636 yield_after_packets_(kQuicYieldAfterPacketsRead), |
| 622 yield_after_duration_(QuicTime::Delta::FromMilliseconds( | 637 yield_after_duration_(QuicTime::Delta::FromMilliseconds( |
| 623 kQuicYieldAfterDurationMilliseconds)), | 638 kQuicYieldAfterDurationMilliseconds)), |
| 624 store_server_configs_in_properties_(store_server_configs_in_properties), | 639 store_server_configs_in_properties_(store_server_configs_in_properties), |
| 625 close_sessions_on_ip_change_(close_sessions_on_ip_change), | 640 close_sessions_on_ip_change_(close_sessions_on_ip_change), |
| 641 migrate_sessions_on_network_change_( |
| 642 migrate_sessions_on_network_change && |
| 643 NetworkChangeNotifier::AreNetworkHandlesSupported()), |
| 626 port_seed_(random_generator_->RandUint64()), | 644 port_seed_(random_generator_->RandUint64()), |
| 627 check_persisted_supports_quic_(true), | 645 check_persisted_supports_quic_(true), |
| 628 has_initialized_data_(false), | 646 has_initialized_data_(false), |
| 629 task_runner_(nullptr), | 647 task_runner_(nullptr), |
| 630 weak_factory_(this) { | 648 weak_factory_(this) { |
| 631 DCHECK(transport_security_state_); | 649 DCHECK(transport_security_state_); |
| 632 DCHECK(http_server_properties_); | 650 DCHECK(http_server_properties_); |
| 633 crypto_config_.set_user_agent_id(user_agent_id); | 651 crypto_config_.set_user_agent_id(user_agent_id); |
| 634 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); | 652 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); |
| 635 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); | 653 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 654 if (!IsEcdsaSupported()) | 672 if (!IsEcdsaSupported()) |
| 655 crypto_config_.DisableEcdsa(); | 673 crypto_config_.DisableEcdsa(); |
| 656 // When disk cache is used to store the server configs, HttpCache code calls | 674 // When disk cache is used to store the server configs, HttpCache code calls |
| 657 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't | 675 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't |
| 658 // created. | 676 // created. |
| 659 if (store_server_configs_in_properties_) { | 677 if (store_server_configs_in_properties_) { |
| 660 quic_server_info_factory_.reset( | 678 quic_server_info_factory_.reset( |
| 661 new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); | 679 new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); |
| 662 } | 680 } |
| 663 | 681 |
| 664 if (close_sessions_on_ip_change_) { | 682 DCHECK( |
| 683 !(close_sessions_on_ip_change_ && migrate_sessions_on_network_change_)); |
| 684 if (migrate_sessions_on_network_change_) { |
| 685 NetworkChangeNotifier::AddNetworkObserver(this); |
| 686 } else if (close_sessions_on_ip_change_) { |
| 665 NetworkChangeNotifier::AddIPAddressObserver(this); | 687 NetworkChangeNotifier::AddIPAddressObserver(this); |
| 666 } | 688 } |
| 667 } | 689 } |
| 668 | 690 |
| 669 QuicStreamFactory::~QuicStreamFactory() { | 691 QuicStreamFactory::~QuicStreamFactory() { |
| 670 CloseAllSessions(ERR_ABORTED); | 692 CloseAllSessions(ERR_ABORTED, QUIC_INTERNAL_ERROR); |
| 671 while (!all_sessions_.empty()) { | 693 while (!all_sessions_.empty()) { |
| 672 delete all_sessions_.begin()->first; | 694 delete all_sessions_.begin()->first; |
| 673 all_sessions_.erase(all_sessions_.begin()); | 695 all_sessions_.erase(all_sessions_.begin()); |
| 674 } | 696 } |
| 675 while (!active_jobs_.empty()) { | 697 while (!active_jobs_.empty()) { |
| 676 const QuicServerId server_id = active_jobs_.begin()->first; | 698 const QuicServerId server_id = active_jobs_.begin()->first; |
| 677 STLDeleteElements(&(active_jobs_[server_id])); | 699 STLDeleteElements(&(active_jobs_[server_id])); |
| 678 active_jobs_.erase(server_id); | 700 active_jobs_.erase(server_id); |
| 679 } | 701 } |
| 680 if (close_sessions_on_ip_change_) { | 702 if (migrate_sessions_on_network_change_) { |
| 703 NetworkChangeNotifier::RemoveNetworkObserver(this); |
| 704 } else if (close_sessions_on_ip_change_) { |
| 681 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 705 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 682 } | 706 } |
| 683 } | 707 } |
| 684 | 708 |
| 685 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { | 709 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { |
| 686 require_confirmation_ = require_confirmation; | 710 require_confirmation_ = require_confirmation; |
| 687 if (!(local_address_ == IPEndPoint())) { | 711 if (!(local_address_ == IPEndPoint())) { |
| 688 http_server_properties_->SetSupportsQuic(!require_confirmation, | 712 http_server_properties_->SetSupportsQuic(!require_confirmation, |
| 689 local_address_.address()); | 713 local_address_.address()); |
| 690 } | 714 } |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1096 DCHECK_EQ(ERR_IO_PENDING, rv); | 1120 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 1097 } | 1121 } |
| 1098 | 1122 |
| 1099 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 1123 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
| 1100 DCHECK(ContainsKey(active_requests_, request)); | 1124 DCHECK(ContainsKey(active_requests_, request)); |
| 1101 QuicServerId server_id = active_requests_[request]; | 1125 QuicServerId server_id = active_requests_[request]; |
| 1102 job_requests_map_[server_id].erase(request); | 1126 job_requests_map_[server_id].erase(request); |
| 1103 active_requests_.erase(request); | 1127 active_requests_.erase(request); |
| 1104 } | 1128 } |
| 1105 | 1129 |
| 1106 void QuicStreamFactory::CloseAllSessions(int error) { | 1130 void QuicStreamFactory::CloseAllSessions(int error, QuicErrorCode quic_error) { |
| 1107 while (!active_sessions_.empty()) { | 1131 while (!active_sessions_.empty()) { |
| 1108 size_t initial_size = active_sessions_.size(); | 1132 size_t initial_size = active_sessions_.size(); |
| 1109 active_sessions_.begin()->second->CloseSessionOnError(error, | 1133 active_sessions_.begin()->second->CloseSessionOnError(error, quic_error); |
| 1110 QUIC_INTERNAL_ERROR); | |
| 1111 DCHECK_NE(initial_size, active_sessions_.size()); | 1134 DCHECK_NE(initial_size, active_sessions_.size()); |
| 1112 } | 1135 } |
| 1113 while (!all_sessions_.empty()) { | 1136 while (!all_sessions_.empty()) { |
| 1114 size_t initial_size = all_sessions_.size(); | 1137 size_t initial_size = all_sessions_.size(); |
| 1115 all_sessions_.begin()->first->CloseSessionOnError(error, | 1138 all_sessions_.begin()->first->CloseSessionOnError(error, quic_error); |
| 1116 QUIC_INTERNAL_ERROR); | |
| 1117 DCHECK_NE(initial_size, all_sessions_.size()); | 1139 DCHECK_NE(initial_size, all_sessions_.size()); |
| 1118 } | 1140 } |
| 1119 DCHECK(all_sessions_.empty()); | 1141 DCHECK(all_sessions_.empty()); |
| 1120 } | 1142 } |
| 1121 | 1143 |
| 1122 scoped_ptr<base::Value> QuicStreamFactory::QuicStreamFactoryInfoToValue() | 1144 scoped_ptr<base::Value> QuicStreamFactory::QuicStreamFactoryInfoToValue() |
| 1123 const { | 1145 const { |
| 1124 scoped_ptr<base::ListValue> list(new base::ListValue()); | 1146 scoped_ptr<base::ListValue> list(new base::ListValue()); |
| 1125 | 1147 |
| 1126 for (SessionMap::const_iterator it = active_sessions_.begin(); | 1148 for (SessionMap::const_iterator it = active_sessions_.begin(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1139 } | 1161 } |
| 1140 } | 1162 } |
| 1141 return std::move(list); | 1163 return std::move(list); |
| 1142 } | 1164 } |
| 1143 | 1165 |
| 1144 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { | 1166 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { |
| 1145 crypto_config_.ClearCachedStates(); | 1167 crypto_config_.ClearCachedStates(); |
| 1146 } | 1168 } |
| 1147 | 1169 |
| 1148 void QuicStreamFactory::OnIPAddressChanged() { | 1170 void QuicStreamFactory::OnIPAddressChanged() { |
| 1149 CloseAllSessions(ERR_NETWORK_CHANGED); | 1171 CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED); |
| 1150 set_require_confirmation(true); | 1172 set_require_confirmation(true); |
| 1151 } | 1173 } |
| 1152 | 1174 |
| 1175 void QuicStreamFactory::OnNetworkConnected( |
| 1176 NetworkChangeNotifier::NetworkHandle network) {} |
| 1177 |
| 1178 void QuicStreamFactory::OnNetworkMadeDefault( |
| 1179 NetworkChangeNotifier::NetworkHandle network) {} |
| 1180 |
| 1181 void QuicStreamFactory::OnNetworkDisconnected( |
| 1182 NetworkChangeNotifier::NetworkHandle network) { |
| 1183 MaybeMigrateOrCloseSessions(network, /*force_close=*/true); |
| 1184 set_require_confirmation(true); |
| 1185 } |
| 1186 |
| 1187 // This method is expected to only be called when migrating from Cellular to |
| 1188 // WiFi on Android. |
| 1189 void QuicStreamFactory::OnNetworkSoonToDisconnect( |
| 1190 NetworkChangeNotifier::NetworkHandle network) { |
| 1191 MaybeMigrateOrCloseSessions(network, /*force_close=*/false); |
| 1192 } |
| 1193 |
| 1194 void QuicStreamFactory::MaybeMigrateOrCloseSessions( |
| 1195 NetworkChangeNotifier::NetworkHandle network, |
| 1196 bool force_close) { |
| 1197 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); |
| 1198 |
| 1199 // Find a new network that sessions bound to |network| can be migrated to. |
| 1200 NetworkChangeNotifier::NetworkList network_list; |
| 1201 NetworkChangeNotifier::GetConnectedNetworks(&network_list); |
| 1202 NetworkChangeNotifier::NetworkHandle new_network = |
| 1203 NetworkChangeNotifier::kInvalidNetworkHandle; |
| 1204 for (NetworkChangeNotifier::NetworkHandle n : network_list) { |
| 1205 if (n != network) { |
| 1206 new_network = n; |
| 1207 break; |
| 1208 } |
| 1209 } |
| 1210 |
| 1211 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); |
| 1212 while (it != all_sessions_.end()) { |
| 1213 QuicChromiumClientSession* session = it->first; |
| 1214 QuicServerId server_id = it->second; |
| 1215 ++it; |
| 1216 |
| 1217 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { |
| 1218 // If session is not bound to |network|, move on. |
| 1219 HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED); |
| 1220 continue; |
| 1221 } |
| 1222 if (session->GetNumActiveStreams() == 0) { |
| 1223 // Close idle sessions. |
| 1224 session->CloseSessionOnError( |
| 1225 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS); |
| 1226 HistogramMigrationStatus(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS); |
| 1227 continue; |
| 1228 } |
| 1229 // If session has active streams, mark it as going away. |
| 1230 OnSessionGoingAway(session); |
| 1231 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
| 1232 // No new network was found. |
| 1233 if (force_close) { |
| 1234 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
| 1235 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); |
| 1236 } |
| 1237 continue; |
| 1238 } |
| 1239 |
| 1240 // Use OS-specified port for socket (DEFAULT_BIND) instead of |
| 1241 // using the PortSuggester since the connection is being migrated |
| 1242 // and not being newly created. |
| 1243 scoped_ptr<DatagramClientSocket> socket( |
| 1244 client_socket_factory_->CreateDatagramClientSocket( |
| 1245 DatagramSocket::DEFAULT_BIND, RandIntCallback(), |
| 1246 session->net_log().net_log(), session->net_log().source())); |
| 1247 |
| 1248 QuicConnection* connection = session->connection(); |
| 1249 if (ConfigureSocket(socket.get(), connection->peer_address(), |
| 1250 new_network) != OK) { |
| 1251 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); |
| 1252 HistogramMigrationStatus(MIGRATION_STATUS_INTERNAL_ERROR); |
| 1253 continue; |
| 1254 } |
| 1255 |
| 1256 scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader( |
| 1257 socket.get(), clock_.get(), session, yield_after_packets_, |
| 1258 yield_after_duration_, session->net_log())); |
| 1259 DefaultPacketWriterFactory packet_writer_factory(socket.get()); |
| 1260 scoped_ptr<QuicPacketWriter> new_writer( |
| 1261 packet_writer_factory.Create(connection)); |
| 1262 |
| 1263 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), |
| 1264 std::move(new_writer))) { |
| 1265 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
| 1266 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); |
| 1267 HistogramMigrationStatus(MIGRATION_STATUS_TOO_MANY_CHANGES); |
| 1268 } else { |
| 1269 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); |
| 1270 } |
| 1271 } |
| 1272 } |
| 1273 |
| 1153 void QuicStreamFactory::OnSSLConfigChanged() { | 1274 void QuicStreamFactory::OnSSLConfigChanged() { |
| 1154 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 1275 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); |
| 1155 } | 1276 } |
| 1156 | 1277 |
| 1157 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 1278 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
| 1158 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 1279 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); |
| 1159 } | 1280 } |
| 1160 | 1281 |
| 1161 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { | 1282 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { |
| 1162 // We should flush the sessions if we removed trust from a | 1283 // We should flush the sessions if we removed trust from a |
| 1163 // cert, because a previously trusted server may have become | 1284 // cert, because a previously trusted server may have become |
| 1164 // untrusted. | 1285 // untrusted. |
| 1165 // | 1286 // |
| 1166 // We should not flush the sessions if we added trust to a cert. | 1287 // We should not flush the sessions if we added trust to a cert. |
| 1167 // | 1288 // |
| 1168 // Since the OnCACertChanged method doesn't tell us what | 1289 // Since the OnCACertChanged method doesn't tell us what |
| 1169 // kind of change it is, we have to flush the socket | 1290 // kind of change it is, we have to flush the socket |
| 1170 // pools to be safe. | 1291 // pools to be safe. |
| 1171 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 1292 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); |
| 1172 } | 1293 } |
| 1173 | 1294 |
| 1174 bool QuicStreamFactory::HasActiveSession(const QuicServerId& server_id) const { | 1295 bool QuicStreamFactory::HasActiveSession(const QuicServerId& server_id) const { |
| 1175 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. | 1296 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. |
| 1176 if (active_sessions_.empty()) | 1297 if (active_sessions_.empty()) |
| 1177 return false; | 1298 return false; |
| 1178 return ContainsKey(active_sessions_, server_id); | 1299 return ContainsKey(active_sessions_, server_id); |
| 1179 } | 1300 } |
| 1180 | 1301 |
| 1181 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | 1302 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
| 1182 return ContainsKey(active_jobs_, key); | 1303 return ContainsKey(active_jobs_, key); |
| 1183 } | 1304 } |
| 1184 | 1305 |
| 1185 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, | 1306 int QuicStreamFactory::ConfigureSocket( |
| 1186 int cert_verify_flags, | 1307 DatagramClientSocket* socket, |
| 1187 scoped_ptr<QuicServerInfo> server_info, | 1308 IPEndPoint addr, |
| 1188 const AddressList& address_list, | 1309 NetworkChangeNotifier::NetworkHandle network) { |
| 1189 base::TimeTicks dns_resolution_end_time, | |
| 1190 const BoundNetLog& net_log, | |
| 1191 QuicChromiumClientSession** session) { | |
| 1192 bool enable_port_selection = enable_port_selection_; | |
| 1193 if (enable_port_selection && ContainsKey(gone_away_aliases_, server_id)) { | |
| 1194 // Disable port selection when the server is going away. | |
| 1195 // There is no point in trying to return to the same server, if | |
| 1196 // that server is no longer handling requests. | |
| 1197 enable_port_selection = false; | |
| 1198 gone_away_aliases_.erase(server_id); | |
| 1199 } | |
| 1200 | |
| 1201 QuicConnectionId connection_id = random_generator_->RandUint64(); | |
| 1202 IPEndPoint addr = *address_list.begin(); | |
| 1203 scoped_refptr<PortSuggester> port_suggester = | |
| 1204 new PortSuggester(server_id.host_port_pair(), port_seed_); | |
| 1205 DatagramSocket::BindType bind_type = | |
| 1206 enable_port_selection ? DatagramSocket::RANDOM_BIND | |
| 1207 : // Use our callback. | |
| 1208 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | |
| 1209 scoped_ptr<DatagramClientSocket> socket( | |
| 1210 client_socket_factory_->CreateDatagramClientSocket( | |
| 1211 bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester), | |
| 1212 net_log.net_log(), net_log.source())); | |
| 1213 | |
| 1214 if (enable_non_blocking_io_ && | 1310 if (enable_non_blocking_io_ && |
| 1215 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { | 1311 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { |
| 1216 #if defined(OS_WIN) | 1312 #if defined(OS_WIN) |
| 1217 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO(); | 1313 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO(); |
| 1218 #endif | 1314 #endif |
| 1219 } | 1315 } |
| 1220 | 1316 |
| 1221 int rv = socket->Connect(addr); | 1317 // If caller leaves network unspecified, use current default. |
| 1318 int rv; |
| 1319 if (migrate_sessions_on_network_change_) { |
| 1320 if (network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
| 1321 rv = socket->BindToDefaultNetwork(); |
| 1322 } else { |
| 1323 rv = socket->BindToNetwork(network); |
| 1324 } |
| 1325 if (rv != OK) |
| 1326 return rv; |
| 1327 } |
| 1222 | 1328 |
| 1329 rv = socket->Connect(addr); |
| 1223 if (rv != OK) { | 1330 if (rv != OK) { |
| 1224 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); | 1331 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); |
| 1225 return rv; | 1332 return rv; |
| 1226 } | 1333 } |
| 1227 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", | |
| 1228 port_suggester->call_count()); | |
| 1229 if (enable_port_selection) { | |
| 1230 DCHECK_LE(1u, port_suggester->call_count()); | |
| 1231 } else { | |
| 1232 DCHECK_EQ(0u, port_suggester->call_count()); | |
| 1233 } | |
| 1234 | 1334 |
| 1235 rv = socket->SetReceiveBufferSize(socket_receive_buffer_size_); | 1335 rv = socket->SetReceiveBufferSize(socket_receive_buffer_size_); |
| 1236 if (rv != OK) { | 1336 if (rv != OK) { |
| 1237 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); | 1337 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); |
| 1238 return rv; | 1338 return rv; |
| 1239 } | 1339 } |
| 1340 |
| 1240 // Set a buffer large enough to contain the initial CWND's worth of packet | 1341 // Set a buffer large enough to contain the initial CWND's worth of packet |
| 1241 // to work around the problem with CHLO packets being sent out with the | 1342 // to work around the problem with CHLO packets being sent out with the |
| 1242 // wrong encryption level, when the send buffer is full. | 1343 // wrong encryption level, when the send buffer is full. |
| 1243 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); | 1344 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); |
| 1244 if (rv != OK) { | 1345 if (rv != OK) { |
| 1245 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER); | 1346 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER); |
| 1246 return rv; | 1347 return rv; |
| 1247 } | 1348 } |
| 1248 | 1349 |
| 1249 socket->GetLocalAddress(&local_address_); | 1350 socket->GetLocalAddress(&local_address_); |
| 1250 if (check_persisted_supports_quic_) { | 1351 if (check_persisted_supports_quic_) { |
| 1251 check_persisted_supports_quic_ = false; | 1352 check_persisted_supports_quic_ = false; |
| 1252 IPAddressNumber last_address; | 1353 IPAddressNumber last_address; |
| 1253 if (http_server_properties_->GetSupportsQuic(&last_address) && | 1354 if (http_server_properties_->GetSupportsQuic(&last_address) && |
| 1254 last_address == local_address_.address()) { | 1355 last_address == local_address_.address()) { |
| 1255 require_confirmation_ = false; | 1356 require_confirmation_ = false; |
| 1256 } | 1357 } |
| 1257 } | 1358 } |
| 1258 | 1359 |
| 1360 return OK; |
| 1361 } |
| 1362 |
| 1363 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, |
| 1364 int cert_verify_flags, |
| 1365 scoped_ptr<QuicServerInfo> server_info, |
| 1366 const AddressList& address_list, |
| 1367 base::TimeTicks dns_resolution_end_time, |
| 1368 const BoundNetLog& net_log, |
| 1369 QuicChromiumClientSession** session) { |
| 1370 IPEndPoint addr = *address_list.begin(); |
| 1371 bool enable_port_selection = enable_port_selection_; |
| 1372 if (enable_port_selection && ContainsKey(gone_away_aliases_, server_id)) { |
| 1373 // Disable port selection when the server is going away. |
| 1374 // There is no point in trying to return to the same server, if |
| 1375 // that server is no longer handling requests. |
| 1376 enable_port_selection = false; |
| 1377 gone_away_aliases_.erase(server_id); |
| 1378 } |
| 1379 scoped_refptr<PortSuggester> port_suggester = |
| 1380 new PortSuggester(server_id.host_port_pair(), port_seed_); |
| 1381 DatagramSocket::BindType bind_type = |
| 1382 enable_port_selection ? DatagramSocket::RANDOM_BIND |
| 1383 : // Use our callback. |
| 1384 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
| 1385 |
| 1386 scoped_ptr<DatagramClientSocket> socket( |
| 1387 client_socket_factory_->CreateDatagramClientSocket( |
| 1388 bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester), |
| 1389 net_log.net_log(), net_log.source())); |
| 1390 |
| 1391 // Passing in kInvalidNetworkHandle binds socket to default network. |
| 1392 int rv = ConfigureSocket(socket.get(), addr, |
| 1393 NetworkChangeNotifier::kInvalidNetworkHandle); |
| 1394 if (rv != OK) { |
| 1395 return rv; |
| 1396 } |
| 1397 |
| 1398 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested", |
| 1399 port_suggester->call_count()); |
| 1400 if (enable_port_selection) { |
| 1401 DCHECK_LE(1u, port_suggester->call_count()); |
| 1402 } else { |
| 1403 DCHECK_EQ(0u, port_suggester->call_count()); |
| 1404 } |
| 1405 |
| 1259 DefaultPacketWriterFactory packet_writer_factory(socket.get()); | 1406 DefaultPacketWriterFactory packet_writer_factory(socket.get()); |
| 1260 | |
| 1261 if (!helper_.get()) { | 1407 if (!helper_.get()) { |
| 1262 helper_.reset( | 1408 helper_.reset( |
| 1263 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(), | 1409 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(), |
| 1264 clock_.get(), random_generator_)); | 1410 clock_.get(), random_generator_)); |
| 1265 } | 1411 } |
| 1266 | 1412 |
| 1413 QuicConnectionId connection_id = random_generator_->RandUint64(); |
| 1267 QuicConnection* connection = new QuicConnection( | 1414 QuicConnection* connection = new QuicConnection( |
| 1268 connection_id, addr, helper_.get(), packet_writer_factory, | 1415 connection_id, addr, helper_.get(), packet_writer_factory, |
| 1269 true /* owns_writer */, Perspective::IS_CLIENT, supported_versions_); | 1416 true /* owns_writer */, Perspective::IS_CLIENT, supported_versions_); |
| 1270 connection->SetMaxPacketLength(max_packet_length_); | 1417 connection->SetMaxPacketLength(max_packet_length_); |
| 1271 | 1418 |
| 1272 InitializeCachedStateInCryptoConfig(server_id, server_info); | 1419 InitializeCachedStateInCryptoConfig(server_id, server_info); |
| 1273 | 1420 |
| 1274 QuicConfig config = config_; | 1421 QuicConfig config = config_; |
| 1275 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_); | 1422 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_); |
| 1276 config.set_max_undecryptable_packets(kMaxUndecryptablePackets); | 1423 config.set_max_undecryptable_packets(kMaxUndecryptablePackets); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 // Since the session was active, there's no longer an | 1606 // Since the session was active, there's no longer an |
| 1460 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1607 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
| 1461 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1608 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
| 1462 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1609 // it as recently broken, which means that 0-RTT will be disabled but we'll |
| 1463 // still race. | 1610 // still race. |
| 1464 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1611 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
| 1465 alternative_service); | 1612 alternative_service); |
| 1466 } | 1613 } |
| 1467 | 1614 |
| 1468 } // namespace net | 1615 } // namespace net |
| OLD | NEW |