| 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 |