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