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 |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/strings/string_piece.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_test_utils.h" | 21 #include "net/quic/test_tools/quic_test_utils.h" |
| 22 #include "net/test/gtest_util.h" |
21 #include "net/tools/epoll_server/epoll_server.h" | 23 #include "net/tools/epoll_server/epoll_server.h" |
| 24 #include "net/tools/quic/chlo_extractor.h" |
22 #include "net/tools/quic/quic_epoll_alarm_factory.h" | 25 #include "net/tools/quic/quic_epoll_alarm_factory.h" |
23 #include "net/tools/quic/quic_epoll_connection_helper.h" | 26 #include "net/tools/quic/quic_epoll_connection_helper.h" |
24 #include "net/tools/quic/quic_packet_writer_wrapper.h" | 27 #include "net/tools/quic/quic_packet_writer_wrapper.h" |
25 #include "net/tools/quic/quic_simple_server_session_helper.h" | 28 #include "net/tools/quic/quic_simple_server_session_helper.h" |
26 #include "net/tools/quic/quic_time_wait_list_manager.h" | 29 #include "net/tools/quic/quic_time_wait_list_manager.h" |
| 30 #include "net/tools/quic/stateless_rejector.h" |
27 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" | 31 #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" |
28 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" | 32 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" |
29 #include "testing/gmock/include/gmock/gmock.h" | 33 #include "testing/gmock/include/gmock/gmock.h" |
| 34 #include "testing/gmock_mutant.h" |
30 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
31 | 36 |
| 37 using base::IntToString; |
32 using base::StringPiece; | 38 using base::StringPiece; |
33 using net::EpollServer; | 39 using net::EpollServer; |
34 using net::test::ConstructEncryptedPacket; | 40 using net::test::ConstructEncryptedPacket; |
35 using net::test::CryptoTestUtils; | 41 using net::test::CryptoTestUtils; |
36 using net::test::MockQuicConnection; | 42 using net::test::MockQuicConnection; |
37 using net::test::MockQuicConnectionHelper; | 43 using net::test::MockQuicConnectionHelper; |
38 using net::test::ValueRestore; | 44 using net::test::ValueRestore; |
| 45 using std::ostream; |
39 using std::string; | 46 using std::string; |
40 using std::vector; | 47 using std::vector; |
| 48 using testing::CreateFunctor; |
41 using testing::DoAll; | 49 using testing::DoAll; |
42 using testing::InSequence; | 50 using testing::InSequence; |
43 using testing::Invoke; | 51 using testing::Invoke; |
44 using testing::WithoutArgs; | 52 using testing::WithoutArgs; |
45 using testing::_; | 53 using testing::_; |
46 | 54 |
| 55 static const size_t kDefaultMaxConnectionsInStore = 100; |
| 56 |
47 namespace net { | 57 namespace net { |
48 namespace test { | 58 namespace test { |
49 namespace { | 59 namespace { |
50 | 60 |
51 class TestQuicSpdyServerSession : public QuicServerSessionBase { | 61 class TestQuicSpdyServerSession : public QuicServerSessionBase { |
52 public: | 62 public: |
53 TestQuicSpdyServerSession(const QuicConfig& config, | 63 TestQuicSpdyServerSession(const QuicConfig& config, |
54 QuicConnection* connection, | 64 QuicConnection* connection, |
55 const QuicCryptoServerConfig* crypto_config, | 65 const QuicCryptoServerConfig* crypto_config, |
56 QuicCompressedCertsCache* compressed_certs_cache) | 66 QuicCompressedCertsCache* compressed_certs_cache) |
57 : QuicServerSessionBase(config, | 67 : QuicServerSessionBase(config, |
58 connection, | 68 connection, |
59 nullptr, | 69 nullptr, |
60 nullptr, | 70 nullptr, |
61 crypto_config, | 71 crypto_config, |
62 compressed_certs_cache), | 72 compressed_certs_cache), |
63 crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {} | 73 crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {} |
64 ~TestQuicSpdyServerSession() override{}; | 74 |
| 75 ~TestQuicSpdyServerSession() override { delete connection(); }; |
65 | 76 |
66 MOCK_METHOD3(OnConnectionClosed, | 77 MOCK_METHOD3(OnConnectionClosed, |
67 void(QuicErrorCode error, | 78 void(QuicErrorCode error, |
68 const string& error_details, | 79 const string& error_details, |
69 ConnectionCloseSource source)); | 80 ConnectionCloseSource source)); |
70 MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); | 81 MOCK_METHOD1(CreateIncomingDynamicStream, QuicSpdyStream*(QuicStreamId id)); |
71 MOCK_METHOD1(CreateOutgoingDynamicStream, | 82 MOCK_METHOD1(CreateOutgoingDynamicStream, |
72 QuicSpdyStream*(SpdyPriority priority)); | 83 QuicSpdyStream*(SpdyPriority priority)); |
73 | 84 |
74 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( | 85 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), | 118 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), |
108 std::unique_ptr<QuicServerSessionBase::Helper>( | 119 std::unique_ptr<QuicServerSessionBase::Helper>( |
109 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), | 120 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), |
110 std::unique_ptr<QuicEpollAlarmFactory>( | 121 std::unique_ptr<QuicEpollAlarmFactory>( |
111 new QuicEpollAlarmFactory(eps))) {} | 122 new QuicEpollAlarmFactory(eps))) {} |
112 | 123 |
113 MOCK_METHOD2(CreateQuicSession, | 124 MOCK_METHOD2(CreateQuicSession, |
114 QuicServerSessionBase*(QuicConnectionId connection_id, | 125 QuicServerSessionBase*(QuicConnectionId connection_id, |
115 const IPEndPoint& client_address)); | 126 const IPEndPoint& client_address)); |
116 | 127 |
| 128 MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id)); |
| 129 |
117 using QuicDispatcher::current_server_address; | 130 using QuicDispatcher::current_server_address; |
118 using QuicDispatcher::current_client_address; | 131 using QuicDispatcher::current_client_address; |
119 }; | 132 }; |
120 | 133 |
121 // A Connection class which unregisters the session from the dispatcher when | 134 // A Connection class which unregisters the session from the dispatcher when |
122 // sending connection close. | 135 // sending connection close. |
123 // It'd be slightly more realistic to do this from the Session but it would | 136 // It'd be slightly more realistic to do this from the Session but it would |
124 // involve a lot more mocking. | 137 // involve a lot more mocking. |
125 class MockServerConnection : public MockQuicConnection { | 138 class MockServerConnection : public MockQuicConnection { |
126 public: | 139 public: |
(...skipping 10 matching lines...) Expand all Loading... |
137 void UnregisterOnConnectionClosed() { | 150 void UnregisterOnConnectionClosed() { |
138 LOG(ERROR) << "Unregistering " << connection_id(); | 151 LOG(ERROR) << "Unregistering " << connection_id(); |
139 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, | 152 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, |
140 "Unregistering."); | 153 "Unregistering."); |
141 } | 154 } |
142 | 155 |
143 private: | 156 private: |
144 QuicDispatcher* dispatcher_; | 157 QuicDispatcher* dispatcher_; |
145 }; | 158 }; |
146 | 159 |
147 QuicServerSessionBase* CreateSession( | |
148 QuicDispatcher* dispatcher, | |
149 const QuicConfig& config, | |
150 QuicConnectionId connection_id, | |
151 const IPEndPoint& client_address, | |
152 MockQuicConnectionHelper* helper, | |
153 MockAlarmFactory* alarm_factory, | |
154 const QuicCryptoServerConfig* crypto_config, | |
155 QuicCompressedCertsCache* compressed_certs_cache, | |
156 TestQuicSpdyServerSession** session) { | |
157 MockServerConnection* connection = new MockServerConnection( | |
158 connection_id, helper, alarm_factory, dispatcher); | |
159 *session = new TestQuicSpdyServerSession(config, connection, crypto_config, | |
160 compressed_certs_cache); | |
161 connection->set_visitor(*session); | |
162 ON_CALL(*connection, CloseConnection(_, _, _)) | |
163 .WillByDefault(WithoutArgs(Invoke( | |
164 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | |
165 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>((*session)->connection()), | |
166 ProcessUdpPacket(_, client_address, _)); | |
167 | |
168 return *session; | |
169 } | |
170 | |
171 class QuicDispatcherTest : public ::testing::Test { | 160 class QuicDispatcherTest : public ::testing::Test { |
172 public: | 161 public: |
173 QuicDispatcherTest() | 162 QuicDispatcherTest() |
174 : helper_(&eps_, QuicAllocator::BUFFER_POOL), | 163 : helper_(&eps_, QuicAllocator::BUFFER_POOL), |
175 alarm_factory_(&eps_), | 164 alarm_factory_(&eps_), |
176 version_manager_(QuicSupportedVersions()), | 165 version_manager_(AllSupportedVersions()), |
177 crypto_config_(QuicCryptoServerConfig::TESTING, | 166 crypto_config_(QuicCryptoServerConfig::TESTING, |
178 QuicRandom::GetInstance(), | 167 QuicRandom::GetInstance(), |
179 CryptoTestUtils::ProofSourceForTesting()), | 168 CryptoTestUtils::ProofSourceForTesting()), |
180 dispatcher_(new TestDispatcher(config_, | 169 dispatcher_(new TestDispatcher(config_, |
181 &crypto_config_, | 170 &crypto_config_, |
182 &version_manager_, | 171 &version_manager_, |
183 &eps_)), | 172 &eps_)), |
184 time_wait_list_manager_(nullptr), | 173 time_wait_list_manager_(nullptr), |
185 session1_(nullptr), | 174 session1_(nullptr), |
186 session2_(nullptr) { | 175 session2_(nullptr), |
| 176 store_(nullptr) {} |
| 177 |
| 178 void SetUp() override { |
187 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); | 179 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); |
188 } | 180 } |
189 | 181 |
190 ~QuicDispatcherTest() override {} | 182 ~QuicDispatcherTest() override {} |
191 | 183 |
192 MockQuicConnection* connection1() { | 184 MockQuicConnection* connection1() { |
193 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); | 185 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); |
194 } | 186 } |
195 | 187 |
196 MockQuicConnection* connection2() { | 188 MockQuicConnection* connection2() { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 void ProcessPacket(IPEndPoint client_address, | 220 void ProcessPacket(IPEndPoint client_address, |
229 QuicConnectionId connection_id, | 221 QuicConnectionId connection_id, |
230 bool has_version_flag, | 222 bool has_version_flag, |
231 bool has_multipath_flag, | 223 bool has_multipath_flag, |
232 const string& data, | 224 const string& data, |
233 QuicConnectionIdLength connection_id_length, | 225 QuicConnectionIdLength connection_id_length, |
234 QuicPacketNumberLength packet_number_length, | 226 QuicPacketNumberLength packet_number_length, |
235 QuicPathId path_id, | 227 QuicPathId path_id, |
236 QuicPacketNumber packet_number) { | 228 QuicPacketNumber packet_number) { |
237 ProcessPacket(client_address, connection_id, has_version_flag, | 229 ProcessPacket(client_address, connection_id, has_version_flag, |
238 QuicSupportedVersions().front(), data, connection_id_length, | 230 CurrentSupportedVersions().front(), data, |
239 packet_number_length, packet_number); | 231 connection_id_length, packet_number_length, packet_number); |
240 } | 232 } |
241 | 233 |
242 // Processes a packet. | 234 // Processes a packet. |
243 void ProcessPacket(IPEndPoint client_address, | 235 void ProcessPacket(IPEndPoint client_address, |
244 QuicConnectionId connection_id, | 236 QuicConnectionId connection_id, |
245 bool has_version_flag, | 237 bool has_version_flag, |
246 QuicVersion version, | 238 QuicVersion version, |
247 const string& data, | 239 const string& data, |
248 QuicConnectionIdLength connection_id_length, | 240 QuicConnectionIdLength connection_id_length, |
249 QuicPacketNumberLength packet_number_length, | 241 QuicPacketNumberLength packet_number_length, |
250 QuicPacketNumber packet_number) { | 242 QuicPacketNumber packet_number) { |
251 QuicVersionVector versions(SupportedVersions(version)); | 243 QuicVersionVector versions(SupportedVersions(version)); |
252 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( | 244 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( |
253 connection_id, has_version_flag, false, false, 0, packet_number, data, | 245 connection_id, has_version_flag, false, false, 0, packet_number, data, |
254 connection_id_length, packet_number_length, &versions)); | 246 connection_id_length, packet_number_length, &versions)); |
255 std::unique_ptr<QuicReceivedPacket> received_packet( | 247 std::unique_ptr<QuicReceivedPacket> received_packet( |
256 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); | 248 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); |
257 | 249 |
258 data_ = string(packet->data(), packet->length()); | 250 if (ChloExtractor::Extract(*packet, versions, nullptr)) { |
| 251 // Add CHLO packet to the beginning to be verified first, because it is |
| 252 // also processed first by new session. |
| 253 data_connection_map_[connection_id].push_front( |
| 254 string(packet->data(), packet->length())); |
| 255 } else { |
| 256 // For non-CHLO, always append to last. |
| 257 data_connection_map_[connection_id].push_back( |
| 258 string(packet->data(), packet->length())); |
| 259 } |
259 dispatcher_->ProcessPacket(server_address_, client_address, | 260 dispatcher_->ProcessPacket(server_address_, client_address, |
260 *received_packet); | 261 *received_packet); |
261 } | 262 } |
262 | 263 |
263 void ValidatePacket(const QuicEncryptedPacket& packet) { | 264 void ValidatePacket(QuicConnectionId conn_id, |
264 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); | 265 const QuicEncryptedPacket& packet) { |
265 EXPECT_EQ(data_, packet.AsStringPiece()); | 266 EXPECT_EQ(data_connection_map_[conn_id].front().length(), |
| 267 packet.AsStringPiece().length()); |
| 268 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece()); |
| 269 data_connection_map_[conn_id].pop_front(); |
| 270 } |
| 271 |
| 272 QuicServerSessionBase* CreateSession( |
| 273 QuicDispatcher* dispatcher, |
| 274 const QuicConfig& config, |
| 275 QuicConnectionId connection_id, |
| 276 const IPEndPoint& client_address, |
| 277 MockQuicConnectionHelper* helper, |
| 278 MockAlarmFactory* alarm_factory, |
| 279 const QuicCryptoServerConfig* crypto_config, |
| 280 QuicCompressedCertsCache* compressed_certs_cache, |
| 281 TestQuicSpdyServerSession** session) { |
| 282 MockServerConnection* connection = new MockServerConnection( |
| 283 connection_id, helper, alarm_factory, dispatcher); |
| 284 *session = new TestQuicSpdyServerSession(config, connection, crypto_config, |
| 285 compressed_certs_cache); |
| 286 connection->set_visitor(*session); |
| 287 ON_CALL(*connection, CloseConnection(_, _, _)) |
| 288 .WillByDefault(WithoutArgs(Invoke( |
| 289 connection, &MockServerConnection::UnregisterOnConnectionClosed))); |
| 290 return *session; |
266 } | 291 } |
267 | 292 |
268 void CreateTimeWaitListManager() { | 293 void CreateTimeWaitListManager() { |
269 time_wait_list_manager_ = new MockTimeWaitListManager( | 294 time_wait_list_manager_ = new MockTimeWaitListManager( |
270 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), | 295 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), |
271 &helper_, &alarm_factory_); | 296 &helper_, &alarm_factory_); |
272 // dispatcher_ takes the ownership of time_wait_list_manager_. | 297 // dispatcher_ takes the ownership of time_wait_list_manager_. |
273 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), | 298 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), |
274 time_wait_list_manager_); | 299 time_wait_list_manager_); |
275 } | 300 } |
(...skipping 10 matching lines...) Expand all Loading... |
286 QuicEpollAlarmFactory alarm_factory_; | 311 QuicEpollAlarmFactory alarm_factory_; |
287 MockAlarmFactory mock_alarm_factory_; | 312 MockAlarmFactory mock_alarm_factory_; |
288 QuicConfig config_; | 313 QuicConfig config_; |
289 QuicVersionManager version_manager_; | 314 QuicVersionManager version_manager_; |
290 QuicCryptoServerConfig crypto_config_; | 315 QuicCryptoServerConfig crypto_config_; |
291 IPEndPoint server_address_; | 316 IPEndPoint server_address_; |
292 std::unique_ptr<TestDispatcher> dispatcher_; | 317 std::unique_ptr<TestDispatcher> dispatcher_; |
293 MockTimeWaitListManager* time_wait_list_manager_; | 318 MockTimeWaitListManager* time_wait_list_manager_; |
294 TestQuicSpdyServerSession* session1_; | 319 TestQuicSpdyServerSession* session1_; |
295 TestQuicSpdyServerSession* session2_; | 320 TestQuicSpdyServerSession* session2_; |
296 string data_; | 321 std::map<QuicConnectionId, std::list<string>> data_connection_map_; |
| 322 QuicBufferedPacketStore* store_; |
297 }; | 323 }; |
298 | 324 |
299 TEST_F(QuicDispatcherTest, ProcessPackets) { | 325 TEST_F(QuicDispatcherTest, ProcessPackets) { |
300 IPEndPoint client_address(net::test::Loopback4(), 1); | 326 IPEndPoint client_address(net::test::Loopback4(), 1); |
301 server_address_ = IPEndPoint(net::test::Any4(), 5); | 327 server_address_ = IPEndPoint(net::test::Any4(), 5); |
302 | 328 |
303 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 329 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
304 .WillOnce(testing::Return(CreateSession( | 330 .WillOnce(testing::Return(CreateSession( |
305 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 331 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
306 &mock_alarm_factory_, &crypto_config_, | 332 &mock_alarm_factory_, &crypto_config_, |
307 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 333 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 334 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 335 ProcessUdpPacket(_, _, _)) |
| 336 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 337 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
308 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 338 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
309 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 339 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
310 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 340 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
311 | 341 |
312 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) | 342 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) |
313 .WillOnce(testing::Return(CreateSession( | 343 .WillOnce(testing::Return(CreateSession( |
314 dispatcher_.get(), config_, 2, client_address, &mock_helper_, | 344 dispatcher_.get(), config_, 2, client_address, &mock_helper_, |
315 &mock_alarm_factory_, &crypto_config_, | 345 &mock_alarm_factory_, &crypto_config_, |
316 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); | 346 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); |
| 347 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), |
| 348 ProcessUdpPacket(_, _, _)) |
| 349 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 350 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); |
317 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 351 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
318 | 352 |
319 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 353 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
320 ProcessUdpPacket(_, _, _)) | 354 ProcessUdpPacket(_, _, _)) |
321 .Times(1) | 355 .Times(1) |
322 .WillOnce(testing::WithArgs<2>( | 356 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
323 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 357 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
324 ProcessPacket(client_address, 1, false, false, "data"); | 358 ProcessPacket(client_address, 1, false, false, "data"); |
325 } | 359 } |
326 | 360 |
327 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { | 361 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { |
328 IPEndPoint client_address(net::test::Loopback4(), 1); | 362 IPEndPoint client_address(net::test::Loopback4(), 1); |
329 server_address_ = IPEndPoint(net::test::Any4(), 5); | 363 server_address_ = IPEndPoint(net::test::Any4(), 5); |
330 | 364 |
331 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); | 365 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); |
332 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); | 366 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); |
333 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), | 367 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), |
334 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); | 368 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); |
335 } | 369 } |
336 | 370 |
337 TEST_F(QuicDispatcherTest, Shutdown) { | 371 TEST_F(QuicDispatcherTest, Shutdown) { |
338 IPEndPoint client_address(net::test::Loopback4(), 1); | 372 IPEndPoint client_address(net::test::Loopback4(), 1); |
339 | 373 |
340 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 374 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
341 .WillOnce(testing::Return(CreateSession( | 375 .WillOnce(testing::Return(CreateSession( |
342 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 376 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
343 &mock_alarm_factory_, &crypto_config_, | 377 &mock_alarm_factory_, &crypto_config_, |
344 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 378 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 379 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 380 ProcessUdpPacket(_, _, _)) |
| 381 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 382 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
345 | 383 |
346 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 384 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
347 | 385 |
348 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 386 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
349 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 387 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
350 | 388 |
351 dispatcher_->Shutdown(); | 389 dispatcher_->Shutdown(); |
352 } | 390 } |
353 | 391 |
354 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 392 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
355 CreateTimeWaitListManager(); | 393 CreateTimeWaitListManager(); |
356 | 394 |
357 // Create a new session. | 395 // Create a new session. |
358 IPEndPoint client_address(net::test::Loopback4(), 1); | 396 IPEndPoint client_address(net::test::Loopback4(), 1); |
359 QuicConnectionId connection_id = 1; | 397 QuicConnectionId connection_id = 1; |
360 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 398 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
361 .WillOnce(testing::Return(CreateSession( | 399 .WillOnce(testing::Return(CreateSession( |
362 dispatcher_.get(), config_, connection_id, client_address, | 400 dispatcher_.get(), config_, connection_id, client_address, |
363 &mock_helper_, &mock_alarm_factory_, &crypto_config_, | 401 &mock_helper_, &mock_alarm_factory_, &crypto_config_, |
364 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 402 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 403 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 404 ProcessUdpPacket(_, _, _)) |
| 405 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 406 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
| 407 |
365 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 408 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
366 | 409 |
367 // Close the connection by sending public reset packet. | 410 // Close the connection by sending public reset packet. |
368 QuicPublicResetPacket packet; | 411 QuicPublicResetPacket packet; |
369 packet.public_header.connection_id = connection_id; | 412 packet.public_header.connection_id = connection_id; |
370 packet.public_header.reset_flag = true; | 413 packet.public_header.reset_flag = true; |
371 packet.public_header.version_flag = false; | 414 packet.public_header.version_flag = false; |
372 packet.rejected_packet_number = 19191; | 415 packet.rejected_packet_number = 19191; |
373 packet.nonce_proof = 132232; | 416 packet.nonce_proof = 132232; |
374 std::unique_ptr<QuicEncryptedPacket> encrypted( | 417 std::unique_ptr<QuicEncryptedPacket> encrypted( |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { | 475 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { |
433 IPEndPoint client_address(net::test::Loopback4(), 1); | 476 IPEndPoint client_address(net::test::Loopback4(), 1); |
434 QuicConnectionId connection_id = 1; | 477 QuicConnectionId connection_id = 1; |
435 server_address_ = IPEndPoint(net::test::Any4(), 5); | 478 server_address_ = IPEndPoint(net::test::Any4(), 5); |
436 | 479 |
437 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) | 480 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) |
438 .WillOnce(testing::Return(CreateSession( | 481 .WillOnce(testing::Return(CreateSession( |
439 dispatcher_.get(), config_, 1, client_address, &mock_helper_, | 482 dispatcher_.get(), config_, 1, client_address, &mock_helper_, |
440 &mock_alarm_factory_, &crypto_config_, | 483 &mock_alarm_factory_, &crypto_config_, |
441 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 484 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 485 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 486 ProcessUdpPacket(_, _, _)) |
| 487 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 488 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
442 // A packet whose packet number is the largest that is allowed to start a | 489 // A packet whose packet number is the largest that is allowed to start a |
443 // connection. | 490 // connection. |
444 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), | 491 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), |
445 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, | 492 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
446 kDefaultPathId, | 493 kDefaultPathId, |
447 QuicDispatcher::kMaxReasonableInitialPacketNumber); | 494 QuicDispatcher::kMaxReasonableInitialPacketNumber); |
448 EXPECT_EQ(client_address, dispatcher_->current_client_address()); | 495 EXPECT_EQ(client_address, dispatcher_->current_client_address()); |
449 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); | 496 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); |
450 } | 497 } |
451 | 498 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 } | 575 } |
529 } | 576 } |
530 } | 577 } |
531 return params; | 578 return params; |
532 } | 579 } |
533 | 580 |
534 class QuicDispatcherStatelessRejectTest | 581 class QuicDispatcherStatelessRejectTest |
535 : public QuicDispatcherTest, | 582 : public QuicDispatcherTest, |
536 public ::testing::WithParamInterface<StatelessRejectTestParams> { | 583 public ::testing::WithParamInterface<StatelessRejectTestParams> { |
537 public: | 584 public: |
538 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} | 585 QuicDispatcherStatelessRejectTest() |
| 586 : QuicDispatcherTest(), crypto_stream1_(nullptr) {} |
539 | 587 |
540 ~QuicDispatcherStatelessRejectTest() override { | 588 ~QuicDispatcherStatelessRejectTest() override { |
541 if (crypto_stream1_) { | 589 if (crypto_stream1_) { |
542 delete crypto_stream1_; | 590 delete crypto_stream1_; |
543 } | 591 } |
544 } | 592 } |
545 | 593 |
546 // This test setup assumes that all testing will be done using | 594 // This test setup assumes that all testing will be done using |
547 // crypto_stream1_. | 595 // crypto_stream1_. |
548 void SetUp() override { | 596 void SetUp() override { |
| 597 QuicDispatcherTest::SetUp(); |
549 FLAGS_enable_quic_stateless_reject_support = | 598 FLAGS_enable_quic_stateless_reject_support = |
550 GetParam().enable_stateless_rejects_via_flag; | 599 GetParam().enable_stateless_rejects_via_flag; |
551 } | 600 } |
552 | 601 |
553 // Returns true or false, depending on whether the server will emit | 602 // Returns true or false, depending on whether the server will emit |
554 // a stateless reject, depending upon the parameters of the test. | 603 // a stateless reject, depending upon the parameters of the test. |
555 bool ExpectStatelessReject() { | 604 bool ExpectStatelessReject() { |
556 return GetParam().enable_stateless_rejects_via_flag && | 605 return GetParam().enable_stateless_rejects_via_flag && |
557 !GetParam().crypto_handshake_successful && | 606 !GetParam().crypto_handshake_successful && |
558 GetParam().client_supports_statelesss_rejects; | 607 GetParam().client_supports_statelesss_rejects; |
(...skipping 30 matching lines...) Expand all Loading... |
589 ::testing::ValuesIn(GetStatelessRejectTestParams())); | 638 ::testing::ValuesIn(GetStatelessRejectTestParams())); |
590 | 639 |
591 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { | 640 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { |
592 CreateTimeWaitListManager(); | 641 CreateTimeWaitListManager(); |
593 | 642 |
594 IPEndPoint client_address(net::test::Loopback4(), 1); | 643 IPEndPoint client_address(net::test::Loopback4(), 1); |
595 QuicConnectionId connection_id = 1; | 644 QuicConnectionId connection_id = 1; |
596 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 645 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
597 .WillOnce(testing::Return( | 646 .WillOnce(testing::Return( |
598 CreateSessionBasedOnTestParams(connection_id, client_address))); | 647 CreateSessionBasedOnTestParams(connection_id, client_address))); |
599 | 648 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 649 ProcessUdpPacket(_, _, _)) |
| 650 .WillOnce(testing::WithArgs<2>( |
| 651 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 652 base::Unretained(this), connection_id)))); |
600 // Process the first packet for the connection. | 653 // Process the first packet for the connection. |
601 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); | 654 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); |
602 if (ExpectStatelessReject()) { | 655 if (ExpectStatelessReject()) { |
603 // If this is a stateless reject, the crypto stream will close the | 656 // If this is a stateless reject, the crypto stream will close the |
604 // connection. | 657 // connection. |
605 session1_->connection()->CloseConnection( | 658 session1_->connection()->CloseConnection( |
606 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", | 659 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", |
607 ConnectionCloseBehavior::SILENT_CLOSE); | 660 ConnectionCloseBehavior::SILENT_CLOSE); |
608 } | 661 } |
609 | 662 |
610 // Send a second packet and check the results. If this is a stateless reject, | 663 // Send a second packet and check the results. If this is a stateless reject, |
611 // the existing connection_id will go on the time-wait list. | 664 // the existing connection_id will go on the time-wait list. |
612 EXPECT_EQ(ExpectStatelessReject(), | 665 EXPECT_EQ(ExpectStatelessReject(), |
613 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
614 if (ExpectStatelessReject()) { | 667 if (ExpectStatelessReject()) { |
615 // The second packet will be processed on the time-wait list. | 668 // The second packet will be processed on the time-wait list. |
616 EXPECT_CALL(*time_wait_list_manager_, | 669 EXPECT_CALL(*time_wait_list_manager_, |
617 ProcessPacket(_, _, connection_id, _, _)) | 670 ProcessPacket(_, _, connection_id, _, _)) |
618 .Times(1); | 671 .Times(1); |
619 } else { | 672 } else { |
620 // The second packet will trigger a packet-validation | 673 // The second packet will trigger a packet-validation |
621 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 674 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
622 ProcessUdpPacket(_, _, _)) | 675 ProcessUdpPacket(_, _, _)) |
623 .Times(1) | 676 .Times(1) |
624 .WillOnce(testing::WithArgs<2>( | 677 .WillOnce(testing::WithArgs<2>( |
625 Invoke(this, &QuicDispatcherTest::ValidatePacket))); | 678 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 679 base::Unretained(this), connection_id)))); |
626 } | 680 } |
627 ProcessPacket(client_address, connection_id, true, false, "data"); | 681 ProcessPacket(client_address, connection_id, true, false, "data"); |
628 } | 682 } |
629 | 683 |
630 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { | 684 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { |
631 FLAGS_quic_use_cheap_stateless_rejects = true; | 685 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 686 FLAGS_quic_buffer_packet_till_chlo = true; |
632 CreateTimeWaitListManager(); | 687 CreateTimeWaitListManager(); |
633 | 688 |
634 IPEndPoint client_address(net::test::Loopback4(), 1); | 689 IPEndPoint client_address(net::test::Loopback4(), 1); |
635 QuicConnectionId connection_id = 1; | 690 QuicConnectionId connection_id = 1; |
636 if (GetParam().enable_stateless_rejects_via_flag) { | 691 if (GetParam().enable_stateless_rejects_via_flag) { |
637 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 692 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
638 .Times(0); | 693 .Times(0); |
639 } else { | 694 } else { |
640 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 695 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
641 .WillOnce(testing::Return( | 696 .WillOnce(testing::Return( |
642 CreateSessionBasedOnTestParams(connection_id, client_address))); | 697 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 698 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 699 ProcessUdpPacket(_, _, _)) |
| 700 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 701 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
643 } | 702 } |
644 | 703 |
645 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); | 704 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); |
646 VLOG(1) << "Params: " << GetParam(); | 705 VLOG(1) << "Params: " << GetParam(); |
647 // Process the first packet for the connection. | 706 // Process the first packet for the connection. |
648 // clang-format off | 707 // clang-format off |
649 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 708 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
650 "CHLO", | 709 "CHLO", |
651 "AEAD", "AESG", | 710 "AEAD", "AESG", |
652 "KEXS", "C255", | 711 "KEXS", "C255", |
653 "COPT", "SREJ", | 712 "COPT", "SREJ", |
654 "NONC", "1234567890123456789012", | 713 "NONC", "1234567890123456789012", |
655 "VER\0", "Q025", | 714 "VER\0", "Q025", |
656 "$padding", static_cast<int>(kClientHelloMinimumSize), | 715 "$padding", static_cast<int>(kClientHelloMinimumSize), |
657 nullptr); | 716 nullptr); |
658 // clang-format on | 717 // clang-format on |
659 | 718 |
660 ProcessPacket(client_address, connection_id, true, false, | 719 ProcessPacket(client_address, connection_id, true, false, |
661 client_hello.GetSerialized().AsStringPiece().as_string()); | 720 client_hello.GetSerialized().AsStringPiece().as_string()); |
662 | 721 |
663 if (GetParam().enable_stateless_rejects_via_flag) { | 722 if (GetParam().enable_stateless_rejects_via_flag) { |
664 EXPECT_EQ(true, | 723 EXPECT_EQ(true, |
665 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 724 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
666 } | 725 } |
667 } | 726 } |
668 | 727 |
669 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { | 728 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { |
670 FLAGS_quic_use_cheap_stateless_rejects = true; | 729 FLAGS_quic_use_cheap_stateless_rejects = true; |
| 730 FLAGS_quic_always_log_bugs_for_tests = true; |
671 CreateTimeWaitListManager(); | 731 CreateTimeWaitListManager(); |
672 | 732 |
673 const IPEndPoint client_address(net::test::Loopback4(), 1); | 733 const IPEndPoint client_address(net::test::Loopback4(), 1); |
674 const QuicConnectionId connection_id = 1; | 734 const QuicConnectionId connection_id = 1; |
675 | 735 |
676 if (!GetParam().enable_stateless_rejects_via_flag) { | 736 if (!GetParam().enable_stateless_rejects_via_flag && |
677 // If stateless rejects are not being used, then a connection will be | 737 !FLAGS_quic_buffer_packet_till_chlo) { |
678 // created immediately. | 738 // If stateless rejects are not being used and early arrived packets are not |
| 739 // buffered, then a connection will be created immediately. |
679 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 740 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
680 .WillOnce(testing::Return( | 741 .WillOnce(testing::Return( |
681 CreateSessionBasedOnTestParams(connection_id, client_address))); | 742 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 743 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 744 ProcessUdpPacket(_, client_address, _)) |
| 745 .WillOnce(testing::WithArg<2>( |
| 746 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 747 base::Unretained(this), connection_id)))); |
682 } | 748 } |
683 ProcessPacket(client_address, connection_id, true, false, | 749 bool first_packet_dropped = GetParam().enable_stateless_rejects_via_flag && |
684 "NOT DATA FOR A CHLO"); | 750 !FLAGS_quic_buffer_packet_till_chlo; |
| 751 if (first_packet_dropped) { |
| 752 // Never do stateless reject while |
| 753 // FLAGS_quic_buffer_packet_till_chlo is off. |
| 754 EXPECT_DFATAL( |
| 755 ProcessPacket(client_address, connection_id, true, false, |
| 756 "NOT DATA FOR A CHLO"), |
| 757 "Have to drop packet because buffering non-chlo packet is " |
| 758 "not supported while trying to do stateless reject. " |
| 759 "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false " |
| 760 "--gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"); |
| 761 } else { |
| 762 ProcessPacket(client_address, connection_id, true, false, |
| 763 "NOT DATA FOR A CHLO"); |
| 764 } |
685 | 765 |
686 // Process the first packet for the connection. | 766 // Process the first packet for the connection. |
687 // clang-format off | 767 // clang-format off |
688 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 768 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
689 "CHLO", | 769 "CHLO", |
690 "AEAD", "AESG", | 770 "AEAD", "AESG", |
691 "KEXS", "C255", | 771 "KEXS", "C255", |
692 "NONC", "1234567890123456789012", | 772 "NONC", "1234567890123456789012", |
693 "VER\0", "Q025", | 773 "VER\0", "Q025", |
694 "$padding", static_cast<int>(kClientHelloMinimumSize), | 774 "$padding", static_cast<int>(kClientHelloMinimumSize), |
695 nullptr); | 775 nullptr); |
696 // clang-format on | 776 // clang-format on |
697 | 777 |
698 if (GetParam().enable_stateless_rejects_via_flag) { | 778 if (GetParam().enable_stateless_rejects_via_flag || |
| 779 FLAGS_quic_buffer_packet_till_chlo) { |
699 // If stateless rejects are enabled then a connection will be created now | 780 // If stateless rejects are enabled then a connection will be created now |
700 // and the buffered packet will be processed | 781 // and the buffered packet will be processed |
701 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) | 782 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) |
702 .WillOnce(testing::Return( | 783 .WillOnce(testing::Return( |
703 CreateSessionBasedOnTestParams(connection_id, client_address))); | 784 CreateSessionBasedOnTestParams(connection_id, client_address))); |
| 785 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 786 ProcessUdpPacket(_, client_address, _)) |
| 787 .WillOnce(testing::WithArg<2>( |
| 788 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 789 base::Unretained(this), connection_id)))); |
704 } | 790 } |
705 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), | 791 if (!first_packet_dropped) { |
706 ProcessUdpPacket(_, client_address, _)) | 792 // Expect both packets to be passed to ProcessUdpPacket(). And one of them |
707 .RetiresOnSaturation(); | 793 // is already expected in CreateSessionBasedOnTestParams(). |
| 794 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 795 ProcessUdpPacket(_, client_address, _)) |
| 796 .WillOnce(testing::WithArg<2>( |
| 797 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 798 base::Unretained(this), connection_id)))) |
| 799 .RetiresOnSaturation(); |
| 800 } else { |
| 801 // Since first packet is dropped, remove it from map to skip |
| 802 // ValidatePacket() on it. |
| 803 data_connection_map_[connection_id].pop_front(); |
| 804 } |
708 ProcessPacket(client_address, connection_id, true, false, | 805 ProcessPacket(client_address, connection_id, true, false, |
709 client_hello.GetSerialized().AsStringPiece().as_string()); | 806 client_hello.GetSerialized().AsStringPiece().as_string()); |
710 EXPECT_FALSE( | 807 EXPECT_FALSE( |
711 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 808 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
712 } | 809 } |
713 | 810 |
714 // Verify the stopgap test: Packets with truncated connection IDs should be | 811 // Verify the stopgap test: Packets with truncated connection IDs should be |
715 // dropped. | 812 // dropped. |
716 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; | 813 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; |
717 | 814 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 LOG(DFATAL) << "Not supported"; | 848 LOG(DFATAL) << "Not supported"; |
752 return WriteResult(); | 849 return WriteResult(); |
753 } | 850 } |
754 | 851 |
755 bool write_blocked_; | 852 bool write_blocked_; |
756 }; | 853 }; |
757 | 854 |
758 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { | 855 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { |
759 public: | 856 public: |
760 void SetUp() override { | 857 void SetUp() override { |
| 858 QuicDispatcherTest::SetUp(); |
761 writer_ = new BlockingWriter; | 859 writer_ = new BlockingWriter; |
762 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); | 860 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); |
763 | 861 |
764 IPEndPoint client_address(net::test::Loopback4(), 1); | 862 IPEndPoint client_address(net::test::Loopback4(), 1); |
765 | 863 |
766 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 864 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
767 .WillOnce(testing::Return(CreateSession( | 865 .WillOnce(testing::Return(CreateSession( |
768 dispatcher_.get(), config_, 1, client_address, &helper_, | 866 dispatcher_.get(), config_, 1, client_address, &helper_, |
769 &alarm_factory_, &crypto_config_, | 867 &alarm_factory_, &crypto_config_, |
770 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); | 868 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 869 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 870 ProcessUdpPacket(_, _, _)) |
| 871 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 872 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); |
771 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); | 873 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); |
772 | 874 |
773 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) | 875 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) |
774 .WillOnce(testing::Return(CreateSession( | 876 .WillOnce(testing::Return(CreateSession( |
775 dispatcher_.get(), config_, 2, client_address, &helper_, | 877 dispatcher_.get(), config_, 2, client_address, &helper_, |
776 &alarm_factory_, &crypto_config_, | 878 &alarm_factory_, &crypto_config_, |
777 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); | 879 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); |
| 880 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), |
| 881 ProcessUdpPacket(_, _, _)) |
| 882 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( |
| 883 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); |
778 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); | 884 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); |
779 | 885 |
780 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); | 886 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); |
781 } | 887 } |
782 | 888 |
783 void TearDown() override { | 889 void TearDown() override { |
784 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 890 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
785 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); | 891 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); |
786 dispatcher_->Shutdown(); | 892 dispatcher_->Shutdown(); |
787 } | 893 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 1030 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
925 dispatcher_->OnCanWrite(); | 1031 dispatcher_->OnCanWrite(); |
926 EXPECT_TRUE(dispatcher_->HasPendingWrites()); | 1032 EXPECT_TRUE(dispatcher_->HasPendingWrites()); |
927 | 1033 |
928 // And we'll resume where we left off when we get another call. | 1034 // And we'll resume where we left off when we get another call. |
929 EXPECT_CALL(*connection2(), OnCanWrite()); | 1035 EXPECT_CALL(*connection2(), OnCanWrite()); |
930 dispatcher_->OnCanWrite(); | 1036 dispatcher_->OnCanWrite(); |
931 EXPECT_FALSE(dispatcher_->HasPendingWrites()); | 1037 EXPECT_FALSE(dispatcher_->HasPendingWrites()); |
932 } | 1038 } |
933 | 1039 |
| 1040 // Tests that bufferring packets works in stateful reject, expensive stateless |
| 1041 // reject and cheap stateless reject. |
| 1042 struct BufferedPacketStoreTestParams { |
| 1043 BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag, |
| 1044 bool support_cheap_stateless_reject) |
| 1045 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag), |
| 1046 support_cheap_stateless_reject(support_cheap_stateless_reject) {} |
| 1047 |
| 1048 friend ostream& operator<<(ostream& os, |
| 1049 const BufferedPacketStoreTestParams& p) { |
| 1050 os << "{ enable_stateless_rejects_via_flag: " |
| 1051 << p.enable_stateless_rejects_via_flag << std::endl; |
| 1052 os << " support_cheap_stateless_reject: " |
| 1053 << p.support_cheap_stateless_reject << " }"; |
| 1054 return os; |
| 1055 } |
| 1056 |
| 1057 // This only enables the stateless reject feature via the feature-flag. |
| 1058 // This should be a no-op if the peer does not support them. |
| 1059 bool enable_stateless_rejects_via_flag; |
| 1060 // Whether to do cheap stateless or not. |
| 1061 bool support_cheap_stateless_reject; |
| 1062 }; |
| 1063 |
| 1064 vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() { |
| 1065 vector<BufferedPacketStoreTestParams> params; |
| 1066 for (bool enable_stateless_rejects_via_flag : {true, false}) { |
| 1067 for (bool support_cheap_stateless_reject : {true, false}) { |
| 1068 params.push_back(BufferedPacketStoreTestParams( |
| 1069 enable_stateless_rejects_via_flag, support_cheap_stateless_reject)); |
| 1070 } |
| 1071 } |
| 1072 return params; |
| 1073 } |
| 1074 |
| 1075 // A dispatcher whose stateless rejector will always ACCEPTs CHLO. |
| 1076 class BufferedPacketStoreTest |
| 1077 : public QuicDispatcherTest, |
| 1078 public ::testing::WithParamInterface<BufferedPacketStoreTestParams> { |
| 1079 public: |
| 1080 BufferedPacketStoreTest() |
| 1081 : QuicDispatcherTest(), client_addr_(Loopback4(), 1234) { |
| 1082 FLAGS_quic_buffer_packet_till_chlo = true; |
| 1083 FLAGS_quic_use_cheap_stateless_rejects = |
| 1084 GetParam().support_cheap_stateless_reject; |
| 1085 FLAGS_enable_quic_stateless_reject_support = |
| 1086 GetParam().enable_stateless_rejects_via_flag; |
| 1087 } |
| 1088 |
| 1089 void SetUp() override { |
| 1090 QuicDispatcherTest::SetUp(); |
| 1091 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock(); |
| 1092 |
| 1093 QuicVersion version = AllSupportedVersions().front(); |
| 1094 CryptoHandshakeMessage chlo = CryptoTestUtils::GenerateDefaultInchoateCHLO( |
| 1095 clock_, version, &crypto_config_); |
| 1096 chlo.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ}); |
| 1097 // Pass an inchoate CHLO. |
| 1098 CryptoTestUtils::GenerateFullCHLO( |
| 1099 chlo, &crypto_config_, server_ip_, client_addr_, version, clock_, |
| 1100 &proof_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &full_chlo_); |
| 1101 } |
| 1102 |
| 1103 string SerializeFullCHLO() { |
| 1104 return full_chlo_.GetSerialized().AsStringPiece().as_string(); |
| 1105 } |
| 1106 |
| 1107 protected: |
| 1108 IPAddress server_ip_; |
| 1109 IPEndPoint client_addr_; |
| 1110 QuicCryptoProof proof_; |
| 1111 const QuicClock* clock_; |
| 1112 CryptoHandshakeMessage full_chlo_; |
| 1113 }; |
| 1114 |
| 1115 INSTANTIATE_TEST_CASE_P( |
| 1116 BufferedPacketStoreTests, |
| 1117 BufferedPacketStoreTest, |
| 1118 ::testing::ValuesIn(GetBufferedPacketStoreTestParams())); |
| 1119 |
| 1120 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { |
| 1121 InSequence s; |
| 1122 IPEndPoint client_address(Loopback4(), 1); |
| 1123 server_address_ = IPEndPoint(Any4(), 5); |
| 1124 QuicConnectionId conn_id = 1; |
| 1125 // A bunch of non-CHLO should be buffered upon arrival, and the first one |
| 1126 // should trigger OnNewConnectionAdded(). |
| 1127 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)).Times(1); |
| 1128 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { |
| 1129 ProcessPacket(client_address, conn_id, true, false, |
| 1130 "data packet " + IntToString(i + 1), |
| 1131 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1132 kDefaultPathId, |
| 1133 /*packet_number=*/i + 1); |
| 1134 } |
| 1135 EXPECT_EQ(0u, dispatcher_->session_map().size()) |
| 1136 << "No session should be created before CHLO arrives."; |
| 1137 |
| 1138 // Pop out the last packet as it is also be dropped by the store. |
| 1139 data_connection_map_[conn_id].pop_back(); |
| 1140 // When CHLO arrives, a new session should be created, and all packets |
| 1141 // buffered should be delivered to the session. |
| 1142 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1143 .WillOnce(testing::Return(CreateSession( |
| 1144 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1145 &mock_alarm_factory_, &crypto_config_, |
| 1146 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1147 |
| 1148 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they |
| 1149 // should be delivered in arrival order. |
| 1150 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1151 ProcessUdpPacket(_, _, _)) |
| 1152 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO. |
| 1153 .WillRepeatedly(testing::WithArg<2>( |
| 1154 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1155 base::Unretained(this), conn_id)))); |
| 1156 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1157 } |
| 1158 |
| 1159 TEST_P(BufferedPacketStoreTest, |
| 1160 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) { |
| 1161 InSequence s; |
| 1162 server_address_ = IPEndPoint(Any4(), 5); |
| 1163 // A bunch of non-CHLO should be buffered upon arrival. |
| 1164 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { |
| 1165 IPEndPoint client_address(Loopback4(), i); |
| 1166 QuicConnectionId conn_id = i; |
| 1167 if (i <= kDefaultMaxConnectionsInStore) { |
| 1168 // As they are on different connection, they should trigger |
| 1169 // OnNewConnectionAdded(). The last packet should be dropped. |
| 1170 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1171 } |
| 1172 ProcessPacket(client_address, conn_id, true, false, |
| 1173 "data packet on connection " + IntToString(i), |
| 1174 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, |
| 1175 kDefaultPathId, |
| 1176 /*packet_number=*/2); |
| 1177 } |
| 1178 |
| 1179 // Pop out the packet on last connection as it shouldn't be enqueued in store |
| 1180 // as well. |
| 1181 data_connection_map_[kDefaultMaxConnectionsInStore + 1].pop_front(); |
| 1182 |
| 1183 // Process CHLOs. |
| 1184 for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { |
| 1185 IPEndPoint client_address(Loopback4(), i); |
| 1186 QuicConnectionId conn_id = i; |
| 1187 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1188 .WillOnce(testing::Return(CreateSession( |
| 1189 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1190 &mock_alarm_factory_, &crypto_config_, |
| 1191 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1192 if (conn_id == kDefaultMaxConnectionsInStore + 1) { |
| 1193 // The last CHLO should trigger OnNewConnectionAdded() since it's the |
| 1194 // first packet arrives on that connection. |
| 1195 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1196 } |
| 1197 // First |kDefaultMaxConnectionsInStore| connections should have buffered |
| 1198 // a packet in store. The rest should have been dropped. |
| 1199 if (i <= kDefaultMaxConnectionsInStore) { |
| 1200 EXPECT_CALL( |
| 1201 *reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1202 ProcessUdpPacket(_, client_address, _)) |
| 1203 .Times(2) |
| 1204 .WillRepeatedly(testing::WithArg<2>( |
| 1205 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1206 base::Unretained(this), conn_id)))); |
| 1207 } |
| 1208 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 // Tests that store delivers empty packet list if CHLO arrives firstly. |
| 1213 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { |
| 1214 QuicConnectionId conn_id = 1; |
| 1215 IPEndPoint client_address(Loopback4(), 1); |
| 1216 EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); |
| 1217 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1218 .WillOnce(testing::Return(CreateSession( |
| 1219 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1220 &mock_alarm_factory_, &crypto_config_, |
| 1221 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1222 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1223 } |
| 1224 |
| 1225 // Tests that by the time a retransmitted CHLO arrives, a connection for the |
| 1226 // CHLO should already be created. |
| 1227 TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { |
| 1228 InSequence s; |
| 1229 IPEndPoint client_address(Loopback4(), 1); |
| 1230 server_address_ = IPEndPoint(Any4(), 5); |
| 1231 QuicConnectionId conn_id = 1; |
| 1232 ProcessPacket(client_address, conn_id, true, false, |
| 1233 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, |
| 1234 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, |
| 1235 /*packet_number=*/2); |
| 1236 |
| 1237 // When CHLO arrives, a new session should be created, and all packets |
| 1238 // buffered should be delivered to the session. |
| 1239 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) |
| 1240 .Times(1) // Only triggered by 1st CHLO. |
| 1241 .WillOnce(testing::Return(CreateSession( |
| 1242 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, |
| 1243 &mock_alarm_factory_, &crypto_config_, |
| 1244 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); |
| 1245 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), |
| 1246 ProcessUdpPacket(_, _, _)) |
| 1247 .Times(3) // Triggered by 1 data packet and 2 CHLOs. |
| 1248 .WillRepeatedly(testing::WithArg<2>( |
| 1249 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, |
| 1250 base::Unretained(this), conn_id)))); |
| 1251 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1252 |
| 1253 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1254 } |
| 1255 |
| 1256 // Tests that expiration of a connection add connection id to time wait list. |
| 1257 TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) { |
| 1258 InSequence s; |
| 1259 CreateTimeWaitListManager(); |
| 1260 QuicBufferedPacketStore* store = |
| 1261 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); |
| 1262 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); |
| 1263 |
| 1264 IPEndPoint client_address(Loopback4(), 1); |
| 1265 server_address_ = IPEndPoint(Any4(), 5); |
| 1266 QuicConnectionId conn_id = 1; |
| 1267 ProcessPacket(client_address, conn_id, true, false, |
| 1268 "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, |
| 1269 PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, |
| 1270 /*packet_number=*/2); |
| 1271 |
| 1272 mock_helper_.AdvanceTime( |
| 1273 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); |
| 1274 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store); |
| 1275 // Cancel alarm as if it had been fired. |
| 1276 alarm->Cancel(); |
| 1277 store->OnExpirationTimeout(); |
| 1278 // New arrived CHLO will be dropped because this connection is in time wait |
| 1279 // list. |
| 1280 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); |
| 1281 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); |
| 1282 ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); |
| 1283 } |
| 1284 |
934 } // namespace | 1285 } // namespace |
935 } // namespace test | 1286 } // namespace test |
936 } // namespace net | 1287 } // namespace net |
OLD | NEW |