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

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: Added read/write socket error tests. 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 #include <utility> 9 #include <utility>
10 10
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698