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 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 using std::string; | 45 using std::string; |
46 using std::vector; | 46 using std::vector; |
47 using testing::CreateFunctor; | 47 using testing::CreateFunctor; |
48 using testing::DoAll; | 48 using testing::DoAll; |
49 using testing::InSequence; | 49 using testing::InSequence; |
50 using testing::Invoke; | 50 using testing::Invoke; |
51 using testing::WithoutArgs; | 51 using testing::WithoutArgs; |
52 using testing::_; | 52 using testing::_; |
53 | 53 |
54 static const size_t kDefaultMaxConnectionsInStore = 100; | 54 static const size_t kDefaultMaxConnectionsInStore = 100; |
| 55 static const size_t kMaxConnectionsWithoutCHLO = |
| 56 kDefaultMaxConnectionsInStore / 2; |
| 57 static const int16_t kMaxNumSessionsToCreate = 16; |
55 | 58 |
56 namespace net { | 59 namespace net { |
57 namespace test { | 60 namespace test { |
58 namespace { | 61 namespace { |
59 | 62 |
60 class TestQuicSpdyServerSession : public QuicServerSessionBase { | 63 class TestQuicSpdyServerSession : public QuicServerSessionBase { |
61 public: | 64 public: |
62 TestQuicSpdyServerSession(const QuicConfig& config, | 65 TestQuicSpdyServerSession(const QuicConfig& config, |
63 QuicConnection* connection, | 66 QuicConnection* connection, |
64 const QuicCryptoServerConfig* crypto_config, | 67 const QuicCryptoServerConfig* crypto_config, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 &crypto_config_, | 172 &crypto_config_, |
170 &version_manager_, | 173 &version_manager_, |
171 &eps_)), | 174 &eps_)), |
172 time_wait_list_manager_(nullptr), | 175 time_wait_list_manager_(nullptr), |
173 session1_(nullptr), | 176 session1_(nullptr), |
174 session2_(nullptr), | 177 session2_(nullptr), |
175 store_(nullptr) {} | 178 store_(nullptr) {} |
176 | 179 |
177 void SetUp() override { | 180 void SetUp() override { |
178 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); | 181 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); |
| 182 // Set the counter to some value to start with. |
| 183 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop( |
| 184 dispatcher_.get(), kMaxNumSessionsToCreate); |
179 } | 185 } |
180 | 186 |
181 ~QuicDispatcherTest() override {} | 187 ~QuicDispatcherTest() override {} |
182 | 188 |
183 MockQuicConnection* connection1() { | 189 MockQuicConnection* connection1() { |
184 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); | 190 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); |
185 } | 191 } |
186 | 192 |
187 MockQuicConnection* connection2() { | 193 MockQuicConnection* connection2() { |
188 return reinterpret_cast<MockQuicConnection*>(session2_->connection()); | 194 return reinterpret_cast<MockQuicConnection*>(session2_->connection()); |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, | 1158 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
1153 base::Unretained(this), conn_id)))); | 1159 base::Unretained(this), conn_id)))); |
1154 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1160 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
1155 } | 1161 } |
1156 | 1162 |
1157 TEST_P(BufferedPacketStoreTest, | 1163 TEST_P(BufferedPacketStoreTest, |
1158 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) { | 1164 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) { |
1159 InSequence s; | 1165 InSequence s; |
1160 server_address_ = IPEndPoint(Any4(), 5); | 1166 server_address_ = IPEndPoint(Any4(), 5); |
1161 // A bunch of non-CHLO should be buffered upon arrival. | 1167 // A bunch of non-CHLO should be buffered upon arrival. |
1162 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { | 1168 size_t kNumConnections = (FLAGS_quic_limit_num_new_sessions_per_epoll_loop |
| 1169 ? kMaxConnectionsWithoutCHLO |
| 1170 : kDefaultMaxConnectionsInStore) + |
| 1171 1; |
| 1172 for (size_t i = 1; i <= kNumConnections; ++i) { |
1163 IPEndPoint client_address(Loopback4(), i); | 1173 IPEndPoint client_address(Loopback4(), i); |
1164 QuicConnectionId conn_id = i; | 1174 QuicConnectionId conn_id = i; |
1165 if (i <= kDefaultMaxConnectionsInStore) { | 1175 if (i <= kNumConnections - 1) { |
1166 // As they are on different connection, they should trigger | 1176 // As they are on different connection, they should trigger |
1167 // OnNewConnectionAdded(). The last packet should be dropped. | 1177 // OnNewConnectionAdded(). The last packet should be dropped. |
1168 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1178 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
1169 } | 1179 } |
1170 ProcessPacket(client_address, conn_id, true, false, | 1180 ProcessPacket(client_address, conn_id, true, false, |
1171 "data packet on connection " + IntToString(i), | 1181 "data packet on connection " + IntToString(i), |
1172 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 1182 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
1173 kDefaultPathId, | 1183 kDefaultPathId, |
1174 /*packet_number=*/2); | 1184 /*packet_number=*/2); |
1175 } | 1185 } |
1176 | 1186 |
1177 // Pop out the packet on last connection as it shouldn't be enqueued in store | 1187 // Pop out the packet on last connection as it shouldn't be enqueued in store |
1178 // as well. | 1188 // as well. |
1179 data_connection_map_[kDefaultMaxConnectionsInStore + 1].pop_front(); | 1189 data_connection_map_[kNumConnections].pop_front(); |
1180 | 1190 |
1181 // Process CHLOs. | 1191 // Reset session creation counter to ensure processing CHLO can always |
1182 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { | 1192 // create session. |
| 1193 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(), |
| 1194 kNumConnections); |
| 1195 // Process CHLOs to create session for these connections. |
| 1196 for (size_t i = 1; i <= kNumConnections; ++i) { |
1183 IPEndPoint client_address(Loopback4(), i); | 1197 IPEndPoint client_address(Loopback4(), i); |
1184 QuicConnectionId conn_id = i; | 1198 QuicConnectionId conn_id = i; |
1185 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) | 1199 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
1186 .WillOnce(testing::Return(CreateSession( | 1200 .WillOnce(testing::Return(CreateSession( |
1187 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, | 1201 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
1188 &mock_alarm_factory_, &crypto_config_, | 1202 &mock_alarm_factory_, &crypto_config_, |
1189 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1203 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
1190 if (conn_id == kDefaultMaxConnectionsInStore + 1) { | 1204 if (conn_id == kNumConnections) { |
1191 // The last CHLO should trigger OnNewConnectionAdded() since it's the | 1205 // The last CHLO should trigger OnNewConnectionAdded() since it's the |
1192 // first packet arrives on that connection. | 1206 // first packet arrives on that connection. |
1193 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1207 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
1194 } | 1208 } |
1195 // First |kDefaultMaxConnectionsInStore| connections should have buffered | 1209 // First |kNumConnections| - 1 connections should have buffered |
1196 // a packet in store. The rest should have been dropped. | 1210 // a packet in store. The rest should have been dropped. |
1197 if (i <= kDefaultMaxConnectionsInStore) { | 1211 size_t upper_limit = FLAGS_quic_limit_num_new_sessions_per_epoll_loop |
1198 EXPECT_CALL( | 1212 ? kMaxConnectionsWithoutCHLO |
1199 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 1213 : kDefaultMaxConnectionsInStore; |
1200 ProcessUdpPacket(_, client_address, _)) | 1214 size_t num_packet_to_process = i <= upper_limit ? 2u : 1u; |
1201 .Times(2) | 1215 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
1202 .WillRepeatedly(testing::WithArg<2>( | 1216 ProcessUdpPacket(_, client_address, _)) |
1203 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, | 1217 .Times(num_packet_to_process) |
1204 base::Unretained(this), conn_id)))); | 1218 .WillRepeatedly(testing::WithArg<2>( |
1205 } | 1219 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1220 base::Unretained(this), conn_id)))); |
1206 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1221 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
1207 } | 1222 } |
1208 } | 1223 } |
1209 | 1224 |
1210 // Tests that store delivers empty packet list if CHLO arrives firstly. | 1225 // Tests that store delivers empty packet list if CHLO arrives firstly. |
1211 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { | 1226 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { |
1212 QuicConnectionId conn_id = 1; | 1227 QuicConnectionId conn_id = 1; |
1213 IPEndPoint client_address(Loopback4(), 1); | 1228 IPEndPoint client_address(Loopback4(), 1); |
1214 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1229 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
1215 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) | 1230 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
1216 .WillOnce(testing::Return(CreateSession( | 1231 .WillOnce(testing::Return(CreateSession( |
1217 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, | 1232 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
1218 &mock_alarm_factory_, &crypto_config_, | 1233 &mock_alarm_factory_, &crypto_config_, |
1219 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1234 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
1220 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1235 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
1221 } | 1236 } |
1222 | 1237 |
1223 // Tests that by the time a retransmitted CHLO arrives, a connection for the | 1238 // Tests that a retransmitted CHLO arrives after a connection for the |
1224 // CHLO should already be created. | 1239 // CHLO has been created. |
1225 TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { | 1240 TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { |
1226 InSequence s; | 1241 InSequence s; |
1227 IPEndPoint client_address(Loopback4(), 1); | 1242 IPEndPoint client_address(Loopback4(), 1); |
1228 server_address_ = IPEndPoint(Any4(), 5); | 1243 server_address_ = IPEndPoint(Any4(), 5); |
1229 QuicConnectionId conn_id = 1; | 1244 QuicConnectionId conn_id = 1; |
1230 ProcessPacket(client_address, conn_id, true, false, | 1245 ProcessPacket(client_address, conn_id, true, false, |
1231 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, | 1246 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, |
1232 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, | 1247 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, |
1233 /*packet_number=*/2); | 1248 /*packet_number=*/2); |
1234 | 1249 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1273 // Cancel alarm as if it had been fired. | 1288 // Cancel alarm as if it had been fired. |
1274 alarm->Cancel(); | 1289 alarm->Cancel(); |
1275 store->OnExpirationTimeout(); | 1290 store->OnExpirationTimeout(); |
1276 // New arrived CHLO will be dropped because this connection is in time wait | 1291 // New arrived CHLO will be dropped because this connection is in time wait |
1277 // list. | 1292 // list. |
1278 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); | 1293 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
1279 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); | 1294 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); |
1280 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1295 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
1281 } | 1296 } |
1282 | 1297 |
| 1298 TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) { |
| 1299 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true; |
| 1300 // Process more than (|kMaxNumSessionsToCreate| + |
| 1301 // |kDefaultMaxConnectionsInStore|) CHLOs, |
| 1302 // the first |kMaxNumSessionsToCreate| should create connections immediately, |
| 1303 // the next |kDefaultMaxConnectionsInStore| should be buffered, |
| 1304 // the rest should be dropped. |
| 1305 QuicBufferedPacketStore* store = |
| 1306 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1307 const size_t kNumCHLOs = |
| 1308 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1; |
| 1309 for (size_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) { |
| 1310 if (conn_id < kNumCHLOs) { |
| 1311 // Except the last connection, all connections for previous CHLOs should |
| 1312 // be regarded as newly added. |
| 1313 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1314 } |
| 1315 if (conn_id <= kMaxNumSessionsToCreate) { |
| 1316 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1317 .WillOnce(testing::Return(CreateSession( |
| 1318 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1319 &mock_alarm_factory_, &crypto_config_, |
| 1320 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1321 EXPECT_CALL( |
| 1322 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1323 ProcessUdpPacket(_, _, _)) |
| 1324 .WillOnce(testing::WithArg<2>( |
| 1325 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1326 base::Unretained(this), conn_id)))); |
| 1327 } |
| 1328 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1329 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore && |
| 1330 conn_id > kMaxNumSessionsToCreate) { |
| 1331 EXPECT_TRUE(store->HasChloForConnection(conn_id)); |
| 1332 } else { |
| 1333 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new |
| 1334 // connections immediately, and the last CHLO should be dropped as the |
| 1335 // store is full. |
| 1336 EXPECT_FALSE(store->HasChloForConnection(conn_id)); |
| 1337 } |
| 1338 } |
| 1339 |
| 1340 // Graduately consume buffered CHLOs. The buffered connections should be |
| 1341 // created but the dropped one shouldn't. |
| 1342 for (size_t conn_id = kMaxNumSessionsToCreate + 1; |
| 1343 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore; |
| 1344 ++conn_id) { |
| 1345 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1346 .WillOnce(testing::Return(CreateSession( |
| 1347 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1348 &mock_alarm_factory_, &crypto_config_, |
| 1349 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1350 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1351 ProcessUdpPacket(_, _, _)) |
| 1352 .WillOnce(testing::WithArg<2>( |
| 1353 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1354 base::Unretained(this), conn_id)))); |
| 1355 } |
| 1356 EXPECT_CALL(*dispatcher_, CreateQuicSession(kNumCHLOs, client_addr_)) |
| 1357 .Times(0); |
| 1358 |
| 1359 while (store->HasChlosBuffered()) { |
| 1360 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate); |
| 1361 } |
| 1362 |
| 1363 EXPECT_EQ(static_cast<size_t>(kMaxNumSessionsToCreate) + |
| 1364 kDefaultMaxConnectionsInStore, |
| 1365 session1_->connection_id()); |
| 1366 } |
| 1367 |
| 1368 // Duplicated CHLO shouldn't be buffered. |
| 1369 TEST_P(BufferedPacketStoreTest, DropDuplicatedCHLO) { |
| 1370 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true; |
| 1371 for (QuicConnectionId conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1; |
| 1372 ++conn_id) { |
| 1373 // Last CHLO will be buffered. Others will create connection right away. |
| 1374 if (conn_id <= kMaxNumSessionsToCreate) { |
| 1375 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1376 .WillOnce(testing::Return(CreateSession( |
| 1377 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1378 &mock_alarm_factory_, &crypto_config_, |
| 1379 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1380 EXPECT_CALL( |
| 1381 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1382 ProcessUdpPacket(_, _, _)) |
| 1383 .WillOnce(testing::WithArg<2>( |
| 1384 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1385 base::Unretained(this), conn_id)))); |
| 1386 } |
| 1387 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1388 } |
| 1389 // Retransmit CHLO on last connection should be dropped. |
| 1390 QuicConnectionId last_connection = kMaxNumSessionsToCreate + 1; |
| 1391 ProcessPacket(client_addr_, last_connection, true, false, |
| 1392 SerializeFullCHLO()); |
| 1393 |
| 1394 // Reset counter and process buffered CHLO. |
| 1395 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_)) |
| 1396 .WillOnce(testing::Return(CreateSession( |
| 1397 dispatcher_.get(), config_, last_connection, client_addr_, |
| 1398 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
| 1399 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1400 // Only one packet(CHLO) should be process. |
| 1401 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1402 ProcessUdpPacket(_, _, _)) |
| 1403 .WillOnce(testing::WithArg<2>( |
| 1404 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1405 base::Unretained(this), last_connection)))); |
| 1406 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate); |
| 1407 } |
| 1408 |
| 1409 TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) { |
| 1410 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true; |
| 1411 QuicConnectionId last_connection_id = kMaxNumSessionsToCreate + 1; |
| 1412 for (QuicConnectionId conn_id = 1; conn_id <= last_connection_id; ++conn_id) { |
| 1413 // Last CHLO will be buffered. Others will create connection right away. |
| 1414 if (conn_id <= kMaxNumSessionsToCreate) { |
| 1415 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1416 .WillOnce(testing::Return(CreateSession( |
| 1417 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1418 &mock_alarm_factory_, &crypto_config_, |
| 1419 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1420 EXPECT_CALL( |
| 1421 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1422 ProcessUdpPacket(_, _, _)) |
| 1423 .WillOnce(testing::WithArg<2>( |
| 1424 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1425 base::Unretained(this), conn_id)))); |
| 1426 } |
| 1427 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1428 } |
| 1429 |
| 1430 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The |
| 1431 // last one should be dropped. |
| 1432 for (QuicPacketNumber packet_number = 2; |
| 1433 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) { |
| 1434 ProcessPacket(client_addr_, last_connection_id, true, false, "data packet"); |
| 1435 } |
| 1436 |
| 1437 // Reset counter and process buffered CHLO. |
| 1438 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_)) |
| 1439 .WillOnce(testing::Return(CreateSession( |
| 1440 dispatcher_.get(), config_, last_connection_id, client_addr_, |
| 1441 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
| 1442 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1443 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets |
| 1444 // should be process. |
| 1445 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1446 ProcessUdpPacket(_, _, _)) |
| 1447 .Times(kDefaultMaxUndecryptablePackets + 1) |
| 1448 .WillRepeatedly(testing::WithArg<2>( |
| 1449 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1450 base::Unretained(this), last_connection_id)))); |
| 1451 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate); |
| 1452 } |
| 1453 |
| 1454 // Tests that when dispatcher's packet buffer is full, a CHLO on connection |
| 1455 // which doesn't have buffered CHLO should be buffered. |
| 1456 TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) { |
| 1457 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = true; |
| 1458 QuicBufferedPacketStore* store = |
| 1459 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1460 |
| 1461 QuicConnectionId conn_id = 1; |
| 1462 ProcessPacket(client_addr_, conn_id, true, false, "data packet", |
| 1463 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1464 kDefaultPathId, |
| 1465 /*packet_number=*/1); |
| 1466 // Fill packet buffer to full with CHLOs on other connections. Need to feed |
| 1467 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create |
| 1468 // session directly. |
| 1469 for (conn_id = 2; |
| 1470 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate; |
| 1471 ++conn_id) { |
| 1472 if (conn_id <= kMaxNumSessionsToCreate + 1) { |
| 1473 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1474 .WillOnce(testing::Return(CreateSession( |
| 1475 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1476 &mock_alarm_factory_, &crypto_config_, |
| 1477 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1478 EXPECT_CALL( |
| 1479 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1480 ProcessUdpPacket(_, _, _)) |
| 1481 .WillOnce(testing::WithArg<2>( |
| 1482 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1483 base::Unretained(this), conn_id)))); |
| 1484 } |
| 1485 ProcessPacket(client_addr_, conn_id, true, false, SerializeFullCHLO()); |
| 1486 } |
| 1487 EXPECT_FALSE(store->HasChloForConnection(/*connection_id=*/1)); |
| 1488 |
| 1489 // CHLO on connection 1 should still be buffered. |
| 1490 ProcessPacket(client_addr_, /*connection_id=*/1, true, false, |
| 1491 SerializeFullCHLO()); |
| 1492 EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); |
| 1493 } |
| 1494 |
1283 } // namespace | 1495 } // namespace |
1284 } // namespace test | 1496 } // namespace test |
1285 } // namespace net | 1497 } // namespace net |
OLD | NEW |