| 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 30 matching lines...) Expand all Loading... |
| 41 using net::test::CryptoTestUtils; | 41 using net::test::CryptoTestUtils; |
| 42 using net::test::MockQuicConnection; | 42 using net::test::MockQuicConnection; |
| 43 using net::test::MockQuicConnectionHelper; | 43 using net::test::MockQuicConnectionHelper; |
| 44 using std::ostream; | 44 using std::ostream; |
| 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::Return; |
| 51 using testing::WithoutArgs; | 52 using testing::WithoutArgs; |
| 52 using testing::_; | 53 using testing::_; |
| 53 | 54 |
| 54 static const size_t kDefaultMaxConnectionsInStore = 100; | 55 static const size_t kDefaultMaxConnectionsInStore = 100; |
| 55 static const size_t kMaxConnectionsWithoutCHLO = | 56 static const size_t kMaxConnectionsWithoutCHLO = |
| 56 kDefaultMaxConnectionsInStore / 2; | 57 kDefaultMaxConnectionsInStore / 2; |
| 57 static const int16_t kMaxNumSessionsToCreate = 16; | 58 static const int16_t kMaxNumSessionsToCreate = 16; |
| 58 | 59 |
| 59 namespace net { | 60 namespace net { |
| 60 namespace test { | 61 namespace test { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 std::unique_ptr<QuicCryptoServerStream::Helper>( | 126 std::unique_ptr<QuicCryptoServerStream::Helper>( |
| 126 new QuicSimpleCryptoServerStreamHelper( | 127 new QuicSimpleCryptoServerStreamHelper( |
| 127 QuicRandom::GetInstance())), | 128 QuicRandom::GetInstance())), |
| 128 std::unique_ptr<QuicEpollAlarmFactory>( | 129 std::unique_ptr<QuicEpollAlarmFactory>( |
| 129 new QuicEpollAlarmFactory(eps))) {} | 130 new QuicEpollAlarmFactory(eps))) {} |
| 130 | 131 |
| 131 MOCK_METHOD2(CreateQuicSession, | 132 MOCK_METHOD2(CreateQuicSession, |
| 132 QuicServerSessionBase*(QuicConnectionId connection_id, | 133 QuicServerSessionBase*(QuicConnectionId connection_id, |
| 133 const IPEndPoint& client_address)); | 134 const IPEndPoint& client_address)); |
| 134 | 135 |
| 135 MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id)); | 136 MOCK_METHOD1(ShouldCreateOrBufferPacketForConnection, |
| 137 bool(QuicConnectionId connection_id)); |
| 136 | 138 |
| 137 using QuicDispatcher::current_server_address; | 139 using QuicDispatcher::current_server_address; |
| 138 using QuicDispatcher::current_client_address; | 140 using QuicDispatcher::current_client_address; |
| 139 }; | 141 }; |
| 140 | 142 |
| 141 // A Connection class which unregisters the session from the dispatcher when | 143 // A Connection class which unregisters the session from the dispatcher when |
| 142 // sending connection close. | 144 // sending connection close. |
| 143 // It'd be slightly more realistic to do this from the Session but it would | 145 // It'd be slightly more realistic to do this from the Session but it would |
| 144 // involve a lot more mocking. | 146 // involve a lot more mocking. |
| 145 class MockServerConnection : public MockQuicConnection { | 147 class MockServerConnection : public MockQuicConnection { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 time_wait_list_manager_(nullptr), | 182 time_wait_list_manager_(nullptr), |
| 181 session1_(nullptr), | 183 session1_(nullptr), |
| 182 session2_(nullptr), | 184 session2_(nullptr), |
| 183 store_(nullptr) {} | 185 store_(nullptr) {} |
| 184 | 186 |
| 185 void SetUp() override { | 187 void SetUp() override { |
| 186 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); | 188 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); |
| 187 // Set the counter to some value to start with. | 189 // Set the counter to some value to start with. |
| 188 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop( | 190 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop( |
| 189 dispatcher_.get(), kMaxNumSessionsToCreate); | 191 dispatcher_.get(), kMaxNumSessionsToCreate); |
| 192 ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_)) |
| 193 .WillByDefault(Return(true)); |
| 190 } | 194 } |
| 191 | 195 |
| 192 ~QuicDispatcherTest() override {} | 196 ~QuicDispatcherTest() override {} |
| 193 | 197 |
| 194 MockQuicConnection* connection1() { | 198 MockQuicConnection* connection1() { |
| 195 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); | 199 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); |
| 196 } | 200 } |
| 197 | 201 |
| 198 MockQuicConnection* connection2() { | 202 MockQuicConnection* connection2() { |
| 199 return reinterpret_cast<MockQuicConnection*>(session2_->connection()); | 203 return reinterpret_cast<MockQuicConnection*>(session2_->connection()); |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 BufferedPacketStoreTests, | 1132 BufferedPacketStoreTests, |
| 1129 BufferedPacketStoreTest, | 1133 BufferedPacketStoreTest, |
| 1130 ::testing::ValuesIn(GetBufferedPacketStoreTestParams())); | 1134 ::testing::ValuesIn(GetBufferedPacketStoreTestParams())); |
| 1131 | 1135 |
| 1132 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { | 1136 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { |
| 1133 InSequence s; | 1137 InSequence s; |
| 1134 IPEndPoint client_address(Loopback4(), 1); | 1138 IPEndPoint client_address(Loopback4(), 1); |
| 1135 server_address_ = IPEndPoint(Any4(), 5); | 1139 server_address_ = IPEndPoint(Any4(), 5); |
| 1136 QuicConnectionId conn_id = 1; | 1140 QuicConnectionId conn_id = 1; |
| 1137 // A bunch of non-CHLO should be buffered upon arrival, and the first one | 1141 // A bunch of non-CHLO should be buffered upon arrival, and the first one |
| 1138 // should trigger OnNewConnectionAdded(). | 1142 // should trigger ShouldCreateOrBufferPacketForConnection(). |
| 1139 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)).Times(1); | 1143 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)) |
| 1144 .Times(1); |
| 1140 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { | 1145 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { |
| 1141 ProcessPacket(client_address, conn_id, true, false, | 1146 ProcessPacket(client_address, conn_id, true, false, |
| 1142 "data packet " + IntToString(i + 1), | 1147 "data packet " + IntToString(i + 1), |
| 1143 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 1148 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1144 kDefaultPathId, | 1149 kDefaultPathId, |
| 1145 /*packet_number=*/i + 1); | 1150 /*packet_number=*/i + 1); |
| 1146 } | 1151 } |
| 1147 EXPECT_EQ(0u, dispatcher_->session_map().size()) | 1152 EXPECT_EQ(0u, dispatcher_->session_map().size()) |
| 1148 << "No session should be created before CHLO arrives."; | 1153 << "No session should be created before CHLO arrives."; |
| 1149 | 1154 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1173 InSequence s; | 1178 InSequence s; |
| 1174 server_address_ = IPEndPoint(Any4(), 5); | 1179 server_address_ = IPEndPoint(Any4(), 5); |
| 1175 // A bunch of non-CHLO should be buffered upon arrival. | 1180 // A bunch of non-CHLO should be buffered upon arrival. |
| 1176 size_t kNumConnections = (FLAGS_quic_limit_num_new_sessions_per_epoll_loop | 1181 size_t kNumConnections = (FLAGS_quic_limit_num_new_sessions_per_epoll_loop |
| 1177 ? kMaxConnectionsWithoutCHLO | 1182 ? kMaxConnectionsWithoutCHLO |
| 1178 : kDefaultMaxConnectionsInStore) + | 1183 : kDefaultMaxConnectionsInStore) + |
| 1179 1; | 1184 1; |
| 1180 for (size_t i = 1; i <= kNumConnections; ++i) { | 1185 for (size_t i = 1; i <= kNumConnections; ++i) { |
| 1181 IPEndPoint client_address(Loopback4(), i); | 1186 IPEndPoint client_address(Loopback4(), i); |
| 1182 QuicConnectionId conn_id = i; | 1187 QuicConnectionId conn_id = i; |
| 1183 if (i <= kNumConnections - 1) { | 1188 if (FLAGS_quic_create_session_after_insertion) { |
| 1184 // As they are on different connection, they should trigger | 1189 EXPECT_CALL(*dispatcher_, |
| 1185 // OnNewConnectionAdded(). The last packet should be dropped. | 1190 ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1186 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1191 } else { |
| 1192 if (i <= kNumConnections - 1) { |
| 1193 // As they are on different connection, they should trigger |
| 1194 // ShouldCreateOrBufferPacketForConnection(). The last packet should be |
| 1195 // dropped. |
| 1196 EXPECT_CALL(*dispatcher_, |
| 1197 ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1198 } |
| 1187 } | 1199 } |
| 1188 ProcessPacket(client_address, conn_id, true, false, | 1200 ProcessPacket(client_address, conn_id, true, false, |
| 1189 "data packet on connection " + IntToString(i), | 1201 "data packet on connection " + IntToString(i), |
| 1190 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 1202 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1191 kDefaultPathId, | 1203 kDefaultPathId, |
| 1192 /*packet_number=*/2); | 1204 /*packet_number=*/2); |
| 1193 } | 1205 } |
| 1194 | 1206 |
| 1195 // Pop out the packet on last connection as it shouldn't be enqueued in store | 1207 // Pop out the packet on last connection as it shouldn't be enqueued in store |
| 1196 // as well. | 1208 // as well. |
| 1197 data_connection_map_[kNumConnections].pop_front(); | 1209 data_connection_map_[kNumConnections].pop_front(); |
| 1198 | 1210 |
| 1199 // Reset session creation counter to ensure processing CHLO can always | 1211 // Reset session creation counter to ensure processing CHLO can always |
| 1200 // create session. | 1212 // create session. |
| 1201 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(), | 1213 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(), |
| 1202 kNumConnections); | 1214 kNumConnections); |
| 1203 // Process CHLOs to create session for these connections. | 1215 // Process CHLOs to create session for these connections. |
| 1204 for (size_t i = 1; i <= kNumConnections; ++i) { | 1216 for (size_t i = 1; i <= kNumConnections; ++i) { |
| 1205 IPEndPoint client_address(Loopback4(), i); | 1217 IPEndPoint client_address(Loopback4(), i); |
| 1206 QuicConnectionId conn_id = i; | 1218 QuicConnectionId conn_id = i; |
| 1219 if (FLAGS_quic_create_session_after_insertion && |
| 1220 conn_id == kNumConnections) { |
| 1221 EXPECT_CALL(*dispatcher_, |
| 1222 ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1223 } |
| 1207 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) | 1224 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1208 .WillOnce(testing::Return(CreateSession( | 1225 .WillOnce(testing::Return(CreateSession( |
| 1209 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, | 1226 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1210 &mock_alarm_factory_, &crypto_config_, | 1227 &mock_alarm_factory_, &crypto_config_, |
| 1211 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1228 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1212 if (conn_id == kNumConnections) { | 1229 if (!FLAGS_quic_create_session_after_insertion && |
| 1213 // The last CHLO should trigger OnNewConnectionAdded() since it's the | 1230 conn_id == kNumConnections) { |
| 1214 // first packet arrives on that connection. | 1231 // The last CHLO should trigger ShouldCreateOrBufferPacketForConnection() |
| 1215 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1232 // since it's the first packet arrives on that connection. |
| 1233 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)
); |
| 1216 } | 1234 } |
| 1217 // First |kNumConnections| - 1 connections should have buffered | 1235 // First |kNumConnections| - 1 connections should have buffered |
| 1218 // a packet in store. The rest should have been dropped. | 1236 // a packet in store. The rest should have been dropped. |
| 1219 size_t upper_limit = FLAGS_quic_limit_num_new_sessions_per_epoll_loop | 1237 size_t upper_limit = FLAGS_quic_limit_num_new_sessions_per_epoll_loop |
| 1220 ? kMaxConnectionsWithoutCHLO | 1238 ? kMaxConnectionsWithoutCHLO |
| 1221 : kDefaultMaxConnectionsInStore; | 1239 : kDefaultMaxConnectionsInStore; |
| 1222 size_t num_packet_to_process = i <= upper_limit ? 2u : 1u; | 1240 size_t num_packet_to_process = i <= upper_limit ? 2u : 1u; |
| 1223 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 1241 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1224 ProcessUdpPacket(_, client_address, _)) | 1242 ProcessUdpPacket(_, client_address, _)) |
| 1225 .Times(num_packet_to_process) | 1243 .Times(num_packet_to_process) |
| 1226 .WillRepeatedly(testing::WithArg<2>( | 1244 .WillRepeatedly(testing::WithArg<2>( |
| 1227 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, | 1245 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1228 base::Unretained(this), conn_id)))); | 1246 base::Unretained(this), conn_id)))); |
| 1229 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1247 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1230 } | 1248 } |
| 1231 } | 1249 } |
| 1232 | 1250 |
| 1233 // Tests that store delivers empty packet list if CHLO arrives firstly. | 1251 // Tests that store delivers empty packet list if CHLO arrives firstly. |
| 1234 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { | 1252 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { |
| 1235 QuicConnectionId conn_id = 1; | 1253 QuicConnectionId conn_id = 1; |
| 1236 IPEndPoint client_address(Loopback4(), 1); | 1254 IPEndPoint client_address(Loopback4(), 1); |
| 1237 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1255 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1238 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) | 1256 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1239 .WillOnce(testing::Return(CreateSession( | 1257 .WillOnce(testing::Return(CreateSession( |
| 1240 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, | 1258 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1241 &mock_alarm_factory_, &crypto_config_, | 1259 &mock_alarm_factory_, &crypto_config_, |
| 1242 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1260 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1243 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); | 1261 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1244 } | 1262 } |
| 1245 | 1263 |
| 1246 // Tests that a retransmitted CHLO arrives after a connection for the | 1264 // Tests that a retransmitted CHLO arrives after a connection for the |
| 1247 // CHLO has been created. | 1265 // CHLO has been created. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 // Process more than (|kMaxNumSessionsToCreate| + | 1326 // Process more than (|kMaxNumSessionsToCreate| + |
| 1309 // |kDefaultMaxConnectionsInStore|) CHLOs, | 1327 // |kDefaultMaxConnectionsInStore|) CHLOs, |
| 1310 // the first |kMaxNumSessionsToCreate| should create connections immediately, | 1328 // the first |kMaxNumSessionsToCreate| should create connections immediately, |
| 1311 // the next |kDefaultMaxConnectionsInStore| should be buffered, | 1329 // the next |kDefaultMaxConnectionsInStore| should be buffered, |
| 1312 // the rest should be dropped. | 1330 // the rest should be dropped. |
| 1313 QuicBufferedPacketStore* store = | 1331 QuicBufferedPacketStore* store = |
| 1314 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); | 1332 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1315 const size_t kNumCHLOs = | 1333 const size_t kNumCHLOs = |
| 1316 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1; | 1334 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1; |
| 1317 for (size_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) { | 1335 for (size_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) { |
| 1318 if (conn_id < kNumCHLOs) { | 1336 if (FLAGS_quic_create_session_after_insertion) { |
| 1337 EXPECT_CALL(*dispatcher_, |
| 1338 ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1339 } |
| 1340 if (!FLAGS_quic_create_session_after_insertion && conn_id < kNumCHLOs) { |
| 1319 // Except the last connection, all connections for previous CHLOs should | 1341 // Except the last connection, all connections for previous CHLOs should |
| 1320 // be regarded as newly added. | 1342 // be regarded as newly added. |
| 1321 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); | 1343 EXPECT_CALL(*dispatcher_, |
| 1344 ShouldCreateOrBufferPacketForConnection(conn_id)); |
| 1322 } | 1345 } |
| 1323 if (conn_id <= kMaxNumSessionsToCreate) { | 1346 if (conn_id <= kMaxNumSessionsToCreate) { |
| 1324 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) | 1347 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_)) |
| 1325 .WillOnce(testing::Return(CreateSession( | 1348 .WillOnce(testing::Return(CreateSession( |
| 1326 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, | 1349 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_, |
| 1327 &mock_alarm_factory_, &crypto_config_, | 1350 &mock_alarm_factory_, &crypto_config_, |
| 1328 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 1351 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1329 EXPECT_CALL( | 1352 EXPECT_CALL( |
| 1330 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 1353 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1331 ProcessUdpPacket(_, _, _)) | 1354 ProcessUdpPacket(_, _, _)) |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 | 1526 |
| 1504 // CHLO on connection 1 should still be buffered. | 1527 // CHLO on connection 1 should still be buffered. |
| 1505 ProcessPacket(client_addr_, /*connection_id=*/1, true, false, | 1528 ProcessPacket(client_addr_, /*connection_id=*/1, true, false, |
| 1506 SerializeFullCHLO()); | 1529 SerializeFullCHLO()); |
| 1507 EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); | 1530 EXPECT_TRUE(store->HasChloForConnection(/*connection_id=*/1)); |
| 1508 } | 1531 } |
| 1509 | 1532 |
| 1510 } // namespace | 1533 } // namespace |
| 1511 } // namespace test | 1534 } // namespace test |
| 1512 } // namespace net | 1535 } // namespace net |
| OLD | NEW |