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