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, |
Ryan Hamilton
2016/09/10 16:40:34
Seems like it might just be cleaner to have this m
Jana
2016/09/10 23:08:31
Done.
| |
1580 migration_cause != WRITE_ERROR, | 1578 migration_cause != WRITE_ERROR, |
1581 scoped_event_log.net_log(), packet); | 1579 scoped_event_log.net_log()) |
1580 ? MigrationResult::SUCCESS | |
1581 : MigrationResult::FAILURE; | |
1582 } | 1582 } |
1583 | 1583 |
1584 void QuicStreamFactory::MigrateSessionToNewPeerAddress( | 1584 void QuicStreamFactory::MigrateSessionToNewPeerAddress( |
1585 QuicChromiumClientSession* session, | 1585 QuicChromiumClientSession* session, |
1586 IPEndPoint peer_address, | 1586 IPEndPoint peer_address, |
1587 const BoundNetLog& bound_net_log) { | 1587 const BoundNetLog& bound_net_log) { |
1588 if (!allow_server_migration_) | 1588 if (!allow_server_migration_) |
1589 return; | 1589 return; |
1590 | 1590 |
1591 IPEndPoint old_address; | 1591 IPEndPoint old_address; |
1592 session->GetDefaultSocket()->GetPeerAddress(&old_address); | 1592 session->GetDefaultSocket()->GetPeerAddress(&old_address); |
1593 DCHECK_EQ(old_address.GetFamily(), peer_address.GetFamily()); | 1593 DCHECK_EQ(old_address.GetFamily(), peer_address.GetFamily()); |
1594 | 1594 |
1595 // Specifying kInvalidNetworkHandle for the |network| parameter | 1595 // Specifying kInvalidNetworkHandle for the |network| parameter |
1596 // causes the session to use the default network for the new socket. | 1596 // causes the session to use the default network for the new socket. |
1597 MigrateSession(session, peer_address, | 1597 MigrateSessionInner(session, peer_address, |
1598 NetworkChangeNotifier::kInvalidNetworkHandle, | 1598 NetworkChangeNotifier::kInvalidNetworkHandle, |
1599 /*close_session_on_error=*/true, bound_net_log, nullptr); | 1599 /*close_session_on_error=*/true, bound_net_log); |
1600 } | 1600 } |
1601 | 1601 |
1602 void QuicStreamFactory::MigrateSessionToNewNetwork( | 1602 bool QuicStreamFactory::MigrateSessionToNewNetwork( |
1603 QuicChromiumClientSession* session, | 1603 QuicChromiumClientSession* session, |
1604 NetworkHandle network, | 1604 NetworkHandle network, |
1605 bool close_session_on_error, | 1605 bool close_session_on_error, |
1606 const BoundNetLog& bound_net_log, | 1606 const BoundNetLog& bound_net_log) { |
1607 scoped_refptr<StringIOBuffer> packet) { | 1607 return MigrateSessionInner(session, session->connection()->peer_address(), |
1608 MigrateSession(session, session->connection()->peer_address(), network, | 1608 network, close_session_on_error, bound_net_log); |
1609 close_session_on_error, bound_net_log, packet); | |
1610 } | 1609 } |
1611 | 1610 |
1612 void QuicStreamFactory::MigrateSession(QuicChromiumClientSession* session, | 1611 bool QuicStreamFactory::MigrateSessionInner(QuicChromiumClientSession* session, |
1613 IPEndPoint peer_address, | 1612 IPEndPoint peer_address, |
1614 NetworkHandle network, | 1613 NetworkHandle network, |
1615 bool close_session_on_error, | 1614 bool close_session_on_error, |
1616 const BoundNetLog& bound_net_log, | 1615 const BoundNetLog& bound_net_log) { |
1617 scoped_refptr<StringIOBuffer> packet) { | |
1618 // Use OS-specified port for socket (DEFAULT_BIND) instead of | 1616 // Use OS-specified port for socket (DEFAULT_BIND) instead of |
1619 // using the PortSuggester since the connection is being migrated | 1617 // using the PortSuggester since the connection is being migrated |
1620 // and not being newly created. | 1618 // and not being newly created. |
1621 std::unique_ptr<DatagramClientSocket> socket( | 1619 std::unique_ptr<DatagramClientSocket> socket( |
1622 client_socket_factory_->CreateDatagramClientSocket( | 1620 client_socket_factory_->CreateDatagramClientSocket( |
1623 DatagramSocket::DEFAULT_BIND, RandIntCallback(), | 1621 DatagramSocket::DEFAULT_BIND, RandIntCallback(), |
1624 session->net_log().net_log(), session->net_log().source())); | 1622 session->net_log().net_log(), session->net_log().source())); |
1625 if (ConfigureSocket(socket.get(), peer_address, network) != OK) { | 1623 if (ConfigureSocket(socket.get(), peer_address, network) != OK) { |
1626 HistogramAndLogMigrationFailure( | 1624 HistogramAndLogMigrationFailure( |
1627 bound_net_log, MIGRATION_STATUS_INTERNAL_ERROR, | 1625 bound_net_log, MIGRATION_STATUS_INTERNAL_ERROR, |
1628 session->connection_id(), "Socket configuration failed"); | 1626 session->connection_id(), "Socket configuration failed"); |
1629 if (close_session_on_error) { | 1627 if (close_session_on_error) { |
1630 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); | 1628 session->CloseSessionOnError(ERR_NETWORK_CHANGED, QUIC_INTERNAL_ERROR); |
1631 } | 1629 } |
1632 return; | 1630 return false; |
1633 } | 1631 } |
1634 std::unique_ptr<QuicChromiumPacketReader> new_reader( | 1632 std::unique_ptr<QuicChromiumPacketReader> new_reader( |
1635 new QuicChromiumPacketReader(socket.get(), clock_.get(), session, | 1633 new QuicChromiumPacketReader(socket.get(), clock_.get(), session, |
1636 yield_after_packets_, yield_after_duration_, | 1634 yield_after_packets_, yield_after_duration_, |
1637 session->net_log())); | 1635 session->net_log())); |
1638 std::unique_ptr<QuicChromiumPacketWriter> new_writer( | 1636 std::unique_ptr<QuicChromiumPacketWriter> new_writer( |
1639 new QuicChromiumPacketWriter(socket.get())); | 1637 new QuicChromiumPacketWriter(socket.get())); |
1640 new_writer->set_delegate(session); | 1638 new_writer->set_delegate(session); |
1641 | 1639 |
1642 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), | 1640 if (!session->MigrateToSocket(std::move(socket), std::move(new_reader), |
1643 std::move(new_writer), packet)) { | 1641 std::move(new_writer))) { |
1644 // TODO(jokulik): It's not clear how we could end up on this code | 1642 // 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 | 1643 // path. We would theoretically hit this failure if we've |
1646 // performed too many migrations on this session. However, the | 1644 // performed too many migrations on this session. However, the |
1647 // session will be marked as going away after a previous | 1645 // session will be marked as going away after a previous |
1648 // migration, making subsequent migration impossible. | 1646 // migration, making subsequent migration impossible. |
Ryan Hamilton
2016/09/10 16:40:34
This is now reachable because of migration on writ
Jana
2016/09/10 23:08:31
Yes -- comment removed. I had thought at first tha
| |
1649 HistogramAndLogMigrationFailure( | 1647 HistogramAndLogMigrationFailure( |
1650 bound_net_log, MIGRATION_STATUS_TOO_MANY_CHANGES, | 1648 bound_net_log, MIGRATION_STATUS_TOO_MANY_CHANGES, |
1651 session->connection_id(), "Too many migrations"); | 1649 session->connection_id(), "Too many migrations"); |
1652 if (close_session_on_error) { | 1650 if (close_session_on_error) { |
1653 session->CloseSessionOnError(ERR_NETWORK_CHANGED, | 1651 session->CloseSessionOnError(ERR_NETWORK_CHANGED, |
1654 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); | 1652 QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES); |
1655 } | 1653 } |
1656 return; | 1654 return false; |
1657 } | 1655 } |
1658 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); | 1656 HistogramMigrationStatus(MIGRATION_STATUS_SUCCESS); |
1659 bound_net_log.AddEvent( | 1657 bound_net_log.AddEvent( |
1660 NetLog::TYPE_QUIC_CONNECTION_MIGRATION_SUCCESS, | 1658 NetLog::TYPE_QUIC_CONNECTION_MIGRATION_SUCCESS, |
1661 base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, | 1659 base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, |
1662 session->connection_id())); | 1660 session->connection_id())); |
1661 return true; | |
1663 } | 1662 } |
1664 | 1663 |
1665 void QuicStreamFactory::OnSSLConfigChanged() { | 1664 void QuicStreamFactory::OnSSLConfigChanged() { |
1666 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); | 1665 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); |
1667 } | 1666 } |
1668 | 1667 |
1669 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { | 1668 void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) { |
1670 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); | 1669 CloseAllSessions(ERR_CERT_DATABASE_CHANGED, QUIC_CONNECTION_CANCELLED); |
1671 } | 1670 } |
1672 | 1671 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2053 // Since the session was active, there's no longer an | 2052 // Since the session was active, there's no longer an |
2054 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 2053 // 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 | 2054 // 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 | 2055 // it as recently broken, which means that 0-RTT will be disabled but we'll |
2057 // still race. | 2056 // still race. |
2058 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 2057 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
2059 alternative_service); | 2058 alternative_service); |
2060 } | 2059 } |
2061 | 2060 |
2062 } // namespace net | 2061 } // namespace net |
OLD | NEW |