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

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: Rebase. 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
« no previous file with comments | « net/quic/quic_stream_factory.h ('k') | net/quic/quic_stream_factory_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/quic_stream_factory.h ('k') | net/quic/quic_stream_factory_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698