Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: net/quic/quic_stream_factory.cc

Issue 1327923002: Migrates QUIC sessions to a new network when old network is (about to be) disconnected. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@home
Patch Set: Addresses rch's comments. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698