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

Side by Side Diff: net/tools/quic/quic_dispatcher_test.cc

Issue 2222393002: Make QuicDispatcher to queue packets for new connections while waiting for CHLOs. Flag protected by… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@129318081
Patch Set: add new files Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/quic/quic_dispatcher.cc ('k') | net/tools/quic/test_tools/packet_reordering_writer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)), 118 new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)),
109 std::unique_ptr<QuicServerSessionBase::Helper>( 119 std::unique_ptr<QuicServerSessionBase::Helper>(
110 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), 120 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())),
111 std::unique_ptr<QuicEpollAlarmFactory>( 121 std::unique_ptr<QuicEpollAlarmFactory>(
112 new QuicEpollAlarmFactory(eps))) {} 122 new QuicEpollAlarmFactory(eps))) {}
113 123
114 MOCK_METHOD2(CreateQuicSession, 124 MOCK_METHOD2(CreateQuicSession,
115 QuicServerSessionBase*(QuicConnectionId connection_id, 125 QuicServerSessionBase*(QuicConnectionId connection_id,
116 const IPEndPoint& client_address)); 126 const IPEndPoint& client_address));
117 127
128 MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id));
129
118 using QuicDispatcher::current_server_address; 130 using QuicDispatcher::current_server_address;
119 using QuicDispatcher::current_client_address; 131 using QuicDispatcher::current_client_address;
120 }; 132 };
121 133
122 // A Connection class which unregisters the session from the dispatcher when 134 // A Connection class which unregisters the session from the dispatcher when
123 // sending connection close. 135 // sending connection close.
124 // 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
125 // involve a lot more mocking. 137 // involve a lot more mocking.
126 class MockServerConnection : public MockQuicConnection { 138 class MockServerConnection : public MockQuicConnection {
127 public: 139 public:
(...skipping 10 matching lines...) Expand all
138 void UnregisterOnConnectionClosed() { 150 void UnregisterOnConnectionClosed() {
139 LOG(ERROR) << "Unregistering " << connection_id(); 151 LOG(ERROR) << "Unregistering " << connection_id();
140 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR, 152 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
141 "Unregistering."); 153 "Unregistering.");
142 } 154 }
143 155
144 private: 156 private:
145 QuicDispatcher* dispatcher_; 157 QuicDispatcher* dispatcher_;
146 }; 158 };
147 159
148 QuicServerSessionBase* CreateSession(
149 QuicDispatcher* dispatcher,
150 const QuicConfig& config,
151 QuicConnectionId connection_id,
152 const IPEndPoint& client_address,
153 MockQuicConnectionHelper* helper,
154 MockAlarmFactory* alarm_factory,
155 const QuicCryptoServerConfig* crypto_config,
156 QuicCompressedCertsCache* compressed_certs_cache,
157 TestQuicSpdyServerSession** session) {
158 MockServerConnection* connection = new MockServerConnection(
159 connection_id, helper, alarm_factory, dispatcher);
160 *session = new TestQuicSpdyServerSession(config, connection, crypto_config,
161 compressed_certs_cache);
162 connection->set_visitor(*session);
163 ON_CALL(*connection, CloseConnection(_, _, _))
164 .WillByDefault(WithoutArgs(Invoke(
165 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
166 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>((*session)->connection()),
167 ProcessUdpPacket(_, client_address, _));
168
169 return *session;
170 }
171
172 class QuicDispatcherTest : public ::testing::Test { 160 class QuicDispatcherTest : public ::testing::Test {
173 public: 161 public:
174 QuicDispatcherTest() 162 QuicDispatcherTest()
175 : helper_(&eps_, QuicAllocator::BUFFER_POOL), 163 : helper_(&eps_, QuicAllocator::BUFFER_POOL),
176 alarm_factory_(&eps_), 164 alarm_factory_(&eps_),
177 version_manager_(QuicSupportedVersions()), 165 version_manager_(QuicSupportedVersions()),
178 crypto_config_(QuicCryptoServerConfig::TESTING, 166 crypto_config_(QuicCryptoServerConfig::TESTING,
179 QuicRandom::GetInstance(), 167 QuicRandom::GetInstance(),
180 CryptoTestUtils::ProofSourceForTesting()), 168 CryptoTestUtils::ProofSourceForTesting()),
181 dispatcher_(new TestDispatcher(config_, 169 dispatcher_(new TestDispatcher(config_,
182 &crypto_config_, 170 &crypto_config_,
183 &version_manager_, 171 &version_manager_,
184 &eps_)), 172 &eps_)),
185 time_wait_list_manager_(nullptr), 173 time_wait_list_manager_(nullptr),
186 session1_(nullptr), 174 session1_(nullptr),
187 session2_(nullptr) { 175 session2_(nullptr),
176 store_(nullptr) {}
177
178 void SetUp() override {
188 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); 179 dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1));
189 } 180 }
190 181
191 ~QuicDispatcherTest() override {} 182 ~QuicDispatcherTest() override {}
192 183
193 MockQuicConnection* connection1() { 184 MockQuicConnection* connection1() {
194 return reinterpret_cast<MockQuicConnection*>(session1_->connection()); 185 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
195 } 186 }
196 187
197 MockQuicConnection* connection2() { 188 MockQuicConnection* connection2() {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 QuicConnectionIdLength connection_id_length, 240 QuicConnectionIdLength connection_id_length,
250 QuicPacketNumberLength packet_number_length, 241 QuicPacketNumberLength packet_number_length,
251 QuicPacketNumber packet_number) { 242 QuicPacketNumber packet_number) {
252 QuicVersionVector versions(SupportedVersions(version)); 243 QuicVersionVector versions(SupportedVersions(version));
253 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( 244 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
254 connection_id, has_version_flag, false, false, 0, packet_number, data, 245 connection_id, has_version_flag, false, false, 0, packet_number, data,
255 connection_id_length, packet_number_length, &versions)); 246 connection_id_length, packet_number_length, &versions));
256 std::unique_ptr<QuicReceivedPacket> received_packet( 247 std::unique_ptr<QuicReceivedPacket> received_packet(
257 ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); 248 ConstructReceivedPacket(*packet, helper_.GetClock()->Now()));
258 249
259 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 }
260 dispatcher_->ProcessPacket(server_address_, client_address, 260 dispatcher_->ProcessPacket(server_address_, client_address,
261 *received_packet); 261 *received_packet);
262 } 262 }
263 263
264 void ValidatePacket(const QuicEncryptedPacket& packet) { 264 void ValidatePacket(QuicConnectionId conn_id,
265 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); 265 const QuicEncryptedPacket& packet) {
266 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;
267 } 291 }
268 292
269 void CreateTimeWaitListManager() { 293 void CreateTimeWaitListManager() {
270 time_wait_list_manager_ = new MockTimeWaitListManager( 294 time_wait_list_manager_ = new MockTimeWaitListManager(
271 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(), 295 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
272 &helper_, &alarm_factory_); 296 &helper_, &alarm_factory_);
273 // dispatcher_ takes the ownership of time_wait_list_manager_. 297 // dispatcher_ takes the ownership of time_wait_list_manager_.
274 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(), 298 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
275 time_wait_list_manager_); 299 time_wait_list_manager_);
276 } 300 }
(...skipping 10 matching lines...) Expand all
287 QuicEpollAlarmFactory alarm_factory_; 311 QuicEpollAlarmFactory alarm_factory_;
288 MockAlarmFactory mock_alarm_factory_; 312 MockAlarmFactory mock_alarm_factory_;
289 QuicConfig config_; 313 QuicConfig config_;
290 QuicVersionManager version_manager_; 314 QuicVersionManager version_manager_;
291 QuicCryptoServerConfig crypto_config_; 315 QuicCryptoServerConfig crypto_config_;
292 IPEndPoint server_address_; 316 IPEndPoint server_address_;
293 std::unique_ptr<TestDispatcher> dispatcher_; 317 std::unique_ptr<TestDispatcher> dispatcher_;
294 MockTimeWaitListManager* time_wait_list_manager_; 318 MockTimeWaitListManager* time_wait_list_manager_;
295 TestQuicSpdyServerSession* session1_; 319 TestQuicSpdyServerSession* session1_;
296 TestQuicSpdyServerSession* session2_; 320 TestQuicSpdyServerSession* session2_;
297 string data_; 321 std::map<QuicConnectionId, std::list<string>> data_connection_map_;
322 QuicBufferedPacketStore* store_;
298 }; 323 };
299 324
300 TEST_F(QuicDispatcherTest, ProcessPackets) { 325 TEST_F(QuicDispatcherTest, ProcessPackets) {
301 IPEndPoint client_address(net::test::Loopback4(), 1); 326 IPEndPoint client_address(net::test::Loopback4(), 1);
302 server_address_ = IPEndPoint(net::test::Any4(), 5); 327 server_address_ = IPEndPoint(net::test::Any4(), 5);
303 328
304 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) 329 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address))
305 .WillOnce(testing::Return(CreateSession( 330 .WillOnce(testing::Return(CreateSession(
306 dispatcher_.get(), config_, 1, client_address, &mock_helper_, 331 dispatcher_.get(), config_, 1, client_address, &mock_helper_,
307 &mock_alarm_factory_, &crypto_config_, 332 &mock_alarm_factory_, &crypto_config_,
308 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))));
309 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); 338 ProcessPacket(client_address, 1, true, false, SerializeCHLO());
310 EXPECT_EQ(client_address, dispatcher_->current_client_address()); 339 EXPECT_EQ(client_address, dispatcher_->current_client_address());
311 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); 340 EXPECT_EQ(server_address_, dispatcher_->current_server_address());
312 341
313 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address)) 342 EXPECT_CALL(*dispatcher_, CreateQuicSession(2, client_address))
314 .WillOnce(testing::Return(CreateSession( 343 .WillOnce(testing::Return(CreateSession(
315 dispatcher_.get(), config_, 2, client_address, &mock_helper_, 344 dispatcher_.get(), config_, 2, client_address, &mock_helper_,
316 &mock_alarm_factory_, &crypto_config_, 345 &mock_alarm_factory_, &crypto_config_,
317 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))));
318 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); 351 ProcessPacket(client_address, 2, true, false, SerializeCHLO());
319 352
320 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), 353 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
321 ProcessUdpPacket(_, _, _)) 354 ProcessUdpPacket(_, _, _))
322 .Times(1) 355 .Times(1)
323 .WillOnce(testing::WithArgs<2>( 356 .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor(
324 Invoke(this, &QuicDispatcherTest::ValidatePacket))); 357 &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1))));
325 ProcessPacket(client_address, 1, false, false, "data"); 358 ProcessPacket(client_address, 1, false, false, "data");
326 } 359 }
327 360
328 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) { 361 TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
329 IPEndPoint client_address(net::test::Loopback4(), 1); 362 IPEndPoint client_address(net::test::Loopback4(), 1);
330 server_address_ = IPEndPoint(net::test::Any4(), 5); 363 server_address_ = IPEndPoint(net::test::Any4(), 5);
331 364
332 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0); 365 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)).Times(0);
333 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1); 366 QuicVersion version = static_cast<QuicVersion>(QuicVersionMin() - 1);
334 ProcessPacket(client_address, 1, true, version, SerializeCHLO(), 367 ProcessPacket(client_address, 1, true, version, SerializeCHLO(),
335 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1); 368 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
336 } 369 }
337 370
338 TEST_F(QuicDispatcherTest, Shutdown) { 371 TEST_F(QuicDispatcherTest, Shutdown) {
339 IPEndPoint client_address(net::test::Loopback4(), 1); 372 IPEndPoint client_address(net::test::Loopback4(), 1);
340 373
341 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) 374 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address))
342 .WillOnce(testing::Return(CreateSession( 375 .WillOnce(testing::Return(CreateSession(
343 dispatcher_.get(), config_, 1, client_address, &mock_helper_, 376 dispatcher_.get(), config_, 1, client_address, &mock_helper_,
344 &mock_alarm_factory_, &crypto_config_, 377 &mock_alarm_factory_, &crypto_config_,
345 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))));
346 383
347 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); 384 ProcessPacket(client_address, 1, true, false, SerializeCHLO());
348 385
349 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), 386 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
350 CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); 387 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
351 388
352 dispatcher_->Shutdown(); 389 dispatcher_->Shutdown();
353 } 390 }
354 391
355 TEST_F(QuicDispatcherTest, TimeWaitListManager) { 392 TEST_F(QuicDispatcherTest, TimeWaitListManager) {
356 CreateTimeWaitListManager(); 393 CreateTimeWaitListManager();
357 394
358 // Create a new session. 395 // Create a new session.
359 IPEndPoint client_address(net::test::Loopback4(), 1); 396 IPEndPoint client_address(net::test::Loopback4(), 1);
360 QuicConnectionId connection_id = 1; 397 QuicConnectionId connection_id = 1;
361 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 398 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
362 .WillOnce(testing::Return(CreateSession( 399 .WillOnce(testing::Return(CreateSession(
363 dispatcher_.get(), config_, connection_id, client_address, 400 dispatcher_.get(), config_, connection_id, client_address,
364 &mock_helper_, &mock_alarm_factory_, &crypto_config_, 401 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
365 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
366 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); 408 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO());
367 409
368 // Close the connection by sending public reset packet. 410 // Close the connection by sending public reset packet.
369 QuicPublicResetPacket packet; 411 QuicPublicResetPacket packet;
370 packet.public_header.connection_id = connection_id; 412 packet.public_header.connection_id = connection_id;
371 packet.public_header.reset_flag = true; 413 packet.public_header.reset_flag = true;
372 packet.public_header.version_flag = false; 414 packet.public_header.version_flag = false;
373 packet.rejected_packet_number = 19191; 415 packet.rejected_packet_number = 19191;
374 packet.nonce_proof = 132232; 416 packet.nonce_proof = 132232;
375 std::unique_ptr<QuicEncryptedPacket> encrypted( 417 std::unique_ptr<QuicEncryptedPacket> encrypted(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) { 475 TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
434 IPEndPoint client_address(net::test::Loopback4(), 1); 476 IPEndPoint client_address(net::test::Loopback4(), 1);
435 QuicConnectionId connection_id = 1; 477 QuicConnectionId connection_id = 1;
436 server_address_ = IPEndPoint(net::test::Any4(), 5); 478 server_address_ = IPEndPoint(net::test::Any4(), 5);
437 479
438 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address)) 480 EXPECT_CALL(*dispatcher_, CreateQuicSession(1, client_address))
439 .WillOnce(testing::Return(CreateSession( 481 .WillOnce(testing::Return(CreateSession(
440 dispatcher_.get(), config_, 1, client_address, &mock_helper_, 482 dispatcher_.get(), config_, 1, client_address, &mock_helper_,
441 &mock_alarm_factory_, &crypto_config_, 483 &mock_alarm_factory_, &crypto_config_,
442 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))));
443 // 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
444 // connection. 490 // connection.
445 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), 491 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(),
446 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 492 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
447 kDefaultPathId, 493 kDefaultPathId,
448 QuicDispatcher::kMaxReasonableInitialPacketNumber); 494 QuicDispatcher::kMaxReasonableInitialPacketNumber);
449 EXPECT_EQ(client_address, dispatcher_->current_client_address()); 495 EXPECT_EQ(client_address, dispatcher_->current_client_address());
450 EXPECT_EQ(server_address_, dispatcher_->current_server_address()); 496 EXPECT_EQ(server_address_, dispatcher_->current_server_address());
451 } 497 }
452 498
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 } 575 }
530 } 576 }
531 } 577 }
532 return params; 578 return params;
533 } 579 }
534 580
535 class QuicDispatcherStatelessRejectTest 581 class QuicDispatcherStatelessRejectTest
536 : public QuicDispatcherTest, 582 : public QuicDispatcherTest,
537 public ::testing::WithParamInterface<StatelessRejectTestParams> { 583 public ::testing::WithParamInterface<StatelessRejectTestParams> {
538 public: 584 public:
539 QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} 585 QuicDispatcherStatelessRejectTest()
586 : QuicDispatcherTest(), crypto_stream1_(nullptr) {}
540 587
541 ~QuicDispatcherStatelessRejectTest() override { 588 ~QuicDispatcherStatelessRejectTest() override {
542 if (crypto_stream1_) { 589 if (crypto_stream1_) {
543 delete crypto_stream1_; 590 delete crypto_stream1_;
544 } 591 }
545 } 592 }
546 593
547 // This test setup assumes that all testing will be done using 594 // This test setup assumes that all testing will be done using
548 // crypto_stream1_. 595 // crypto_stream1_.
549 void SetUp() override { 596 void SetUp() override {
597 QuicDispatcherTest::SetUp();
550 FLAGS_enable_quic_stateless_reject_support = 598 FLAGS_enable_quic_stateless_reject_support =
551 GetParam().enable_stateless_rejects_via_flag; 599 GetParam().enable_stateless_rejects_via_flag;
552 } 600 }
553 601
554 // Returns true or false, depending on whether the server will emit 602 // Returns true or false, depending on whether the server will emit
555 // a stateless reject, depending upon the parameters of the test. 603 // a stateless reject, depending upon the parameters of the test.
556 bool ExpectStatelessReject() { 604 bool ExpectStatelessReject() {
557 return GetParam().enable_stateless_rejects_via_flag && 605 return GetParam().enable_stateless_rejects_via_flag &&
558 !GetParam().crypto_handshake_successful && 606 !GetParam().crypto_handshake_successful &&
559 GetParam().client_supports_statelesss_rejects; 607 GetParam().client_supports_statelesss_rejects;
(...skipping 30 matching lines...) Expand all
590 ::testing::ValuesIn(GetStatelessRejectTestParams())); 638 ::testing::ValuesIn(GetStatelessRejectTestParams()));
591 639
592 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) { 640 TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
593 CreateTimeWaitListManager(); 641 CreateTimeWaitListManager();
594 642
595 IPEndPoint client_address(net::test::Loopback4(), 1); 643 IPEndPoint client_address(net::test::Loopback4(), 1);
596 QuicConnectionId connection_id = 1; 644 QuicConnectionId connection_id = 1;
597 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 645 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
598 .WillOnce(testing::Return( 646 .WillOnce(testing::Return(
599 CreateSessionBasedOnTestParams(connection_id, client_address))); 647 CreateSessionBasedOnTestParams(connection_id, client_address)));
600 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))));
601 // Process the first packet for the connection. 653 // Process the first packet for the connection.
602 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); 654 ProcessPacket(client_address, connection_id, true, false, SerializeCHLO());
603 if (ExpectStatelessReject()) { 655 if (ExpectStatelessReject()) {
604 // 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
605 // connection. 657 // connection.
606 session1_->connection()->CloseConnection( 658 session1_->connection()->CloseConnection(
607 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", 659 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
608 ConnectionCloseBehavior::SILENT_CLOSE); 660 ConnectionCloseBehavior::SILENT_CLOSE);
609 } 661 }
610 662
611 // 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,
612 // the existing connection_id will go on the time-wait list. 664 // the existing connection_id will go on the time-wait list.
613 EXPECT_EQ(ExpectStatelessReject(), 665 EXPECT_EQ(ExpectStatelessReject(),
614 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); 666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
615 if (ExpectStatelessReject()) { 667 if (ExpectStatelessReject()) {
616 // The second packet will be processed on the time-wait list. 668 // The second packet will be processed on the time-wait list.
617 EXPECT_CALL(*time_wait_list_manager_, 669 EXPECT_CALL(*time_wait_list_manager_,
618 ProcessPacket(_, _, connection_id, _, _)) 670 ProcessPacket(_, _, connection_id, _, _))
619 .Times(1); 671 .Times(1);
620 } else { 672 } else {
621 // The second packet will trigger a packet-validation 673 // The second packet will trigger a packet-validation
622 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), 674 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
623 ProcessUdpPacket(_, _, _)) 675 ProcessUdpPacket(_, _, _))
624 .Times(1) 676 .Times(1)
625 .WillOnce(testing::WithArgs<2>( 677 .WillOnce(testing::WithArgs<2>(
626 Invoke(this, &QuicDispatcherTest::ValidatePacket))); 678 Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket,
679 base::Unretained(this), connection_id))));
627 } 680 }
628 ProcessPacket(client_address, connection_id, true, false, "data"); 681 ProcessPacket(client_address, connection_id, true, false, "data");
629 } 682 }
630 683
631 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { 684 TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
632 FLAGS_quic_use_cheap_stateless_rejects = true; 685 FLAGS_quic_use_cheap_stateless_rejects = true;
686 FLAGS_quic_buffer_packet_till_chlo = true;
633 CreateTimeWaitListManager(); 687 CreateTimeWaitListManager();
634 688
635 IPEndPoint client_address(net::test::Loopback4(), 1); 689 IPEndPoint client_address(net::test::Loopback4(), 1);
636 QuicConnectionId connection_id = 1; 690 QuicConnectionId connection_id = 1;
637 if (GetParam().enable_stateless_rejects_via_flag) { 691 if (GetParam().enable_stateless_rejects_via_flag) {
638 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 692 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
639 .Times(0); 693 .Times(0);
640 } else { 694 } else {
641 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 695 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
642 .WillOnce(testing::Return( 696 .WillOnce(testing::Return(
643 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))));
644 } 702 }
645 703
646 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); 704 VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject();
647 VLOG(1) << "Params: " << GetParam(); 705 VLOG(1) << "Params: " << GetParam();
648 // Process the first packet for the connection. 706 // Process the first packet for the connection.
649 // clang-format off 707 // clang-format off
650 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( 708 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message(
651 "CHLO", 709 "CHLO",
652 "AEAD", "AESG", 710 "AEAD", "AESG",
653 "KEXS", "C255", 711 "KEXS", "C255",
654 "COPT", "SREJ", 712 "COPT", "SREJ",
655 "NONC", "1234567890123456789012", 713 "NONC", "1234567890123456789012",
656 "VER\0", "Q025", 714 "VER\0", "Q025",
657 "$padding", static_cast<int>(kClientHelloMinimumSize), 715 "$padding", static_cast<int>(kClientHelloMinimumSize),
658 nullptr); 716 nullptr);
659 // clang-format on 717 // clang-format on
660 718
661 ProcessPacket(client_address, connection_id, true, false, 719 ProcessPacket(client_address, connection_id, true, false,
662 client_hello.GetSerialized().AsStringPiece().as_string()); 720 client_hello.GetSerialized().AsStringPiece().as_string());
663 721
664 if (GetParam().enable_stateless_rejects_via_flag) { 722 if (GetParam().enable_stateless_rejects_via_flag) {
665 EXPECT_EQ(true, 723 EXPECT_EQ(true,
666 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); 724 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
667 } 725 }
668 } 726 }
669 727
670 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { 728 TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
671 FLAGS_quic_use_cheap_stateless_rejects = true; 729 FLAGS_quic_use_cheap_stateless_rejects = true;
730 FLAGS_quic_always_log_bugs_for_tests = true;
672 CreateTimeWaitListManager(); 731 CreateTimeWaitListManager();
673 732
674 const IPEndPoint client_address(net::test::Loopback4(), 1); 733 const IPEndPoint client_address(net::test::Loopback4(), 1);
675 const QuicConnectionId connection_id = 1; 734 const QuicConnectionId connection_id = 1;
676 735
677 if (!GetParam().enable_stateless_rejects_via_flag) { 736 if (!GetParam().enable_stateless_rejects_via_flag &&
678 // If stateless rejects are not being used, then a connection will be 737 !FLAGS_quic_buffer_packet_till_chlo) {
679 // 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.
680 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 740 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
681 .WillOnce(testing::Return( 741 .WillOnce(testing::Return(
682 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))));
683 } 748 }
684 ProcessPacket(client_address, connection_id, true, false, 749 bool first_packet_dropped = GetParam().enable_stateless_rejects_via_flag &&
685 "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 }
686 765
687 // Process the first packet for the connection. 766 // Process the first packet for the connection.
688 // clang-format off 767 // clang-format off
689 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( 768 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message(
690 "CHLO", 769 "CHLO",
691 "AEAD", "AESG", 770 "AEAD", "AESG",
692 "KEXS", "C255", 771 "KEXS", "C255",
693 "NONC", "1234567890123456789012", 772 "NONC", "1234567890123456789012",
694 "VER\0", "Q025", 773 "VER\0", "Q025",
695 "$padding", static_cast<int>(kClientHelloMinimumSize), 774 "$padding", static_cast<int>(kClientHelloMinimumSize),
696 nullptr); 775 nullptr);
697 // clang-format on 776 // clang-format on
698 777
699 if (GetParam().enable_stateless_rejects_via_flag) { 778 if (GetParam().enable_stateless_rejects_via_flag ||
779 FLAGS_quic_buffer_packet_till_chlo) {
700 // 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
701 // and the buffered packet will be processed 781 // and the buffered packet will be processed
702 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) 782 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address))
703 .WillOnce(testing::Return( 783 .WillOnce(testing::Return(
704 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))));
705 } 790 }
706 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), 791 if (!first_packet_dropped) {
707 ProcessUdpPacket(_, client_address, _)) 792 // Expect both packets to be passed to ProcessUdpPacket(). And one of them
708 .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 }
709 ProcessPacket(client_address, connection_id, true, false, 805 ProcessPacket(client_address, connection_id, true, false,
710 client_hello.GetSerialized().AsStringPiece().as_string()); 806 client_hello.GetSerialized().AsStringPiece().as_string());
711 EXPECT_FALSE( 807 EXPECT_FALSE(
712 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); 808 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
713 } 809 }
714 810
715 // Verify the stopgap test: Packets with truncated connection IDs should be 811 // Verify the stopgap test: Packets with truncated connection IDs should be
716 // dropped. 812 // dropped.
717 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {}; 813 class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
718 814
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 LOG(DFATAL) << "Not supported"; 848 LOG(DFATAL) << "Not supported";
753 return WriteResult(); 849 return WriteResult();
754 } 850 }
755 851
756 bool write_blocked_; 852 bool write_blocked_;
757 }; 853 };
758 854
759 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { 855 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
760 public: 856 public:
761 void SetUp() override { 857 void SetUp() override {
858 QuicDispatcherTest::SetUp();
762 writer_ = new BlockingWriter; 859 writer_ = new BlockingWriter;
763 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); 860 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
764 861
765 IPEndPoint client_address(net::test::Loopback4(), 1); 862 IPEndPoint client_address(net::test::Loopback4(), 1);
766 863
767 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) 864 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address))
768 .WillOnce(testing::Return(CreateSession( 865 .WillOnce(testing::Return(CreateSession(
769 dispatcher_.get(), config_, 1, client_address, &helper_, 866 dispatcher_.get(), config_, 1, client_address, &helper_,
770 &alarm_factory_, &crypto_config_, 867 &alarm_factory_, &crypto_config_,
771 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))));
772 ProcessPacket(client_address, 1, true, false, SerializeCHLO()); 873 ProcessPacket(client_address, 1, true, false, SerializeCHLO());
773 874
774 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) 875 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address))
775 .WillOnce(testing::Return(CreateSession( 876 .WillOnce(testing::Return(CreateSession(
776 dispatcher_.get(), config_, 2, client_address, &helper_, 877 dispatcher_.get(), config_, 2, client_address, &helper_,
777 &alarm_factory_, &crypto_config_, 878 &alarm_factory_, &crypto_config_,
778 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))));
779 ProcessPacket(client_address, 2, true, false, SerializeCHLO()); 884 ProcessPacket(client_address, 2, true, false, SerializeCHLO());
780 885
781 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); 886 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
782 } 887 }
783 888
784 void TearDown() override { 889 void TearDown() override {
785 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); 890 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
786 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _)); 891 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
787 dispatcher_->Shutdown(); 892 dispatcher_->Shutdown();
788 } 893 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); 1030 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
926 dispatcher_->OnCanWrite(); 1031 dispatcher_->OnCanWrite();
927 EXPECT_TRUE(dispatcher_->HasPendingWrites()); 1032 EXPECT_TRUE(dispatcher_->HasPendingWrites());
928 1033
929 // 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.
930 EXPECT_CALL(*connection2(), OnCanWrite()); 1035 EXPECT_CALL(*connection2(), OnCanWrite());
931 dispatcher_->OnCanWrite(); 1036 dispatcher_->OnCanWrite();
932 EXPECT_FALSE(dispatcher_->HasPendingWrites()); 1037 EXPECT_FALSE(dispatcher_->HasPendingWrites());
933 } 1038 }
934 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 = QuicSupportedVersions().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
935 } // namespace 1285 } // namespace
936 } // namespace test 1286 } // namespace test
937 } // namespace net 1287 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_dispatcher.cc ('k') | net/tools/quic/test_tools/packet_reordering_writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698