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

Unified Diff: net/tools/quic/quic_dispatcher_test.cc

Issue 2310543002: Limits only 16 new QUIC connections can be opened per epoll event. (Closed)
Patch Set: Limits only 16 new QUIC connections can be opened per epoll event. Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/tools/quic/quic_dispatcher.cc ('k') | net/tools/quic/quic_server.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/tools/quic/quic_dispatcher_test.cc
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index fcf45c2fadb90669f5d78f2a3bb96f5fe1c342b9..09364881bf0679a0dd142904018e946ae000b67b 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -52,6 +52,9 @@ using testing::WithoutArgs;
using testing::_;
static const size_t kDefaultMaxConnectionsInStore = 100;
+static const size_t kMaxConnectionsWithoutCHLO =
+ kDefaultMaxConnectionsInStore / 2;
+static const int16_t kMaxNumSessionsToCreate = 16;
namespace net {
namespace test {
@@ -176,6 +179,9 @@ class QuicDispatcherTest : public ::testing::Test {
void SetUp() override {
dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1));
+ // Set the counter to some value to start with.
+ QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
+ dispatcher_.get(), kMaxNumSessionsToCreate);
}
~QuicDispatcherTest() override {}
@@ -1159,10 +1165,14 @@ TEST_P(BufferedPacketStoreTest,
InSequence s;
server_address_ = IPEndPoint(Any4(), 5);
// A bunch of non-CHLO should be buffered upon arrival.
- for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) {
+ size_t kNumConnections = (FLAGS_quic_limit_num_new_sessions_per_epoll_loop
+ ? kMaxConnectionsWithoutCHLO
+ : kDefaultMaxConnectionsInStore) +
+ 1;
+ for (size_t i = 1; i <= kNumConnections; ++i) {
IPEndPoint client_address(Loopback4(), i);
QuicConnectionId conn_id = i;
- if (i <= kDefaultMaxConnectionsInStore) {
+ if (i <= kNumConnections - 1) {
// As they are on different connection, they should trigger
// OnNewConnectionAdded(). The last packet should be dropped.
EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id));
@@ -1176,10 +1186,14 @@ TEST_P(BufferedPacketStoreTest,
// Pop out the packet on last connection as it shouldn't be enqueued in store
// as well.
- data_connection_map_[kDefaultMaxConnectionsInStore + 1].pop_front();
-
- // Process CHLOs.
- for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) {
+ data_connection_map_[kNumConnections].pop_front();
+
+ // Reset session creation counter to ensure processing CHLO can always
+ // create session.
+ QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
+ kNumConnections);
+ // Process CHLOs to create session for these connections.
+ for (size_t i = 1; i <= kNumConnections; ++i) {
IPEndPoint client_address(Loopback4(), i);
QuicConnectionId conn_id = i;
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address))
@@ -1187,22 +1201,23 @@ TEST_P(BufferedPacketStoreTest,
dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
&mock_alarm_factory_, &crypto_config_,
QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
- if (conn_id == kDefaultMaxConnectionsInStore + 1) {
+ if (conn_id == kNumConnections) {
// The last CHLO should trigger OnNewConnectionAdded() since it's the
// first packet arrives on that connection.
EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id));
}
- // First |kDefaultMaxConnectionsInStore| connections should have buffered
+ // First |kNumConnections| - 1 connections should have buffered
// a packet in store. The rest should have been dropped.
- if (i <= kDefaultMaxConnectionsInStore) {
- EXPECT_CALL(
- *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
- ProcessUdpPacket(_, client_address, _))
- .Times(2)
- .WillRepeatedly(testing::WithArg<2>(
- Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
- base::Unretained(this), conn_id))));
- }
+ size_t upper_limit = FLAGS_quic_limit_num_new_sessions_per_epoll_loop
+ ? kMaxConnectionsWithoutCHLO
+ : kDefaultMaxConnectionsInStore;
+ size_t num_packet_to_process = i <= upper_limit ? 2u : 1u;
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, client_address, _))
+ .Times(num_packet_to_process)
+ .WillRepeatedly(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO());
}
}
@@ -1220,8 +1235,8 @@ TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO());
}
-// Tests that by the time a retransmitted CHLO arrives, a connection for the
-// CHLO should already be created.
+// Tests that a retransmitted CHLO arrives after a connection for the
+// CHLO has been created.
TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
InSequence s;
IPEndPoint client_address(Loopback4(), 1);
@@ -1280,6 +1295,203 @@ TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO());
}
+TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
+ FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true;
+ // Process more than (|kMaxNumSessionsToCreate| +
+ // |kDefaultMaxConnectionsInStore|) CHLOs,
+ // the first |kMaxNumSessionsToCreate| should create connections immediately,
+ // the next |kDefaultMaxConnectionsInStore| should be buffered,
+ // the rest should be dropped.
+ QuicBufferedPacketStore* store =
+ QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+ const size_t kNumCHLOs =
+ kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
+ for (size_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
+ if (conn_id < kNumCHLOs) {
+ // Except the last connection, all connections for previous CHLOs should
+ // be regarded as newly added.
+ EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id));
+ }
+ if (conn_id <= kMaxNumSessionsToCreate) {
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+ &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ EXPECT_CALL(
+ *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
+ }
+ ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO());
+ if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
+ conn_id > kMaxNumSessionsToCreate) {
+ EXPECT_TRUE(store->HasChloForConnection(conn_id));
+ } else {
+ // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
+ // connections immediately, and the last CHLO should be dropped as the
+ // store is full.
+ EXPECT_FALSE(store->HasChloForConnection(conn_id));
+ }
+ }
+
+ // Graduately consume buffered CHLOs. The buffered connections should be
+ // created but the dropped one shouldn't.
+ for (size_t conn_id = kMaxNumSessionsToCreate + 1;
+ conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
+ ++conn_id) {
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+ &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
+ }
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(kNumCHLOs, client_addr_))
+ .Times(0);
+
+ while (store->HasChlosBuffered()) {
+ dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+ }
+
+ EXPECT_EQ(static_cast<size_t>(kMaxNumSessionsToCreate) +
+ kDefaultMaxConnectionsInStore,
+ session1_->connection_id());
+}
+
+// Duplicated CHLO shouldn't be buffered.
+TEST_P(BufferedPacketStoreTest, DropDuplicatedCHLO) {
+ FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true;
+ for (QuicConnectionId conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
+ ++conn_id) {
+ // Last CHLO will be buffered. Others will create connection right away.
+ if (conn_id <= kMaxNumSessionsToCreate) {
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+ &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ EXPECT_CALL(
+ *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
+ }
+ ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO());
+ }
+ // Retransmit CHLO on last connection should be dropped.
+ QuicConnectionId last_connection = kMaxNumSessionsToCreate + 1;
+ ProcessPacket(client_addr_, last_connection, true, false,
+ SerializeFullCHLO());
+
+ // Reset counter and process buffered CHLO.
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, last_connection, client_addr_,
+ &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ // Only one packet(CHLO) should be process.
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), last_connection))));
+ dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
+ FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true;
+ QuicConnectionId last_connection_id = kMaxNumSessionsToCreate + 1;
+ for (QuicConnectionId conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
+ // Last CHLO will be buffered. Others will create connection right away.
+ if (conn_id <= kMaxNumSessionsToCreate) {
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+ &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ EXPECT_CALL(
+ *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
+ }
+ ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO());
+ }
+
+ // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
+ // last one should be dropped.
+ for (QuicPacketNumber packet_number = 2;
+ packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
+ ProcessPacket(client_addr_, last_connection_id, true, false, "data packet");
+ }
+
+ // Reset counter and process buffered CHLO.
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, last_connection_id, client_addr_,
+ &mock_helper_, &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
+ // should be process.
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .Times(kDefaultMaxUndecryptablePackets + 1)
+ .WillRepeatedly(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), last_connection_id))));
+ dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
+}
+
+// Tests that when dispatcher's packet buffer is full, a CHLO on connection
+// which doesn't have buffered CHLO should be buffered.
+TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
+ FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true;
+ QuicBufferedPacketStore* store =
+ QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
+
+ QuicConnectionId conn_id = 1;
+ ProcessPacket(client_addr_, conn_id, true, false, "data packet",
+ PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ kDefaultPathId,
+ /*packet_number=*/1);
+ // Fill packet buffer to full with CHLOs on other connections. Need to feed
+ // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
+ // session directly.
+ for (conn_id = 2;
+ conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
+ ++conn_id) {
+ if (conn_id <= kMaxNumSessionsToCreate + 1) {
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_))
+ .WillOnce(testing::Return(CreateSession(
+ dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
+ &mock_alarm_factory_, &crypto_config_,
+ QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
+ EXPECT_CALL(
+ *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(testing::WithArg<2>(
+ Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
+ base::Unretained(this), conn_id))));
+ }
+ ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO());
+ }
+ EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1));
+
+ // CHLO on connection 1 should still be buffered.
+ ProcessPacket(client_addr_, /*connection_id=*/1, true, false,
+ SerializeFullCHLO());
+ EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1));
+}
+
} // namespace
} // namespace test
} // namespace net
« no previous file with comments | « net/tools/quic/quic_dispatcher.cc ('k') | net/tools/quic/quic_server.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698