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/tools/quic/quic_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <ostream> | 8 #include <ostream> |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "net/quic/core/crypto/crypto_handshake.h" | 13 #include "net/quic/core/crypto/crypto_handshake.h" |
14 #include "net/quic/core/crypto/quic_crypto_server_config.h" | 14 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
15 #include "net/quic/core/crypto/quic_random.h" | 15 #include "net/quic/core/crypto/quic_random.h" |
16 #include "net/quic/core/quic_crypto_stream.h" | 16 #include "net/quic/core/quic_crypto_stream.h" |
17 #include "net/quic/core/quic_flags.h" | 17 #include "net/quic/core/quic_flags.h" |
18 #include "net/quic/core/quic_utils.h" | 18 #include "net/quic/core/quic_utils.h" |
19 #include "net/quic/test_tools/crypto_test_utils.h" | 19 #include "net/quic/test_tools/crypto_test_utils.h" |
| 20 #include "net/quic/test_tools/fake_proof_source.h" |
20 #include "net/quic/test_tools/quic_buffered_packet_store_peer.h" | 21 #include "net/quic/test_tools/quic_buffered_packet_store_peer.h" |
| 22 #include "net/quic/test_tools/quic_crypto_server_config_peer.h" |
21 #include "net/quic/test_tools/quic_test_utils.h" | 23 #include "net/quic/test_tools/quic_test_utils.h" |
| 24 #include "net/quic/test_tools/quic_time_wait_list_manager_peer.h" |
22 #include "net/test/gtest_util.h" | 25 #include "net/test/gtest_util.h" |
23 #include "net/tools/epoll_server/epoll_server.h" | 26 #include "net/tools/epoll_server/epoll_server.h" |
24 #include "net/tools/quic/chlo_extractor.h" | 27 #include "net/tools/quic/chlo_extractor.h" |
25 #include "net/tools/quic/quic_epoll_alarm_factory.h" | 28 #include "net/tools/quic/quic_epoll_alarm_factory.h" |
26 #include "net/tools/quic/quic_epoll_connection_helper.h" | 29 #include "net/tools/quic/quic_epoll_connection_helper.h" |
27 #include "net/tools/quic/quic_packet_writer_wrapper.h" | 30 #include "net/tools/quic/quic_packet_writer_wrapper.h" |
28 #include "net/tools/quic/quic_simple_crypto_server_stream_helper.h" | 31 #include "net/tools/quic/quic_simple_crypto_server_stream_helper.h" |
29 #include "net/tools/quic/quic_time_wait_list_manager.h" | 32 #include "net/tools/quic/quic_time_wait_list_manager.h" |
30 #include "net/tools/quic/stateless_rejector.h" | 33 #include "net/tools/quic/stateless_rejector.h" |
31 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" | 34 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 "Unregistering."); | 165 "Unregistering."); |
163 } | 166 } |
164 | 167 |
165 private: | 168 private: |
166 QuicDispatcher* dispatcher_; | 169 QuicDispatcher* dispatcher_; |
167 }; | 170 }; |
168 | 171 |
169 class QuicDispatcherTest : public ::testing::Test { | 172 class QuicDispatcherTest : public ::testing::Test { |
170 public: | 173 public: |
171 QuicDispatcherTest() | 174 QuicDispatcherTest() |
| 175 : QuicDispatcherTest(CryptoTestUtils::ProofSourceForTesting()) {} |
| 176 |
| 177 explicit QuicDispatcherTest(std::unique_ptr<ProofSource> proof_source) |
172 : helper_(&eps_, QuicAllocator::BUFFER_POOL), | 178 : helper_(&eps_, QuicAllocator::BUFFER_POOL), |
173 alarm_factory_(&eps_), | 179 alarm_factory_(&eps_), |
174 version_manager_(AllSupportedVersions()), | 180 version_manager_(AllSupportedVersions()), |
175 crypto_config_(QuicCryptoServerConfig::TESTING, | 181 crypto_config_(QuicCryptoServerConfig::TESTING, |
176 QuicRandom::GetInstance(), | 182 QuicRandom::GetInstance(), |
177 CryptoTestUtils::ProofSourceForTesting()), | 183 std::move(proof_source)), |
178 dispatcher_(new TestDispatcher(config_, | 184 dispatcher_(new TestDispatcher(config_, |
179 &crypto_config_, | 185 &crypto_config_, |
180 &version_manager_, | 186 &version_manager_, |
181 &eps_)), | 187 &eps_)), |
182 time_wait_list_manager_(nullptr), | 188 time_wait_list_manager_(nullptr), |
183 session1_(nullptr), | 189 session1_(nullptr), |
184 session2_(nullptr), | 190 session2_(nullptr), |
185 store_(nullptr) {} | 191 store_(nullptr) {} |
186 | 192 |
187 void SetUp() override { | 193 void SetUp() override { |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 // Reset session creation counter to ensure processing CHLO can always | 1217 // Reset session creation counter to ensure processing CHLO can always |
1212 // create session. | 1218 // create session. |
1213 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(), | 1219 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(), |
1214 kNumConnections); | 1220 kNumConnections); |
1215 // Process CHLOs to create session for these connections. | 1221 // Process CHLOs to create session for these connections. |
1216 for (size_t i = 1; i <= kNumConnections; ++i) { | 1222 for (size_t i = 1; i <= kNumConnections; ++i) { |
1217 IPEndPoint client_address(Loopback4(), i); | 1223 IPEndPoint client_address(Loopback4(), i); |
1218 QuicConnectionId conn_id = i; | 1224 QuicConnectionId conn_id = i; |
1219 if (FLAGS_quic_create_session_after_insertion && | 1225 if (FLAGS_quic_create_session_after_insertion && |
1220 conn_id == kNumConnections) { | 1226 conn_id == kNumConnections) { |
| 1227 // The last CHLO should trigger ShouldCreateOrBufferPacketForConnection() |
| 1228 // since it's the |
| 1229 // first packet arrives on that connection. |
1221 EXPECT_CALL(*dispatcher_, | 1230 EXPECT_CALL(*dispatcher_, |
1222 ShouldCreateOrBufferPacketForConnection(conn_id)); | 1231 ShouldCreateOrBufferPacketForConnection(conn_id)); |
1223 } | 1232 } |
1224 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) | 1233 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
1225 .WillOnce(testing::Return(CreateSession( | 1234 .WillOnce(testing::Return(CreateSession( |
1226 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, | 1235 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
1227 &mock_alarm_factory_, &crypto_config_, | 1236 &mock_alarm_factory_, &crypto_config_, |
1228 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1237 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
1229 if (!FLAGS_quic_create_session_after_insertion && | 1238 if (!FLAGS_quic_create_session_after_insertion && |
1230 conn_id == kNumConnections) { | 1239 conn_id == kNumConnections) { |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); | 1533 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
1525 } | 1534 } |
1526 EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1)); | 1535 EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1)); |
1527 | 1536 |
1528 // CHLO on connection 1 should still be buffered. | 1537 // CHLO on connection 1 should still be buffered. |
1529 ProcessPacket(client_addr_, /*connection_id=*/1, true, false, | 1538 ProcessPacket(client_addr_, /*connection_id=*/1, true, false, |
1530 SerializeFullCHLO()); | 1539 SerializeFullCHLO()); |
1531 EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); | 1540 EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); |
1532 } | 1541 } |
1533 | 1542 |
| 1543 // Test which exercises the async GetProof codepaths, especially in the context |
| 1544 // of stateless rejection. |
| 1545 class AsyncGetProofTest : public QuicDispatcherTest { |
| 1546 public: |
| 1547 AsyncGetProofTest() |
| 1548 : QuicDispatcherTest( |
| 1549 std::unique_ptr<FakeProofSource>(new FakeProofSource())), |
| 1550 client_addr_(net::test::Loopback4(), 1234), |
| 1551 crypto_config_peer_(&crypto_config_) { |
| 1552 FLAGS_enable_async_get_proof = true; |
| 1553 FLAGS_quic_buffer_packet_till_chlo = true; |
| 1554 FLAGS_enable_quic_stateless_reject_support = true; |
| 1555 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 1556 FLAGS_quic_create_session_after_insertion = true; |
| 1557 } |
| 1558 |
| 1559 void SetUp() override { |
| 1560 QuicDispatcherTest::SetUp(); |
| 1561 |
| 1562 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock(); |
| 1563 QuicVersion version = AllSupportedVersions().front(); |
| 1564 chlo_ = CryptoTestUtils::GenerateDefaultInchoateCHLO(clock_, version, |
| 1565 &crypto_config_); |
| 1566 chlo_.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ}); |
| 1567 // Pass an inchoate CHLO. |
| 1568 CryptoTestUtils::GenerateFullCHLO( |
| 1569 chlo_, &crypto_config_, server_ip_, client_addr_, version, clock_, |
| 1570 &proof_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &full_chlo_); |
| 1571 |
| 1572 GetFakeProofSource()->Activate(); |
| 1573 } |
| 1574 |
| 1575 FakeProofSource* GetFakeProofSource() const { |
| 1576 return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource()); |
| 1577 } |
| 1578 |
| 1579 string SerializeFullCHLO() { |
| 1580 return full_chlo_.GetSerialized().AsStringPiece().as_string(); |
| 1581 } |
| 1582 |
| 1583 string SerializeCHLO() { |
| 1584 return chlo_.GetSerialized().AsStringPiece().as_string(); |
| 1585 } |
| 1586 |
| 1587 // Sets up a session, and crypto stream based on the test parameters. |
| 1588 QuicServerSessionBase* GetSession(QuicConnectionId connection_id) { |
| 1589 auto it = sessions_.find(connection_id); |
| 1590 if (it != sessions_.end()) { |
| 1591 return it->second.session; |
| 1592 } |
| 1593 |
| 1594 TestQuicSpdyServerSession* session; |
| 1595 CreateSession(dispatcher_.get(), config_, connection_id, client_addr_, |
| 1596 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
| 1597 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session); |
| 1598 |
| 1599 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream( |
| 1600 new MockQuicCryptoServerStream( |
| 1601 crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), |
| 1602 session, session->stream_helper())); |
| 1603 session->SetCryptoStream(crypto_stream.get()); |
| 1604 crypto_stream->SetPeerSupportsStatelessRejects(true); |
| 1605 const bool ok = |
| 1606 sessions_ |
| 1607 .insert(std::make_pair( |
| 1608 connection_id, SessionInfo{session, std::move(crypto_stream)})) |
| 1609 .second; |
| 1610 CHECK(ok); |
| 1611 return session; |
| 1612 } |
| 1613 |
| 1614 protected: |
| 1615 const IPEndPoint client_addr_; |
| 1616 |
| 1617 private: |
| 1618 QuicCryptoServerConfigPeer crypto_config_peer_; |
| 1619 IPAddress server_ip_; |
| 1620 QuicCryptoProof proof_; |
| 1621 const QuicClock* clock_; |
| 1622 CryptoHandshakeMessage chlo_; |
| 1623 CryptoHandshakeMessage full_chlo_; |
| 1624 |
| 1625 struct SessionInfo { |
| 1626 TestQuicSpdyServerSession* session; |
| 1627 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream; |
| 1628 }; |
| 1629 std::map<QuicConnectionId, SessionInfo> sessions_; |
| 1630 }; |
| 1631 |
| 1632 // Test a simple situation of connections which the StatelessRejector will |
| 1633 // accept. |
| 1634 TEST_F(AsyncGetProofTest, BasicAccept) { |
| 1635 QuicConnectionId conn_id = 1; |
| 1636 |
| 1637 testing::MockFunction<void(int check_point)> check; |
| 1638 { |
| 1639 InSequence s; |
| 1640 |
| 1641 EXPECT_CALL(check, Call(1)); |
| 1642 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1643 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1644 .WillOnce(testing::Return(GetSession(conn_id))); |
| 1645 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1646 GetSession(conn_id)->connection()), |
| 1647 ProcessUdpPacket(_, _, _)) |
| 1648 .WillOnce(testing::WithArg<2>( |
| 1649 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1650 base::Unretained(this), conn_id)))); |
| 1651 |
| 1652 EXPECT_CALL(check, Call(2)); |
| 1653 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1654 GetSession(conn_id)->connection()), |
| 1655 ProcessUdpPacket(_, _, _)) |
| 1656 .WillOnce(testing::WithArg<2>( |
| 1657 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1658 base::Unretained(this), conn_id)))); |
| 1659 } |
| 1660 |
| 1661 // Send a CHLO that the StatelessRejector will accept. |
| 1662 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1663 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1664 |
| 1665 check.Call(1); |
| 1666 // Complete the ProofSource::GetProof call and verify that a session is |
| 1667 // created. |
| 1668 GetFakeProofSource()->InvokePendingCallback(0); |
| 1669 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1670 |
| 1671 check.Call(2); |
| 1672 // Verify that a data packet gets processed immediately. |
| 1673 ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); |
| 1674 } |
| 1675 |
| 1676 // Test a simple situation of connections which the StatelessRejector will |
| 1677 // reject. |
| 1678 TEST_F(AsyncGetProofTest, BasicReject) { |
| 1679 CreateTimeWaitListManager(); |
| 1680 |
| 1681 QuicConnectionId conn_id = 1; |
| 1682 |
| 1683 testing::MockFunction<void(int check_point)> check; |
| 1684 { |
| 1685 InSequence s; |
| 1686 EXPECT_CALL(check, Call(1)); |
| 1687 EXPECT_CALL(*time_wait_list_manager_, |
| 1688 AddConnectionIdToTimeWait(conn_id, _, true, _)); |
| 1689 EXPECT_CALL(*time_wait_list_manager_, |
| 1690 ProcessPacket(_, client_addr_, conn_id, _, _)); |
| 1691 |
| 1692 EXPECT_CALL(check, Call(2)); |
| 1693 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1694 .Times(0); |
| 1695 EXPECT_CALL(*time_wait_list_manager_, |
| 1696 ProcessPacket(_, client_addr_, conn_id, _, _)); |
| 1697 } |
| 1698 |
| 1699 // Send a CHLO that the StatelessRejector will reject. |
| 1700 ProcessPacket(client_addr_, conn_id, true, false, SerializeCHLO()); |
| 1701 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1702 |
| 1703 // Complete the ProofSource::GetProof call and verify that the connection and |
| 1704 // packet are processed by the time wait list manager. |
| 1705 check.Call(1); |
| 1706 GetFakeProofSource()->InvokePendingCallback(0); |
| 1707 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1708 |
| 1709 // Verify that a data packet is passed to the time wait list manager. |
| 1710 check.Call(2); |
| 1711 ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); |
| 1712 } |
| 1713 |
| 1714 // Test a situation with multiple interleaved connections which the |
| 1715 // StatelessRejector will accept. |
| 1716 TEST_F(AsyncGetProofTest, MultipleAccept) { |
| 1717 QuicConnectionId conn_id_1 = 1; |
| 1718 QuicConnectionId conn_id_2 = 2; |
| 1719 QuicBufferedPacketStore* store = |
| 1720 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1721 |
| 1722 testing::MockFunction<void(int check_point)> check; |
| 1723 { |
| 1724 InSequence s; |
| 1725 EXPECT_CALL(check, Call(1)); |
| 1726 EXPECT_CALL(*dispatcher_, |
| 1727 ShouldCreateOrBufferPacketForConnection(conn_id_2)); |
| 1728 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_)) |
| 1729 .WillOnce(testing::Return(GetSession(conn_id_2))); |
| 1730 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1731 GetSession(conn_id_2)->connection()), |
| 1732 ProcessUdpPacket(_, _, _)) |
| 1733 .WillOnce(testing::WithArg<2>( |
| 1734 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1735 base::Unretained(this), conn_id_2)))); |
| 1736 |
| 1737 EXPECT_CALL(check, Call(2)); |
| 1738 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1739 GetSession(conn_id_2)->connection()), |
| 1740 ProcessUdpPacket(_, _, _)) |
| 1741 .WillOnce(testing::WithArg<2>( |
| 1742 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1743 base::Unretained(this), conn_id_2)))); |
| 1744 |
| 1745 EXPECT_CALL(check, Call(3)); |
| 1746 EXPECT_CALL(*dispatcher_, |
| 1747 ShouldCreateOrBufferPacketForConnection(conn_id_1)); |
| 1748 |
| 1749 EXPECT_CALL(check, Call(4)); |
| 1750 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_)) |
| 1751 .WillOnce(testing::Return(GetSession(conn_id_1))); |
| 1752 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1753 GetSession(conn_id_1)->connection()), |
| 1754 ProcessUdpPacket(_, _, _)) |
| 1755 .WillRepeatedly(testing::WithArg<2>( |
| 1756 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1757 base::Unretained(this), conn_id_1)))); |
| 1758 } |
| 1759 |
| 1760 // Send a CHLO that the StatelessRejector will accept. |
| 1761 ProcessPacket(client_addr_, conn_id_1, true, false, SerializeFullCHLO()); |
| 1762 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1763 |
| 1764 // Send another CHLO that the StatelessRejector will accept. |
| 1765 ProcessPacket(client_addr_, conn_id_2, true, false, SerializeFullCHLO()); |
| 1766 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2); |
| 1767 |
| 1768 // Complete the second ProofSource::GetProof call and verify that a session is |
| 1769 // created. |
| 1770 check.Call(1); |
| 1771 GetFakeProofSource()->InvokePendingCallback(1); |
| 1772 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1773 |
| 1774 // Verify that a data packet on that connection gets processed immediately. |
| 1775 check.Call(2); |
| 1776 ProcessPacket(client_addr_, conn_id_2, true, false, "My name is Data"); |
| 1777 |
| 1778 // Verify that a data packet on the other connection does not get processed |
| 1779 // yet. |
| 1780 check.Call(3); |
| 1781 ProcessPacket(client_addr_, conn_id_1, true, false, "My name is Data"); |
| 1782 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); |
| 1783 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2)); |
| 1784 |
| 1785 // Complete the first ProofSource::GetProof call and verify that a session is |
| 1786 // created and the buffered packet is processed. |
| 1787 check.Call(4); |
| 1788 GetFakeProofSource()->InvokePendingCallback(0); |
| 1789 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1790 } |
| 1791 |
| 1792 // Test a situation with multiple interleaved connections which the |
| 1793 // StatelessRejector will reject. |
| 1794 TEST_F(AsyncGetProofTest, MultipleReject) { |
| 1795 CreateTimeWaitListManager(); |
| 1796 |
| 1797 QuicConnectionId conn_id_1 = 1; |
| 1798 QuicConnectionId conn_id_2 = 2; |
| 1799 QuicBufferedPacketStore* store = |
| 1800 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1801 |
| 1802 testing::MockFunction<void(int check_point)> check; |
| 1803 { |
| 1804 InSequence s; |
| 1805 |
| 1806 EXPECT_CALL(check, Call(1)); |
| 1807 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_)) |
| 1808 .Times(0); |
| 1809 EXPECT_CALL(*time_wait_list_manager_, |
| 1810 AddConnectionIdToTimeWait(conn_id_2, _, true, _)); |
| 1811 EXPECT_CALL(*time_wait_list_manager_, |
| 1812 ProcessPacket(_, client_addr_, conn_id_2, _, _)); |
| 1813 |
| 1814 EXPECT_CALL(check, Call(2)); |
| 1815 EXPECT_CALL(*time_wait_list_manager_, |
| 1816 ProcessPacket(_, client_addr_, conn_id_2, _, _)); |
| 1817 |
| 1818 EXPECT_CALL(check, Call(3)); |
| 1819 EXPECT_CALL(*dispatcher_, |
| 1820 ShouldCreateOrBufferPacketForConnection(conn_id_1)); |
| 1821 |
| 1822 EXPECT_CALL(check, Call(4)); |
| 1823 EXPECT_CALL(*time_wait_list_manager_, |
| 1824 AddConnectionIdToTimeWait(conn_id_1, _, true, _)); |
| 1825 EXPECT_CALL(*time_wait_list_manager_, |
| 1826 ProcessPacket(_, client_addr_, conn_id_1, _, _)); |
| 1827 } |
| 1828 |
| 1829 // Send a CHLO that the StatelessRejector will reject. |
| 1830 ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); |
| 1831 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1832 |
| 1833 // Send another CHLO that the StatelessRejector will reject. |
| 1834 ProcessPacket(client_addr_, conn_id_2, true, false, SerializeCHLO()); |
| 1835 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2); |
| 1836 |
| 1837 // Complete the second ProofSource::GetProof call and verify that the |
| 1838 // connection and packet are processed by the time wait manager. |
| 1839 check.Call(1); |
| 1840 GetFakeProofSource()->InvokePendingCallback(1); |
| 1841 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1842 |
| 1843 // Verify that a data packet on that connection gets processed immediately by |
| 1844 // the time wait manager. |
| 1845 check.Call(2); |
| 1846 ProcessPacket(client_addr_, conn_id_2, true, false, "My name is Data"); |
| 1847 |
| 1848 // Verify that a data packet on the first connection gets buffered. |
| 1849 check.Call(3); |
| 1850 ProcessPacket(client_addr_, conn_id_1, true, false, "My name is Data"); |
| 1851 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); |
| 1852 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2)); |
| 1853 |
| 1854 // Complete the first ProofSource::GetProof call and verify that the CHLO is |
| 1855 // processed by the time wait manager and the remaining packets are discarded. |
| 1856 check.Call(4); |
| 1857 GetFakeProofSource()->InvokePendingCallback(0); |
| 1858 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1859 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1)); |
| 1860 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2)); |
| 1861 } |
| 1862 |
| 1863 // Test a situation with multiple identical CHLOs which the StatelessRejector |
| 1864 // will reject. |
| 1865 TEST_F(AsyncGetProofTest, MultipleIdenticalReject) { |
| 1866 CreateTimeWaitListManager(); |
| 1867 |
| 1868 QuicConnectionId conn_id_1 = 1; |
| 1869 QuicBufferedPacketStore* store = |
| 1870 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1871 |
| 1872 testing::MockFunction<void(int check_point)> check; |
| 1873 { |
| 1874 InSequence s; |
| 1875 EXPECT_CALL(check, Call(1)); |
| 1876 EXPECT_CALL(*dispatcher_, |
| 1877 ShouldCreateOrBufferPacketForConnection(conn_id_1)); |
| 1878 |
| 1879 EXPECT_CALL(check, Call(2)); |
| 1880 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_)) |
| 1881 .Times(0); |
| 1882 EXPECT_CALL(*time_wait_list_manager_, |
| 1883 AddConnectionIdToTimeWait(conn_id_1, _, true, _)); |
| 1884 EXPECT_CALL(*time_wait_list_manager_, |
| 1885 ProcessPacket(_, client_addr_, conn_id_1, _, _)); |
| 1886 } |
| 1887 |
| 1888 // Send a CHLO that the StatelessRejector will reject. |
| 1889 ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); |
| 1890 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1891 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1)); |
| 1892 |
| 1893 // Send an identical CHLO which should get buffered. |
| 1894 check.Call(1); |
| 1895 ProcessPacket(client_addr_, conn_id_1, true, false, SerializeCHLO()); |
| 1896 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1897 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1)); |
| 1898 |
| 1899 // Complete the ProofSource::GetProof call and verify that the CHLO is |
| 1900 // rejected and the copy is discarded. |
| 1901 check.Call(2); |
| 1902 GetFakeProofSource()->InvokePendingCallback(0); |
| 1903 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1904 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1)); |
| 1905 } |
| 1906 |
| 1907 // Test dispatcher behavior when packets time out of the buffer while CHLO |
| 1908 // validation is still pending. |
| 1909 TEST_F(AsyncGetProofTest, BufferTimeout) { |
| 1910 CreateTimeWaitListManager(); |
| 1911 |
| 1912 QuicConnectionId conn_id = 1; |
| 1913 QuicBufferedPacketStore* store = |
| 1914 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1915 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); |
| 1916 |
| 1917 testing::MockFunction<void(int check_point)> check; |
| 1918 { |
| 1919 InSequence s; |
| 1920 EXPECT_CALL(check, Call(1)); |
| 1921 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1922 |
| 1923 EXPECT_CALL(check, Call(2)); |
| 1924 EXPECT_CALL(*time_wait_list_manager_, |
| 1925 ProcessPacket(_, client_addr_, conn_id, _, _)); |
| 1926 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1927 .Times(0); |
| 1928 } |
| 1929 |
| 1930 // Send a CHLO that the StatelessRejector will accept. |
| 1931 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1932 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1933 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 1934 |
| 1935 // Send a data packet that will get buffered |
| 1936 check.Call(1); |
| 1937 ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); |
| 1938 EXPECT_TRUE(store->HasBufferedPackets(conn_id)); |
| 1939 |
| 1940 // Pretend that enough time has gone by for the packets to get expired out of |
| 1941 // the buffer |
| 1942 mock_helper_.AdvanceTime( |
| 1943 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); |
| 1944 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel(); |
| 1945 store->OnExpirationTimeout(); |
| 1946 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 1947 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 1948 |
| 1949 // Now allow the CHLO validation to complete, and verify that no connection |
| 1950 // gets created. |
| 1951 check.Call(2); |
| 1952 GetFakeProofSource()->InvokePendingCallback(0); |
| 1953 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 1954 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 1955 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 1956 } |
| 1957 |
| 1958 // Test behavior when packets time out of the buffer *and* the connection times |
| 1959 // out of the time wait manager while CHLO validation is still pending. This |
| 1960 // *should* be impossible, but anything can happen with timing conditions. |
| 1961 TEST_F(AsyncGetProofTest, TimeWaitTimeout) { |
| 1962 QuicConnectionId conn_id = 1; |
| 1963 QuicBufferedPacketStore* store = |
| 1964 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1965 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); |
| 1966 CreateTimeWaitListManager(); |
| 1967 QuicTimeWaitListManagerPeer::set_clock(time_wait_list_manager_, |
| 1968 mock_helper_.GetClock()); |
| 1969 |
| 1970 testing::MockFunction<void(int check_point)> check; |
| 1971 { |
| 1972 InSequence s; |
| 1973 EXPECT_CALL(check, Call(1)); |
| 1974 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1975 |
| 1976 EXPECT_CALL(check, Call(2)); |
| 1977 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1978 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1979 .WillOnce(testing::Return(GetSession(conn_id))); |
| 1980 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>( |
| 1981 GetSession(conn_id)->connection()), |
| 1982 ProcessUdpPacket(_, _, _)) |
| 1983 .WillOnce(testing::WithArg<2>( |
| 1984 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1985 base::Unretained(this), conn_id)))); |
| 1986 } |
| 1987 |
| 1988 // Send a CHLO that the StatelessRejector will accept. |
| 1989 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1990 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1); |
| 1991 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 1992 |
| 1993 // Send a data packet that will get buffered |
| 1994 check.Call(1); |
| 1995 ProcessPacket(client_addr_, conn_id, true, false, "My name is Data"); |
| 1996 EXPECT_TRUE(store->HasBufferedPackets(conn_id)); |
| 1997 |
| 1998 // Pretend that enough time has gone by for the packets to get expired out of |
| 1999 // the buffer |
| 2000 mock_helper_.AdvanceTime( |
| 2001 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); |
| 2002 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel(); |
| 2003 store->OnExpirationTimeout(); |
| 2004 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 2005 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 2006 |
| 2007 // Pretend that enough time has gone by for the connection ID to be removed |
| 2008 // from the time wait manager |
| 2009 mock_helper_.AdvanceTime( |
| 2010 QuicTimeWaitListManagerPeer::time_wait_period(time_wait_list_manager_)); |
| 2011 QuicTimeWaitListManagerPeer::expiration_alarm(time_wait_list_manager_) |
| 2012 ->Cancel(); |
| 2013 time_wait_list_manager_->CleanUpOldConnectionIds(); |
| 2014 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 2015 |
| 2016 // Now allow the CHLO validation to complete. Expect that a connection is |
| 2017 // indeed created, since QUIC has forgotten that this connection ever existed. |
| 2018 // This is a miniscule corner case which should never happen in the wild, so |
| 2019 // really we are just verifying that the dispatcher does not explode in this |
| 2020 // situation. |
| 2021 check.Call(2); |
| 2022 GetFakeProofSource()->InvokePendingCallback(0); |
| 2023 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0); |
| 2024 EXPECT_FALSE(store->HasBufferedPackets(conn_id)); |
| 2025 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 2026 } |
| 2027 |
1534 } // namespace | 2028 } // namespace |
1535 } // namespace test | 2029 } // namespace test |
1536 } // namespace net | 2030 } // namespace net |
OLD | NEW |