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