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 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 set_require_confirmation(true); | 1176 set_require_confirmation(true); |
1177 } | 1177 } |
1178 | 1178 |
1179 // This method is expected to only be called when migrating from Cellular to | 1179 // This method is expected to only be called when migrating from Cellular to |
1180 // WiFi on Android. | 1180 // WiFi on Android. |
1181 void QuicStreamFactory::OnNetworkSoonToDisconnect( | 1181 void QuicStreamFactory::OnNetworkSoonToDisconnect( |
1182 NetworkChangeNotifier::NetworkHandle network) { | 1182 NetworkChangeNotifier::NetworkHandle network) { |
1183 MaybeMigrateOrCloseSessions(network, /*force_close=*/false); | 1183 MaybeMigrateOrCloseSessions(network, /*force_close=*/false); |
1184 } | 1184 } |
1185 | 1185 |
| 1186 NetworkChangeNotifier::NetworkHandle QuicStreamFactory::FindAlternateNetwork( |
| 1187 NetworkChangeNotifier::NetworkHandle old_network) { |
| 1188 // Find a new network that sessions bound to |old_network| can be migrated to. |
| 1189 NetworkChangeNotifier::NetworkList network_list; |
| 1190 NetworkChangeNotifier::GetConnectedNetworks(&network_list); |
| 1191 for (NetworkChangeNotifier::NetworkHandle new_network : network_list) { |
| 1192 if (new_network != old_network) { |
| 1193 return new_network; |
| 1194 } |
| 1195 } |
| 1196 return NetworkChangeNotifier::kInvalidNetworkHandle; |
| 1197 } |
| 1198 |
1186 void QuicStreamFactory::MaybeMigrateOrCloseSessions( | 1199 void QuicStreamFactory::MaybeMigrateOrCloseSessions( |
1187 NetworkChangeNotifier::NetworkHandle network, | 1200 NetworkChangeNotifier::NetworkHandle network, |
1188 bool force_close) { | 1201 bool force_close) { |
1189 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); | 1202 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); |
1190 | |
1191 // Find a new network that sessions bound to |network| can be migrated to. | |
1192 NetworkChangeNotifier::NetworkList network_list; | |
1193 NetworkChangeNotifier::GetConnectedNetworks(&network_list); | |
1194 NetworkChangeNotifier::NetworkHandle new_network = | 1203 NetworkChangeNotifier::NetworkHandle new_network = |
1195 NetworkChangeNotifier::kInvalidNetworkHandle; | 1204 FindAlternateNetwork(network); |
1196 for (NetworkChangeNotifier::NetworkHandle n : network_list) { | |
1197 if (n != network) { | |
1198 new_network = n; | |
1199 break; | |
1200 } | |
1201 } | |
1202 | 1205 |
1203 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); | 1206 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); |
1204 while (it != all_sessions_.end()) { | 1207 while (it != all_sessions_.end()) { |
1205 QuicChromiumClientSession* session = it->first; | 1208 QuicChromiumClientSession* session = it->first; |
1206 QuicServerId server_id = it->second; | 1209 QuicServerId server_id = it->second; |
1207 ++it; | 1210 ++it; |
1208 | 1211 |
1209 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { | 1212 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { |
1210 // If session is not bound to |network|, move on. | 1213 // If session is not bound to |network|, move on. |
1211 HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED); | 1214 HistogramMigrationStatus(MIGRATION_STATUS_ALREADY_MIGRATED); |
1212 continue; | 1215 continue; |
1213 } | 1216 } |
1214 if (session->GetNumActiveStreams() == 0) { | 1217 if (session->GetNumActiveStreams() == 0) { |
1215 // Close idle sessions. | 1218 // Close idle sessions. |
1216 session->CloseSessionOnError( | 1219 session->CloseSessionOnError( |
1217 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS); | 1220 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS); |
1218 HistogramMigrationStatus(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS); | 1221 HistogramMigrationStatus(MIGRATION_STATUS_NO_MIGRATABLE_STREAMS); |
1219 continue; | 1222 continue; |
1220 } | 1223 } |
1221 // If session has active streams, mark it as going away. | 1224 // If session has active streams, mark it as going away. |
1222 OnSessionGoingAway(session); | 1225 OnSessionGoingAway(session); |
1223 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { | 1226 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
1224 // No new network was found. | 1227 // No new network was found. |
1225 if (force_close) { | 1228 if (force_close) { |
1226 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | 1229 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
1227 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); | 1230 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); |
1228 } | 1231 } |
1229 continue; | 1232 continue; |
1230 } | 1233 } |
1231 | 1234 MigrateSessionToNetwork(session, new_network); |
1232 // Use OS-specified port for socket (DEFAULT_BIND) instead of | |
1233 // using the PortSuggester since the connection is being migrated | |
1234 // and not being newly created. | |
1235 scoped_ptr<DatagramClientSocket> socket( | |
1236 client_socket_factory_->CreateDatagramClientSocket( | |
1237 DatagramSocket::DEFAULT_BIND, RandIntCallback(), | |
1238 session->net_log().net_log(), session->net_log().source())); | |
1239 | |
1240 QuicConnection* connection = session->connection(); | |
1241 if (ConfigureSocket(socket.get(), connection->peer_address(), | |
1242 new_network) != OK) { | |
1243 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | |
1244 HistogramMigrationStatus(MIGRATION_STATUS_INTERNAL_ERROR); | |
1245 continue; | |
1246 } | |
1247 | |
1248 scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader( | |
1249 socket.get(), clock_.get(), session, yield_after_packets_, | |
1250 yield_after_duration_, session->net_log())); | |
1251 scoped_ptr<QuicPacketWriter> new_writer( | |
1252 new QuicDefaultPacketWriter(socket.get())); | |
1253 | |
1254 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), | |
1255 std::move(new_writer))) { | |
1256 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | |
1257 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); | |
1258 HistogramMigrationStatus(MIGRATION_STATUS_TOO_MANY_CHANGES); | |
1259 } else { | |
1260 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); | |
1261 } | |
1262 } | 1235 } |
1263 } | 1236 } |
1264 | 1237 |
| 1238 void QuicStreamFactory::MaybeMigrateSessionEarly( |
| 1239 QuicChromiumClientSession* session) { |
| 1240 if (session->GetNumActiveStreams() == 0) { |
| 1241 return; |
| 1242 } |
| 1243 NetworkChangeNotifier::NetworkHandle current_network = |
| 1244 session->GetDefaultSocket()->GetBoundNetwork(); |
| 1245 NetworkChangeNotifier::NetworkHandle new_network = |
| 1246 FindAlternateNetwork(current_network); |
| 1247 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
| 1248 // No alternate network found. |
| 1249 return; |
| 1250 } |
| 1251 OnSessionGoingAway(session); |
| 1252 MigrateSessionToNetwork(session, new_network); |
| 1253 } |
| 1254 |
| 1255 void QuicStreamFactory::MigrateSessionToNetwork( |
| 1256 QuicChromiumClientSession* session, |
| 1257 NetworkChangeNotifier::NetworkHandle new_network) { |
| 1258 // Use OS-specified port for socket (DEFAULT_BIND) instead of |
| 1259 // using the PortSuggester since the connection is being migrated |
| 1260 // and not being newly created. |
| 1261 scoped_ptr<DatagramClientSocket> socket( |
| 1262 client_socket_factory_->CreateDatagramClientSocket( |
| 1263 DatagramSocket::DEFAULT_BIND, RandIntCallback(), |
| 1264 session->net_log().net_log(), session->net_log().source())); |
| 1265 QuicConnection* connection = session->connection(); |
| 1266 if (ConfigureSocket(socket.get(), connection->peer_address(), new_network) != |
| 1267 OK) { |
| 1268 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); |
| 1269 HistogramMigrationStatus(MIGRATION_STATUS_INTERNAL_ERROR); |
| 1270 return; |
| 1271 } |
| 1272 scoped_ptr<QuicPacketReader> new_reader(new QuicPacketReader( |
| 1273 socket.get(), clock_.get(), session, yield_after_packets_, |
| 1274 yield_after_duration_, session->net_log())); |
| 1275 scoped_ptr<QuicPacketWriter> new_writer( |
| 1276 new QuicDefaultPacketWriter(socket.get())); |
| 1277 |
| 1278 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), |
| 1279 std::move(new_writer))) { |
| 1280 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
| 1281 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); |
| 1282 HistogramMigrationStatus(MIGRATION_STATUS_TOO_MANY_CHANGES); |
| 1283 return; |
| 1284 } |
| 1285 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); |
| 1286 } |
| 1287 |
1265 void QuicStreamFactory::OnSSLConfigChanged() { | 1288 void QuicStreamFactory::OnSSLConfigChanged() { |
1266 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); | 1289 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); |
1267 } | 1290 } |
1268 | 1291 |
1269 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 1292 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
1270 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); | 1293 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_INTERNAL_ERROR); |
1271 } | 1294 } |
1272 | 1295 |
1273 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { | 1296 void QuicStreamFactory::OnCACertChanged(const X509Certificate* cert) { |
1274 // We should flush the sessions if we removed trust from a | 1297 // We should flush the sessions if we removed trust from a |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 // Since the session was active, there's no longer an | 1621 // Since the session was active, there's no longer an |
1599 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1622 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
1600 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1623 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
1601 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1624 // it as recently broken, which means that 0-RTT will be disabled but we'll |
1602 // still race. | 1625 // still race. |
1603 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1626 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
1604 alternative_service); | 1627 alternative_service); |
1605 } | 1628 } |
1606 | 1629 |
1607 } // namespace net | 1630 } // namespace net |
OLD | NEW |