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/chromium/quic_stream_factory.h" | 5 #include "net/quic/chromium/quic_stream_factory.h" |
6 | 6 |
7 #include <openssl/aead.h> | 7 #include <openssl/aead.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <tuple> | 10 #include <tuple> |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1447 status_ = OPEN; | 1447 status_ = OPEN; |
1448 CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED); | 1448 CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED); |
1449 set_require_confirmation(true); | 1449 set_require_confirmation(true); |
1450 } | 1450 } |
1451 | 1451 |
1452 void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) { | 1452 void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) { |
1453 num_timeouts_with_open_streams_ = 0; | 1453 num_timeouts_with_open_streams_ = 0; |
1454 status_ = OPEN; | 1454 status_ = OPEN; |
1455 } | 1455 } |
1456 | 1456 |
1457 void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) {} | 1457 void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) { |
1458 ScopedConnectionMigrationEventLog scoped_event_log(net_log_, | |
1459 "OnNetworkMadeDefault"); | |
1460 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); | |
1461 MaybeMigrateOrCloseSessions(network, /*close_if_cannot_migrate=*/false, | |
1462 scoped_event_log.net_log()); | |
1463 set_require_confirmation(true); | |
1464 } | |
1458 | 1465 |
1459 void QuicStreamFactory::OnNetworkDisconnected(NetworkHandle network) { | 1466 void QuicStreamFactory::OnNetworkDisconnected(NetworkHandle network) { |
1460 ScopedConnectionMigrationEventLog scoped_event_log(net_log_, | 1467 ScopedConnectionMigrationEventLog scoped_event_log(net_log_, |
1461 "OnNetworkDisconnected"); | 1468 "OnNetworkDisconnected"); |
1462 MaybeMigrateOrCloseSessions(network, /*force_close=*/true, | 1469 NetworkHandle new_network = FindAlternateNetwork(network); |
1470 MaybeMigrateOrCloseSessions(new_network, /*close_if_cannot_migrate=*/true, | |
1463 scoped_event_log.net_log()); | 1471 scoped_event_log.net_log()); |
1464 set_require_confirmation(true); | |
1465 } | 1472 } |
1466 | 1473 |
1467 // This method is expected to only be called when migrating from Cellular to | 1474 // This method is expected to only be called when migrating from Cellular to |
1468 // WiFi on Android. | 1475 // WiFi on Android, and should always be preceded by OnNetworkMadeDefault(). |
1469 void QuicStreamFactory::OnNetworkSoonToDisconnect(NetworkHandle network) { | 1476 void QuicStreamFactory::OnNetworkSoonToDisconnect(NetworkHandle network) {} |
1470 ScopedConnectionMigrationEventLog scoped_event_log( | |
1471 net_log_, "OnNetworkSoonToDisconnect"); | |
1472 MaybeMigrateOrCloseSessions(network, /*force_close=*/false, | |
1473 scoped_event_log.net_log()); | |
1474 } | |
1475 | 1477 |
1476 NetworkHandle QuicStreamFactory::FindAlternateNetwork( | 1478 NetworkHandle QuicStreamFactory::FindAlternateNetwork( |
1477 NetworkHandle old_network) { | 1479 NetworkHandle old_network) { |
1478 // Find a new network that sessions bound to |old_network| can be migrated to. | 1480 // Find a new network that sessions bound to |old_network| can be migrated to. |
1479 NetworkChangeNotifier::NetworkList network_list; | 1481 NetworkChangeNotifier::NetworkList network_list; |
1480 NetworkChangeNotifier::GetConnectedNetworks(&network_list); | 1482 NetworkChangeNotifier::GetConnectedNetworks(&network_list); |
1481 for (NetworkHandle new_network : network_list) { | 1483 for (NetworkHandle new_network : network_list) { |
1482 if (new_network != old_network) | 1484 if (new_network != old_network) |
1483 return new_network; | 1485 return new_network; |
1484 } | 1486 } |
1485 return NetworkChangeNotifier::kInvalidNetworkHandle; | 1487 return NetworkChangeNotifier::kInvalidNetworkHandle; |
1486 } | 1488 } |
1487 | 1489 |
1488 void QuicStreamFactory::MaybeMigrateOrCloseSessions( | 1490 void QuicStreamFactory::MaybeMigrateOrCloseSessions( |
1489 NetworkHandle network, | 1491 NetworkHandle new_network, |
1490 bool force_close, | 1492 bool close_if_cannot_migrate, |
1491 const BoundNetLog& bound_net_log) { | 1493 const BoundNetLog& bound_net_log) { |
1492 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); | 1494 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); |
1493 NetworkHandle new_network = FindAlternateNetwork(network); | |
1494 | 1495 |
1495 QuicStreamFactory::SessionIdMap::iterator it = all_sessions_.begin(); | 1496 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
1497 // Migration attempted, but no new network was found. Close all sessions. | |
1498 while (it != all_sessions_.end()) { | |
Ryan Hamilton
2016/08/19 22:03:53
nit: instead of having this if(...) clause outside
Jana
2016/08/20 01:48:32
It used to be inside, but I thought it might be cl
| |
1499 QuicChromiumClientSession* session = it->first; | |
1500 ++it; | |
1501 HistogramAndLogMigrationFailure( | |
1502 bound_net_log, MIGRATION_STATUS_NO_ALTERNATE_NETWORK, | |
1503 session->connection_id(), "No alternate network found"); | |
1504 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | |
1505 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); | |
1506 } | |
1507 return; | |
1508 } | |
1509 | |
1496 while (it != all_sessions_.end()) { | 1510 while (it != all_sessions_.end()) { |
1497 QuicChromiumClientSession* session = it->first; | 1511 QuicChromiumClientSession* session = it->first; |
1498 ++it; | 1512 ++it; |
1499 | 1513 |
1500 if (session->GetDefaultSocket()->GetBoundNetwork() != network) { | 1514 // If session is already bound to |new_network|, move on. |
1501 // If session is not bound to |network|, move on. | 1515 if (session->GetDefaultSocket()->GetBoundNetwork() == new_network) { |
1502 HistogramAndLogMigrationFailure( | 1516 HistogramAndLogMigrationFailure( |
1503 bound_net_log, MIGRATION_STATUS_ALREADY_MIGRATED, | 1517 bound_net_log, MIGRATION_STATUS_ALREADY_MIGRATED, |
1504 session->connection_id(), "Not bound to network"); | 1518 session->connection_id(), "Already bound to new network"); |
1505 continue; | 1519 continue; |
1506 } | 1520 } |
1521 | |
1522 // Close idle sessions. | |
1507 if (session->GetNumActiveStreams() == 0) { | 1523 if (session->GetNumActiveStreams() == 0) { |
1508 // Close idle sessions. | |
1509 HistogramAndLogMigrationFailure( | 1524 HistogramAndLogMigrationFailure( |
1510 bound_net_log, MIGRATION_STATUS_NO_MIGRATABLE_STREAMS, | 1525 bound_net_log, MIGRATION_STATUS_NO_MIGRATABLE_STREAMS, |
1511 session->connection_id(), "No active sessions"); | 1526 session->connection_id(), "No active sessions"); |
1512 session->CloseSessionOnError( | 1527 session->CloseSessionOnError( |
1513 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS); | 1528 ERR_NETWORK_CHANGED, QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS); |
1514 continue; | 1529 continue; |
1515 } | 1530 } |
1531 | |
1516 // If session has active streams, mark it as going away. | 1532 // If session has active streams, mark it as going away. |
1517 OnSessionGoingAway(session); | 1533 OnSessionGoingAway(session); |
1518 | 1534 |
1519 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { | 1535 // Do not migrate sessions where connection migration is disabled. |
1520 // No new network was found. | |
1521 // TODO (jri): Add histogram for this failure case. | |
1522 bound_net_log.AddEvent( | |
1523 NetLog::TYPE_QUIC_CONNECTION_MIGRATION_FAILURE, | |
1524 base::Bind(&NetLogQuicConnectionMigrationFailureCallback, | |
1525 session->connection_id(), "No new network")); | |
1526 if (force_close) { | |
1527 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | |
1528 QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK); | |
1529 } | |
1530 continue; | |
1531 } | |
1532 if (session->config()->DisableConnectionMigration()) { | 1536 if (session->config()->DisableConnectionMigration()) { |
1533 // Do not migrate sessions where connection migration is disabled by | |
1534 // config. | |
1535 HistogramAndLogMigrationFailure(bound_net_log, MIGRATION_STATUS_DISABLED, | 1537 HistogramAndLogMigrationFailure(bound_net_log, MIGRATION_STATUS_DISABLED, |
1536 session->connection_id(), | 1538 session->connection_id(), |
1537 "Migration disabled"); | 1539 "Migration disabled"); |
1538 if (force_close) { | 1540 if (close_if_cannot_migrate) { |
1539 // Close sessions where connection migration is disabled. | 1541 // Close sessions where connection migration is disabled. |
Ryan Hamilton
2016/08/19 22:03:53
nit: up to you, but I'd drop this comment and the
Jana
2016/08/20 01:48:32
Done.
| |
1540 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | 1542 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
1541 QUIC_IP_ADDRESS_CHANGED); | 1543 QUIC_IP_ADDRESS_CHANGED); |
1542 } | 1544 } |
1543 continue; | 1545 continue; |
1544 } | 1546 } |
1547 | |
1548 // Do not migrate sessions with non-migratable streams. | |
1545 if (session->HasNonMigratableStreams()) { | 1549 if (session->HasNonMigratableStreams()) { |
1546 // Do not migrate sessions with non-migratable streams. | |
1547 HistogramAndLogMigrationFailure( | 1550 HistogramAndLogMigrationFailure( |
1548 bound_net_log, MIGRATION_STATUS_NON_MIGRATABLE_STREAM, | 1551 bound_net_log, MIGRATION_STATUS_NON_MIGRATABLE_STREAM, |
1549 session->connection_id(), "Non-migratable stream"); | 1552 session->connection_id(), "Non-migratable stream"); |
1550 if (force_close) { | 1553 if (close_if_cannot_migrate) { |
1551 // Close sessions with non-migratable streams. | 1554 // Close sessions with non-migratable streams. |
1552 session->CloseSessionOnError( | 1555 session->CloseSessionOnError( |
1553 ERR_NETWORK_CHANGED, | 1556 ERR_NETWORK_CHANGED, |
1554 QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM); | 1557 QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM); |
1555 } | 1558 } |
1556 continue; | 1559 continue; |
1557 } | 1560 } |
1558 | 1561 |
1559 MigrateSessionToNewNetwork(session, new_network, bound_net_log, nullptr); | 1562 MigrateSessionToNewNetwork(session, new_network, bound_net_log, nullptr); |
1560 } | 1563 } |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2038 // Since the session was active, there's no longer an | 2041 // Since the session was active, there's no longer an |
2039 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 2042 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
2040 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 2043 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
2041 // it as recently broken, which means that 0-RTT will be disabled but we'll | 2044 // it as recently broken, which means that 0-RTT will be disabled but we'll |
2042 // still race. | 2045 // still race. |
2043 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 2046 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
2044 alternative_service); | 2047 alternative_service); |
2045 } | 2048 } |
2046 | 2049 |
2047 } // namespace net | 2050 } // namespace net |
OLD | NEW |