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

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: Naming fixes. Created 5 years 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 63
64 namespace { 64 namespace {
65 65
66 enum CreateSessionFailure { 66 enum CreateSessionFailure {
67 CREATION_ERROR_CONNECTING_SOCKET, 67 CREATION_ERROR_CONNECTING_SOCKET,
68 CREATION_ERROR_SETTING_RECEIVE_BUFFER, 68 CREATION_ERROR_SETTING_RECEIVE_BUFFER,
69 CREATION_ERROR_SETTING_SEND_BUFFER, 69 CREATION_ERROR_SETTING_SEND_BUFFER,
70 CREATION_ERROR_MAX 70 CREATION_ERROR_MAX
71 }; 71 };
72 72
73 enum QuicConnectionMigrationStatus {
74 MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
75 MIGRATION_STATUS_ALREADY_MIGRATED,
76 MIGRATION_STATUS_INTERNAL_ERROR,
77 MIGRATION_STATUS_TOO_MANY_CHANGES,
78 MIGRATION_STATUS_SUCCESS,
79 MIGRATION_STATUS_MAX
80 };
81
73 // The maximum receive window sizes for QUIC sessions and streams. 82 // The maximum receive window sizes for QUIC sessions and streams.
74 const int32 kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB 83 const int32 kQuicSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
75 const int32 kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB 84 const int32 kQuicStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
76 85
77 // Set the maximum number of undecryptable packets the connection will store. 86 // Set the maximum number of undecryptable packets the connection will store.
78 const int32 kMaxUndecryptablePackets = 100; 87 const int32 kMaxUndecryptablePackets = 100;
79 88
80 void HistogramCreateSessionFailure(enum CreateSessionFailure error) { 89 void HistogramCreateSessionFailure(enum CreateSessionFailure error) {
81 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error, 90 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error,
82 CREATION_ERROR_MAX); 91 CREATION_ERROR_MAX);
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 int max_number_of_lossy_connections, 573 int max_number_of_lossy_connections,
565 float packet_loss_threshold, 574 float packet_loss_threshold,
566 int max_disabled_reasons, 575 int max_disabled_reasons,
567 int threshold_public_resets_post_handshake, 576 int threshold_public_resets_post_handshake,
568 int threshold_timeouts_with_open_streams, 577 int threshold_timeouts_with_open_streams,
569 int socket_receive_buffer_size, 578 int socket_receive_buffer_size,
570 bool delay_tcp_race, 579 bool delay_tcp_race,
571 bool store_server_configs_in_properties, 580 bool store_server_configs_in_properties,
572 bool close_sessions_on_ip_change, 581 bool close_sessions_on_ip_change,
573 int idle_connection_timeout_seconds, 582 int idle_connection_timeout_seconds,
583 bool migrate_sessions_on_network_change,
574 const QuicTagVector& connection_options) 584 const QuicTagVector& connection_options)
575 : require_confirmation_(true), 585 : require_confirmation_(true),
576 host_resolver_(host_resolver), 586 host_resolver_(host_resolver),
577 client_socket_factory_(client_socket_factory), 587 client_socket_factory_(client_socket_factory),
578 http_server_properties_(http_server_properties), 588 http_server_properties_(http_server_properties),
579 transport_security_state_(transport_security_state), 589 transport_security_state_(transport_security_state),
580 cert_transparency_verifier_(cert_transparency_verifier), 590 cert_transparency_verifier_(cert_transparency_verifier),
581 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), 591 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory),
582 random_generator_(random_generator), 592 random_generator_(random_generator),
583 clock_(clock), 593 clock_(clock),
(...skipping 27 matching lines...) Expand all
611 threshold_timeouts_with_open_streams), 621 threshold_timeouts_with_open_streams),
612 threshold_public_resets_post_handshake_( 622 threshold_public_resets_post_handshake_(
613 threshold_public_resets_post_handshake), 623 threshold_public_resets_post_handshake),
614 socket_receive_buffer_size_(socket_receive_buffer_size), 624 socket_receive_buffer_size_(socket_receive_buffer_size),
615 delay_tcp_race_(delay_tcp_race), 625 delay_tcp_race_(delay_tcp_race),
616 yield_after_packets_(kQuicYieldAfterPacketsRead), 626 yield_after_packets_(kQuicYieldAfterPacketsRead),
617 yield_after_duration_(QuicTime::Delta::FromMilliseconds( 627 yield_after_duration_(QuicTime::Delta::FromMilliseconds(
618 kQuicYieldAfterDurationMilliseconds)), 628 kQuicYieldAfterDurationMilliseconds)),
619 store_server_configs_in_properties_(store_server_configs_in_properties), 629 store_server_configs_in_properties_(store_server_configs_in_properties),
620 close_sessions_on_ip_change_(close_sessions_on_ip_change), 630 close_sessions_on_ip_change_(close_sessions_on_ip_change),
631 migrate_sessions_on_network_change_(migrate_sessions_on_network_change),
Ryan Hamilton 2015/12/18 21:51:23 Presumably we don't want both close_ and migrate_
Jana 2015/12/21 23:10:19 Hmm -- yes, I think we'd want them to be mutually
621 port_seed_(random_generator_->RandUint64()), 632 port_seed_(random_generator_->RandUint64()),
622 check_persisted_supports_quic_(true), 633 check_persisted_supports_quic_(true),
623 has_initialized_data_(false), 634 has_initialized_data_(false),
624 task_runner_(nullptr), 635 task_runner_(nullptr),
625 weak_factory_(this) { 636 weak_factory_(this) {
626 DCHECK(transport_security_state_); 637 DCHECK(transport_security_state_);
627 DCHECK(http_server_properties_); 638 DCHECK(http_server_properties_);
628 crypto_config_.set_user_agent_id(user_agent_id); 639 crypto_config_.set_user_agent_id(user_agent_id);
629 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); 640 crypto_config_.AddCanonicalSuffix(".c.youtube.com");
630 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); 641 crypto_config_.AddCanonicalSuffix(".googlevideo.com");
(...skipping 18 matching lines...) Expand all
649 if (!IsEcdsaSupported()) 660 if (!IsEcdsaSupported())
650 crypto_config_.DisableEcdsa(); 661 crypto_config_.DisableEcdsa();
651 // When disk cache is used to store the server configs, HttpCache code calls 662 // When disk cache is used to store the server configs, HttpCache code calls
652 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't 663 // |set_quic_server_info_factory| if |quic_server_info_factory_| wasn't
653 // created. 664 // created.
654 if (store_server_configs_in_properties_) { 665 if (store_server_configs_in_properties_) {
655 quic_server_info_factory_.reset( 666 quic_server_info_factory_.reset(
656 new PropertiesBasedQuicServerInfoFactory(http_server_properties_)); 667 new PropertiesBasedQuicServerInfoFactory(http_server_properties_));
657 } 668 }
658 669
659 if (close_sessions_on_ip_change_) { 670 if (migrate_sessions_on_network_change_ &&
671 NetworkChangeNotifier::AreNetworkHandlesSupported()) {
Ryan Hamilton 2015/12/18 21:51:23 This is basically Android only currently?
Jana 2015/12/21 23:10:19 Yes, Android >= L
672 NetworkChangeNotifier::AddNetworkObserver(this);
673 } else if (close_sessions_on_ip_change_) {
660 NetworkChangeNotifier::AddIPAddressObserver(this); 674 NetworkChangeNotifier::AddIPAddressObserver(this);
661 } 675 }
662 } 676 }
663 677
664 QuicStreamFactory::~QuicStreamFactory() { 678 QuicStreamFactory::~QuicStreamFactory() {
665 CloseAllSessions(ERR_ABORTED); 679 CloseAllSessions(ERR_ABORTED);
666 while (!all_sessions_.empty()) { 680 while (!all_sessions_.empty()) {
667 delete all_sessions_.begin()->first; 681 delete all_sessions_.begin()->first;
668 all_sessions_.erase(all_sessions_.begin()); 682 all_sessions_.erase(all_sessions_.begin());
669 } 683 }
670 while (!active_jobs_.empty()) { 684 while (!active_jobs_.empty()) {
671 const QuicServerId server_id = active_jobs_.begin()->first; 685 const QuicServerId server_id = active_jobs_.begin()->first;
672 STLDeleteElements(&(active_jobs_[server_id])); 686 STLDeleteElements(&(active_jobs_[server_id]));
673 active_jobs_.erase(server_id); 687 active_jobs_.erase(server_id);
674 } 688 }
675 if (close_sessions_on_ip_change_) { 689 if (migrate_sessions_on_network_change_ &&
690 NetworkChangeNotifier::AreNetworkHandlesSupported()) {
691 NetworkChangeNotifier::RemoveNetworkObserver(this);
692 } else if (close_sessions_on_ip_change_) {
676 NetworkChangeNotifier::RemoveIPAddressObserver(this); 693 NetworkChangeNotifier::RemoveIPAddressObserver(this);
677 } 694 }
678 } 695 }
679 696
680 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { 697 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) {
681 require_confirmation_ = require_confirmation; 698 require_confirmation_ = require_confirmation;
682 if (!(local_address_ == IPEndPoint())) { 699 if (!(local_address_ == IPEndPoint())) {
683 http_server_properties_->SetSupportsQuic(!require_confirmation, 700 http_server_properties_->SetSupportsQuic(!require_confirmation,
684 local_address_.address()); 701 local_address_.address());
685 } 702 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 DCHECK_EQ(ERR_IO_PENDING, rv); 1108 DCHECK_EQ(ERR_IO_PENDING, rv);
1092 } 1109 }
1093 1110
1094 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { 1111 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
1095 DCHECK(ContainsKey(active_requests_, request)); 1112 DCHECK(ContainsKey(active_requests_, request));
1096 QuicServerId server_id = active_requests_[request]; 1113 QuicServerId server_id = active_requests_[request];
1097 job_requests_map_[server_id].erase(request); 1114 job_requests_map_[server_id].erase(request);
1098 active_requests_.erase(request); 1115 active_requests_.erase(request);
1099 } 1116 }
1100 1117
1101 void QuicStreamFactory::CloseAllSessions(int error) { 1118 void QuicStreamFactory::CloseAllSessions(int error) {
Ryan Hamilton 2015/12/18 21:51:23 I'd be inclined to remove this method and just use
Jana 2015/12/21 23:10:19 Done.
1119 CloseAllSessionsInner(error, QUIC_INTERNAL_ERROR);
1120 }
1121
1122 void QuicStreamFactory::CloseAllSessionsInner(int error,
1123 QuicErrorCode quic_error) {
1102 while (!active_sessions_.empty()) { 1124 while (!active_sessions_.empty()) {
1103 size_t initial_size = active_sessions_.size(); 1125 size_t initial_size = active_sessions_.size();
1104 active_sessions_.begin()->second->CloseSessionOnError(error, 1126 active_sessions_.begin()->second->CloseSessionOnError(error, quic_error);
1105 QUIC_INTERNAL_ERROR);
1106 DCHECK_NE(initial_size, active_sessions_.size()); 1127 DCHECK_NE(initial_size, active_sessions_.size());
1107 } 1128 }
1108 while (!all_sessions_.empty()) { 1129 while (!all_sessions_.empty()) {
1109 size_t initial_size = all_sessions_.size(); 1130 size_t initial_size = all_sessions_.size();
1110 all_sessions_.begin()->first->CloseSessionOnError(error, 1131 all_sessions_.begin()->first->CloseSessionOnError(error, quic_error);
1111 QUIC_INTERNAL_ERROR);
1112 DCHECK_NE(initial_size, all_sessions_.size()); 1132 DCHECK_NE(initial_size, all_sessions_.size());
1113 } 1133 }
1114 DCHECK(all_sessions_.empty()); 1134 DCHECK(all_sessions_.empty());
1115 } 1135 }
1116 1136
1117 scoped_ptr<base::Value> QuicStreamFactory::QuicStreamFactoryInfoToValue() 1137 scoped_ptr<base::Value> QuicStreamFactory::QuicStreamFactoryInfoToValue()
1118 const { 1138 const {
1119 scoped_ptr<base::ListValue> list(new base::ListValue()); 1139 scoped_ptr<base::ListValue> list(new base::ListValue());
1120 1140
1121 for (SessionMap::const_iterator it = active_sessions_.begin(); 1141 for (SessionMap::const_iterator it = active_sessions_.begin();
(...skipping 12 matching lines...) Expand all
1134 } 1154 }
1135 } 1155 }
1136 return list.Pass(); 1156 return list.Pass();
1137 } 1157 }
1138 1158
1139 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() { 1159 void QuicStreamFactory::ClearCachedStatesInCryptoConfig() {
1140 crypto_config_.ClearCachedStates(); 1160 crypto_config_.ClearCachedStates();
1141 } 1161 }
1142 1162
1143 void QuicStreamFactory::OnIPAddressChanged() { 1163 void QuicStreamFactory::OnIPAddressChanged() {
1144 CloseAllSessions(ERR_NETWORK_CHANGED); 1164 CloseAllSessionsInner(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED);
1145 set_require_confirmation(true); 1165 set_require_confirmation(true);
1146 } 1166 }
1147 1167
1168 void QuicStreamFactory::OnNetworkConnected(
1169 NetworkChangeNotifier::NetworkHandle network) {}
1170
1171 void QuicStreamFactory::OnNetworkMadeDefault(
1172 NetworkChangeNotifier::NetworkHandle network) {}
1173
1174 void QuicStreamFactory::OnNetworkDisconnected(
1175 NetworkChangeNotifier::NetworkHandle network) {
1176 MigrateOrCloseSessions(network);
1177 set_require_confirmation(true);
1178 }
1179
1180 void QuicStreamFactory::OnNetworkSoonToDisconnect(
1181 NetworkChangeNotifier::NetworkHandle network) {
1182 MigrateOrCloseSessions(network);
1183 }
1184
1185 void QuicStreamFactory::MigrateOrCloseSessions(
1186 NetworkChangeNotifier::NetworkHandle network) {
1187 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network);
1188 // Find a new network that old sockets can be migrated to.
Ryan Hamilton 2015/12/18 21:51:23 nit: s/sockets/connections/?
Jana 2015/12/21 23:10:19 Done.
1189 NetworkChangeNotifier::NetworkList network_list;
1190 NetworkChangeNotifier::GetConnectedNetworks(&network_list);
1191 NetworkChangeNotifier::NetworkHandle new_network =
1192 NetworkChangeNotifier::kInvalidNetworkHandle;
1193 for (NetworkChangeNotifier::NetworkHandle n : network_list) {
1194 if (n == network) {
1195 continue;
1196 }
1197 new_network = n;
Ryan Hamilton 2015/12/18 21:51:23 Can you break; here? for (...) { if (n != netwo
Jana 2015/12/21 23:10:19 Done.
1198 }
1199
1200 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) {
1201 CloseAllSessionsInner(ERR_NETWORK_CHANGED,
1202 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
Ryan Hamilton 2015/12/18 21:51:23 It seems sad to do this in the "SoonToDisconnect"
Jana 2015/12/21 23:10:19 Yes, it is a bit aggressive. I had two reasons for
1203 return;
1204 }
1205
1206 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin();
1207 while (it != all_sessions_.end()) {
1208 QuicChromiumClientSession* session = it->first;
1209 QuicServerId server_id = it->second;
1210 ++it;
1211
1212 if (session->GetNumActiveStreams() == 0) {
Ryan Hamilton 2015/12/18 21:51:23 Ah, that's why you were needing this method.
Jana 2015/12/21 23:10:19 Acknowledged.
1213 // Close idle sessions.
1214 session->CloseSessionOnError(
1215 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS);
1216 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
1217 MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
1218 MIGRATION_STATUS_MAX);
Ryan Hamilton 2015/12/18 21:51:23 Please factor this out into a helper method which
Jana 2015/12/21 23:10:19 I thought of doing this too simply to reduce clutt
Jana 2015/12/21 23:10:19 Done.
1219 continue;
1220 } else if (session->GetDefaultSocket()->GetBoundNetwork() == new_network) {
1221 // If session is already using |network|, move on.
1222 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
1223 MIGRATION_STATUS_ALREADY_MIGRATED,
1224 MIGRATION_STATUS_MAX);
1225 continue;
1226 }
1227
1228 // If session has active streams, (i) make the session GO_AWAY,
1229 // (ii) create a new socket bound to the new network, and (iii)
1230 // migrate the session to using the new socket.
1231 OnSessionGoingAway(session);
1232 QuicConnection* connection = session->connection();
1233
1234 // Use OS-specified port for socket (DEFAULT_BIND) since the connection is
1235 // being migrated and not being newly created.
Ryan Hamilton 2015/12/18 21:51:23 I don't understand this comment.
Jana 2015/12/21 23:10:19 The point of the PortSuggester, AIUI, is to use a
1236 scoped_ptr<DatagramClientSocket> socket(
1237 client_socket_factory_->CreateDatagramClientSocket(
1238 DatagramSocket::DEFAULT_BIND, RandIntCallback(),
1239 session->net_log().net_log(), session->net_log().source()));
1240
1241 if (ConfigureDatagramClientSocket(socket.get(), connection->peer_address(),
1242 network) != OK) {
1243 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR);
1244 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
1245 MIGRATION_STATUS_INTERNAL_ERROR,
1246 MIGRATION_STATUS_MAX);
1247 continue;
1248 }
1249 scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader(
1250 socket.get(), clock_.get(), session, yield_after_packets_,
1251 yield_after_duration_, session->net_log()));
1252 DefaultPacketWriterFactory packet_writer_factory(socket.get());
1253 scoped_ptr<QuicPacketWriter> new_writer(
1254 packet_writer_factory.Create(connection));
1255
1256 if (!session->MigrateToSocket(socket.Pass(), new_reader.Pass(),
1257 new_writer.Pass())) {
1258 session->CloseSessionOnError(ERR_NETWORK_CHANGED,
1259 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES);
1260 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
1261 MIGRATION_STATUS_TOO_MANY_CHANGES,
1262 MIGRATION_STATUS_MAX);
1263 } else {
1264 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
1265 MIGRATION_STATUS_SUCCESS, MIGRATION_STATUS_MAX);
1266 }
1267 }
1268 }
1269
1148 void QuicStreamFactory::OnSSLConfigChanged() { 1270 void QuicStreamFactory::OnSSLConfigChanged() {
1149 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); 1271 CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
1150 } 1272 }
1151 1273
1152 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { 1274 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) {
1153 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); 1275 CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
1154 } 1276 }
1155 1277
1156 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { 1278 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) {
1157 // We should flush the sessions if we removed trust from a 1279 // We should flush the sessions if we removed trust from a
(...skipping 13 matching lines...) Expand all
1171 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. 1293 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check.
1172 if (active_sessions_.empty()) 1294 if (active_sessions_.empty())
1173 return false; 1295 return false;
1174 return ContainsKey(active_sessions_, server_id); 1296 return ContainsKey(active_sessions_, server_id);
1175 } 1297 }
1176 1298
1177 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { 1299 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const {
1178 return ContainsKey(active_jobs_, key); 1300 return ContainsKey(active_jobs_, key);
1179 } 1301 }
1180 1302
1181 int QuicStreamFactory::CreateSession(const QuicServerId& server_id, 1303 int QuicStreamFactory::ConfigureDatagramClientSocket(
1182 int cert_verify_flags, 1304 DatagramClientSocket* socket,
1183 scoped_ptr<QuicServerInfo> server_info, 1305 IPEndPoint addr,
1184 const AddressList& address_list, 1306 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 &&
1190 ContainsKey(gone_away_aliases_, server_id)) {
1191 // Disable port selection when the server is going away.
1192 // There is no point in trying to return to the same server, if
1193 // that server is no longer handling requests.
1194 enable_port_selection = false;
1195 gone_away_aliases_.erase(server_id);
1196 }
1197
1198 QuicConnectionId connection_id = random_generator_->RandUint64();
1199 IPEndPoint addr = *address_list.begin();
1200 scoped_refptr<PortSuggester> port_suggester =
1201 new PortSuggester(server_id.host_port_pair(), port_seed_);
1202 DatagramSocket::BindType bind_type = enable_port_selection ?
1203 DatagramSocket::RANDOM_BIND : // Use our callback.
1204 DatagramSocket::DEFAULT_BIND; // Use OS to randomize.
1205 scoped_ptr<DatagramClientSocket> socket(
1206 client_socket_factory_->CreateDatagramClientSocket(
1207 bind_type,
1208 base::Bind(&PortSuggester::SuggestPort, port_suggester),
1209 net_log.net_log(), net_log.source()));
1210
1211 if (enable_non_blocking_io_ && 1307 if (enable_non_blocking_io_ &&
1212 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { 1308 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) {
1213 #if defined(OS_WIN) 1309 #if defined(OS_WIN)
1214 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO(); 1310 static_cast<UDPClientSocket*>(socket.get())->UseNonBlockingIO();
1215 #endif 1311 #endif
1216 } 1312 }
1217 1313
1218 int rv = socket->Connect(addr); 1314 // If caller leaves network unspecified, use current default.
1315 int rv;
1316 if (network == NetworkChangeNotifier::kInvalidNetworkHandle) {
1317 rv = socket->BindToDefaultNetwork();
Ryan Hamilton 2015/12/18 21:51:23 Does this represent a behavior change? Is "BindToD
Jana 2015/12/21 23:10:19 Yes. This is a behavior change in that there was n
Ryan Hamilton 2015/12/21 23:18:19 I guess it probably doesn't matter, but I wonder i
1318 } else {
1319 rv = socket->BindToNetwork(network);
1320 }
1321 if (rv != OK) {
1322 return rv;
1323 }
Ryan Hamilton 2015/12/18 21:51:23 nit: no {}s
Jana 2015/12/21 23:10:19 I can never keep this together in my mind. Done.
1219 1324
1325 rv = socket->Connect(addr);
1220 if (rv != OK) { 1326 if (rv != OK) {
1221 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET); 1327 HistogramCreateSessionFailure(CREATION_ERROR_CONNECTING_SOCKET);
1222 return rv; 1328 return rv;
1223 } 1329 }
1224 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested",
1225 port_suggester->call_count());
1226 if (enable_port_selection) {
1227 DCHECK_LE(1u, port_suggester->call_count());
1228 } else {
1229 DCHECK_EQ(0u, port_suggester->call_count());
1230 }
1231 1330
1232 rv = socket->SetReceiveBufferSize(socket_receive_buffer_size_); 1331 rv = socket->SetReceiveBufferSize(socket_receive_buffer_size_);
1233 if (rv != OK) { 1332 if (rv != OK) {
1234 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); 1333 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER);
1235 return rv; 1334 return rv;
1236 } 1335 }
1336
1237 // Set a buffer large enough to contain the initial CWND's worth of packet 1337 // Set a buffer large enough to contain the initial CWND's worth of packet
1238 // to work around the problem with CHLO packets being sent out with the 1338 // to work around the problem with CHLO packets being sent out with the
1239 // wrong encryption level, when the send buffer is full. 1339 // wrong encryption level, when the send buffer is full.
1240 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); 1340 rv = socket->SetSendBufferSize(kMaxPacketSize * 20);
1241 if (rv != OK) { 1341 if (rv != OK) {
1242 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER); 1342 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_SEND_BUFFER);
1243 return rv; 1343 return rv;
1244 } 1344 }
1245 1345
1246 socket->GetLocalAddress(&local_address_); 1346 socket->GetLocalAddress(&local_address_);
1247 if (check_persisted_supports_quic_) { 1347 if (check_persisted_supports_quic_) {
1248 check_persisted_supports_quic_ = false; 1348 check_persisted_supports_quic_ = false;
1249 IPAddressNumber last_address; 1349 IPAddressNumber last_address;
1250 if (http_server_properties_->GetSupportsQuic(&last_address) && 1350 if (http_server_properties_->GetSupportsQuic(&last_address) &&
1251 last_address == local_address_.address()) { 1351 last_address == local_address_.address()) {
1252 require_confirmation_ = false; 1352 require_confirmation_ = false;
1253 } 1353 }
1254 } 1354 }
1255 1355
1356 return OK;
1357 }
1358
1359 int QuicStreamFactory::CreateSession(const QuicServerId& server_id,
1360 int cert_verify_flags,
1361 scoped_ptr<QuicServerInfo> server_info,
1362 const AddressList& address_list,
1363 base::TimeTicks dns_resolution_end_time,
1364 const BoundNetLog& net_log,
1365 QuicChromiumClientSession** session) {
1366 IPEndPoint addr = *address_list.begin();
1367 bool enable_port_selection = enable_port_selection_;
1368 if (enable_port_selection && ContainsKey(gone_away_aliases_, server_id)) {
1369 // Disable port selection when the server is going away.
1370 // There is no point in trying to return to the same server, if
1371 // that server is no longer handling requests.
1372 enable_port_selection = false;
1373 gone_away_aliases_.erase(server_id);
1374 }
1375 scoped_refptr<PortSuggester> port_suggester =
1376 new PortSuggester(server_id.host_port_pair(), port_seed_);
1377 DatagramSocket::BindType bind_type =
1378 enable_port_selection ? DatagramSocket::RANDOM_BIND
1379 : // Use our callback.
1380 DatagramSocket::DEFAULT_BIND; // Use OS to randomize.
1381
1382 scoped_ptr<DatagramClientSocket> socket(
1383 client_socket_factory_->CreateDatagramClientSocket(
1384 bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester),
1385 net_log.net_log(), net_log.source()));
1386
1387 // Passing in kInvalidNetworkHandle binds socket to default network.
1388 int rv = ConfigureDatagramClientSocket(
1389 socket.get(), addr, NetworkChangeNotifier::kInvalidNetworkHandle);
1390 if (rv != OK) {
1391 return rv;
1392 }
1393
1394 UMA_HISTOGRAM_COUNTS("Net.QuicEphemeralPortsSuggested",
1395 port_suggester->call_count());
1396 if (enable_port_selection) {
1397 DCHECK_LE(1u, port_suggester->call_count());
1398 } else {
1399 DCHECK_EQ(0u, port_suggester->call_count());
1400 }
1401
1256 DefaultPacketWriterFactory packet_writer_factory(socket.get()); 1402 DefaultPacketWriterFactory packet_writer_factory(socket.get());
1257
1258 if (!helper_.get()) { 1403 if (!helper_.get()) {
1259 helper_.reset( 1404 helper_.reset(
1260 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(), 1405 new QuicConnectionHelper(base::ThreadTaskRunnerHandle::Get().get(),
1261 clock_.get(), random_generator_)); 1406 clock_.get(), random_generator_));
1262 } 1407 }
1263 1408
1409 QuicConnectionId connection_id = random_generator_->RandUint64();
1264 QuicConnection* connection = new QuicConnection( 1410 QuicConnection* connection = new QuicConnection(
1265 connection_id, addr, helper_.get(), packet_writer_factory, 1411 connection_id, addr, helper_.get(), packet_writer_factory,
1266 true /* owns_writer */, Perspective::IS_CLIENT, supported_versions_); 1412 true /* owns_writer */, Perspective::IS_CLIENT, supported_versions_);
1267 connection->SetMaxPacketLength(max_packet_length_); 1413 connection->SetMaxPacketLength(max_packet_length_);
1268 1414
1269 InitializeCachedStateInCryptoConfig(server_id, server_info); 1415 InitializeCachedStateInCryptoConfig(server_id, server_info);
1270 1416
1271 QuicConfig config = config_; 1417 QuicConfig config = config_;
1272 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_); 1418 config.SetSocketReceiveBufferToSend(socket_receive_buffer_size_);
1273 config.set_max_undecryptable_packets(kMaxUndecryptablePackets); 1419 config.set_max_undecryptable_packets(kMaxUndecryptablePackets);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 // Since the session was active, there's no longer an 1603 // Since the session was active, there's no longer an
1458 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP 1604 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP
1459 // job also fails. So to avoid not using QUIC when we otherwise could, we mark 1605 // job also fails. So to avoid not using QUIC when we otherwise could, we mark
1460 // it as recently broken, which means that 0-RTT will be disabled but we'll 1606 // it as recently broken, which means that 0-RTT will be disabled but we'll
1461 // still race. 1607 // still race.
1462 http_server_properties_->MarkAlternativeServiceRecentlyBroken( 1608 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
1463 alternative_service); 1609 alternative_service);
1464 } 1610 }
1465 1611
1466 } // namespace net 1612 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698