Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: net/tools/quic/quic_dispatcher_test.cc

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

Powered by Google App Engine
This is Rietveld 408576698