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