OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |