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 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 session->connection_id(), "Non-migratable stream"); | 1542 session->connection_id(), "Non-migratable stream"); |
1543 if (close_if_cannot_migrate) { | 1543 if (close_if_cannot_migrate) { |
1544 session->CloseSessionOnError( | 1544 session->CloseSessionOnError( |
1545 ERR_NETWORK_CHANGED, | 1545 ERR_NETWORK_CHANGED, |
1546 QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM); | 1546 QUIC_CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM); |
1547 } | 1547 } |
1548 continue; | 1548 continue; |
1549 } | 1549 } |
1550 | 1550 |
1551 MigrateSessionToNewNetwork(session, new_network, | 1551 MigrateSessionToNewNetwork(session, new_network, |
1552 /*close_session_on_error=*/true, bound_net_log, | 1552 /*close_session_on_error=*/true, bound_net_log); |
1553 nullptr); | |
1554 } | 1553 } |
1555 } | 1554 } |
1556 | 1555 |
1557 void QuicStreamFactory::MaybeMigrateSingleSession( | 1556 MigrationResult QuicStreamFactory::MaybeMigrateSingleSession( |
1558 QuicChromiumClientSession* session, | 1557 QuicChromiumClientSession* session, |
1559 MigrationCause migration_cause, | 1558 MigrationCause migration_cause) { |
1560 scoped_refptr<StringIOBuffer> packet) { | |
1561 ScopedConnectionMigrationEventLog scoped_event_log( | 1559 ScopedConnectionMigrationEventLog scoped_event_log( |
1562 net_log_, | 1560 net_log_, |
1563 migration_cause == EARLY_MIGRATION ? "EarlyMigration" : "WriteError"); | 1561 migration_cause == EARLY_MIGRATION ? "EarlyMigration" : "WriteError"); |
1564 if (!migrate_sessions_on_network_change_ || | 1562 if (!migrate_sessions_on_network_change_ || |
1565 (migration_cause == EARLY_MIGRATION && !migrate_sessions_early_) || | 1563 (migration_cause == EARLY_MIGRATION && !migrate_sessions_early_) || |
1566 session->HasNonMigratableStreams() || | 1564 session->HasNonMigratableStreams() || |
1567 session->config()->DisableConnectionMigration()) { | 1565 session->config()->DisableConnectionMigration()) { |
1568 HistogramAndLogMigrationFailure( | 1566 HistogramAndLogMigrationFailure( |
1569 scoped_event_log.net_log(), MIGRATION_STATUS_DISABLED, | 1567 scoped_event_log.net_log(), MIGRATION_STATUS_DISABLED, |
1570 session->connection_id(), "Migration disabled"); | 1568 session->connection_id(), "Migration disabled"); |
1571 return; | 1569 return MigrationResult::FAILURE; |
1572 } | 1570 } |
1573 NetworkHandle new_network = | 1571 NetworkHandle new_network = |
1574 FindAlternateNetwork(session->GetDefaultSocket()->GetBoundNetwork()); | 1572 FindAlternateNetwork(session->GetDefaultSocket()->GetBoundNetwork()); |
1575 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { | 1573 if (new_network == NetworkChangeNotifier::kInvalidNetworkHandle) { |
1576 // No alternate network found. | 1574 // No alternate network found. |
1577 HistogramAndLogMigrationFailure( | 1575 HistogramAndLogMigrationFailure( |
1578 scoped_event_log.net_log(), MIGRATION_STATUS_NO_ALTERNATE_NETWORK, | 1576 scoped_event_log.net_log(), MIGRATION_STATUS_NO_ALTERNATE_NETWORK, |
1579 session->connection_id(), "No alternate network found"); | 1577 session->connection_id(), "No alternate network found"); |
1580 return; | 1578 return MigrationResult::NO_NEW_NETWORK; |
1581 } | 1579 } |
1582 OnSessionGoingAway(session); | 1580 OnSessionGoingAway(session); |
1583 MigrateSessionToNewNetwork(session, new_network, | 1581 return MigrateSessionToNewNetwork(session, new_network, |
1584 migration_cause != WRITE_ERROR, | 1582 migration_cause != WRITE_ERROR, |
1585 scoped_event_log.net_log(), packet); | 1583 scoped_event_log.net_log()); |
1586 } | 1584 } |
1587 | 1585 |
1588 void QuicStreamFactory::MigrateSessionToNewPeerAddress( | 1586 void QuicStreamFactory::MigrateSessionToNewPeerAddress( |
1589 QuicChromiumClientSession* session, | 1587 QuicChromiumClientSession* session, |
1590 IPEndPoint peer_address, | 1588 IPEndPoint peer_address, |
1591 const BoundNetLog& bound_net_log) { | 1589 const BoundNetLog& bound_net_log) { |
1592 if (!allow_server_migration_) | 1590 if (!allow_server_migration_) |
1593 return; | 1591 return; |
1594 | 1592 |
1595 IPEndPoint old_address; | 1593 IPEndPoint old_address; |
1596 session->GetDefaultSocket()->GetPeerAddress(&old_address); | 1594 session->GetDefaultSocket()->GetPeerAddress(&old_address); |
1597 DCHECK_EQ(old_address.GetFamily(), peer_address.GetFamily()); | 1595 DCHECK_EQ(old_address.GetFamily(), peer_address.GetFamily()); |
1598 | 1596 |
1599 // Specifying kInvalidNetworkHandle for the |network| parameter | 1597 // Specifying kInvalidNetworkHandle for the |network| parameter |
1600 // causes the session to use the default network for the new socket. | 1598 // causes the session to use the default network for the new socket. |
1601 MigrateSession(session, peer_address, | 1599 MigrateSessionInner(session, peer_address, |
1602 NetworkChangeNotifier::kInvalidNetworkHandle, | 1600 NetworkChangeNotifier::kInvalidNetworkHandle, |
1603 /*close_session_on_error=*/true, bound_net_log, nullptr); | 1601 /*close_session_on_error=*/true, bound_net_log); |
1604 } | 1602 } |
1605 | 1603 |
1606 void QuicStreamFactory::MigrateSessionToNewNetwork( | 1604 MigrationResult QuicStreamFactory::MigrateSessionToNewNetwork( |
1607 QuicChromiumClientSession* session, | 1605 QuicChromiumClientSession* session, |
1608 NetworkHandle network, | 1606 NetworkHandle network, |
1609 bool close_session_on_error, | 1607 bool close_session_on_error, |
1610 const BoundNetLog& bound_net_log, | 1608 const BoundNetLog& bound_net_log) { |
1611 scoped_refptr<StringIOBuffer> packet) { | 1609 return MigrateSessionInner(session, session->connection()->peer_address(), |
1612 MigrateSession(session, session->connection()->peer_address(), network, | 1610 network, close_session_on_error, bound_net_log); |
1613 close_session_on_error, bound_net_log, packet); | |
1614 } | 1611 } |
1615 | 1612 |
1616 void QuicStreamFactory::MigrateSession(QuicChromiumClientSession* session, | 1613 MigrationResult QuicStreamFactory::MigrateSessionInner( |
1617 IPEndPoint peer_address, | 1614 QuicChromiumClientSession* session, |
1618 NetworkHandle network, | 1615 IPEndPoint peer_address, |
1619 bool close_session_on_error, | 1616 NetworkHandle network, |
1620 const BoundNetLog& bound_net_log, | 1617 bool close_session_on_error, |
1621 scoped_refptr<StringIOBuffer> packet) { | 1618 const BoundNetLog& bound_net_log) { |
1622 // Use OS-specified port for socket (DEFAULT_BIND) instead of | 1619 // Use OS-specified port for socket (DEFAULT_BIND) instead of |
1623 // using the PortSuggester since the connection is being migrated | 1620 // using the PortSuggester since the connection is being migrated |
1624 // and not being newly created. | 1621 // and not being newly created. |
1625 std::unique_ptr<DatagramClientSocket> socket( | 1622 std::unique_ptr<DatagramClientSocket> socket( |
1626 client_socket_factory_->CreateDatagramClientSocket( | 1623 client_socket_factory_->CreateDatagramClientSocket( |
1627 DatagramSocket::DEFAULT_BIND, RandIntCallback(), | 1624 DatagramSocket::DEFAULT_BIND, RandIntCallback(), |
1628 session->net_log().net_log(), session->net_log().source())); | 1625 session->net_log().net_log(), session->net_log().source())); |
1629 if (ConfigureSocket(socket.get(), peer_address, network) != OK) { | 1626 if (ConfigureSocket(socket.get(), peer_address, network) != OK) { |
1630 HistogramAndLogMigrationFailure( | 1627 HistogramAndLogMigrationFailure( |
1631 bound_net_log, MIGRATION_STATUS_INTERNAL_ERROR, | 1628 bound_net_log, MIGRATION_STATUS_INTERNAL_ERROR, |
1632 session->connection_id(), "Socket configuration failed"); | 1629 session->connection_id(), "Socket configuration failed"); |
1633 if (close_session_on_error) { | 1630 if (close_session_on_error) { |
1634 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | 1631 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); |
1635 } | 1632 } |
1636 return; | 1633 return MigrationResult::FAILURE; |
1637 } | 1634 } |
1638 std::unique_ptr<QuicChromiumPacketReader> new_reader( | 1635 std::unique_ptr<QuicChromiumPacketReader> new_reader( |
1639 new QuicChromiumPacketReader(socket.get(), clock_.get(), session, | 1636 new QuicChromiumPacketReader(socket.get(), clock_.get(), session, |
1640 yield_after_packets_, yield_after_duration_, | 1637 yield_after_packets_, yield_after_duration_, |
1641 session->net_log())); | 1638 session->net_log())); |
1642 std::unique_ptr<QuicChromiumPacketWriter> new_writer( | 1639 std::unique_ptr<QuicChromiumPacketWriter> new_writer( |
1643 new QuicChromiumPacketWriter(socket.get())); | 1640 new QuicChromiumPacketWriter(socket.get())); |
1644 new_writer->set_delegate(session); | 1641 new_writer->set_delegate(session); |
1645 | 1642 |
1646 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), | 1643 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), |
1647 std::move(new_writer), packet)) { | 1644 std::move(new_writer))) { |
1648 // TODO(jokulik): It's not clear how we could end up on this code | |
1649 // path. We would theoretically hit this failure if we've | |
1650 // performed too many migrations on this session. However, the | |
1651 // session will be marked as going away after a previous | |
1652 // migration, making subsequent migration impossible. | |
1653 HistogramAndLogMigrationFailure( | 1645 HistogramAndLogMigrationFailure( |
1654 bound_net_log, MIGRATION_STATUS_TOO_MANY_CHANGES, | 1646 bound_net_log, MIGRATION_STATUS_TOO_MANY_CHANGES, |
1655 session->connection_id(), "Too many migrations"); | 1647 session->connection_id(), "Too many migrations"); |
1656 if (close_session_on_error) { | 1648 if (close_session_on_error) { |
1657 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | 1649 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
1658 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); | 1650 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); |
1659 } | 1651 } |
1660 return; | 1652 return MigrationResult::FAILURE; |
1661 } | 1653 } |
1662 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); | 1654 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); |
1663 bound_net_log.AddEvent( | 1655 bound_net_log.AddEvent( |
1664 NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS, | 1656 NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS, |
1665 base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, | 1657 base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, |
1666 session->connection_id())); | 1658 session->connection_id())); |
| 1659 return MigrationResult::SUCCESS; |
1667 } | 1660 } |
1668 | 1661 |
1669 void QuicStreamFactory::OnSSLConfigChanged() { | 1662 void QuicStreamFactory::OnSSLConfigChanged() { |
1670 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); | 1663 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); |
1671 } | 1664 } |
1672 | 1665 |
1673 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 1666 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
1674 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); | 1667 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); |
1675 } | 1668 } |
1676 | 1669 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2057 // Since the session was active, there's no longer an | 2050 // Since the session was active, there's no longer an |
2058 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 2051 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
2059 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 2052 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
2060 // it as recently broken, which means that 0-RTT will be disabled but we'll | 2053 // it as recently broken, which means that 0-RTT will be disabled but we'll |
2061 // still race. | 2054 // still race. |
2062 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 2055 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
2063 alternative_service); | 2056 alternative_service); |
2064 } | 2057 } |
2065 | 2058 |
2066 } // namespace net | 2059 } // namespace net |
OLD | NEW |