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

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

Issue 2236973002: Landing Recent QUIC changes until 4AM, Aug 7, 2016 UTC-4 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: flip quic_sequencer_buffer_retire_block_in_time to true 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/quic_packet_printer_bin.cc » ('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)
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/tools/quic/quic_dispatcher.cc ('k') | net/tools/quic/quic_packet_printer_bin.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698