blob: 1e646af3445c7b4ac3395f82f7dc66d5280ac43e [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
6
7#include <memory>
8#include <ostream>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/core/chlo_extractor.h"
12#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
13#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
14#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
15#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
16#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
17#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
18#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
19#include "net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h"
20#include "net/third_party/quiche/src/quic/core/quic_types.h"
21#include "net/third_party/quiche/src/quic/core/quic_utils.h"
22#include "net/third_party/quiche/src/quic/core/stateless_rejector.h"
23#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
25#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050029#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
30#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
31#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
32#include "net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h"
33#include "net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h"
34#include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
35#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
36#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
37#include "net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h"
38#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
39
40using testing::_;
41using testing::InSequence;
42using testing::Invoke;
43using testing::NiceMock;
44using testing::Return;
45using testing::WithArg;
46using testing::WithoutArgs;
47
48static const size_t kDefaultMaxConnectionsInStore = 100;
49static const size_t kMaxConnectionsWithoutCHLO =
50 kDefaultMaxConnectionsInStore / 2;
51static const int16_t kMaxNumSessionsToCreate = 16;
52
53namespace quic {
54namespace test {
55namespace {
56
57class TestQuicSpdyServerSession : public QuicServerSessionBase {
58 public:
59 TestQuicSpdyServerSession(const QuicConfig& config,
60 QuicConnection* connection,
61 const QuicCryptoServerConfig* crypto_config,
62 QuicCompressedCertsCache* compressed_certs_cache)
63 : QuicServerSessionBase(config,
64 CurrentSupportedVersions(),
65 connection,
66 nullptr,
67 nullptr,
68 crypto_config,
69 compressed_certs_cache),
70 crypto_stream_(QuicServerSessionBase::GetMutableCryptoStream()) {}
71 TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
72 TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
73 delete;
74
75 ~TestQuicSpdyServerSession() override { delete connection(); }
76
77 MOCK_METHOD3(OnConnectionClosed,
78 void(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -070079 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050080 ConnectionCloseSource source));
81 MOCK_METHOD1(CreateIncomingStream, QuicSpdyStream*(QuicStreamId id));
82 MOCK_METHOD1(CreateIncomingStream, QuicSpdyStream*(PendingStream pending));
83 MOCK_METHOD0(CreateOutgoingBidirectionalStream, QuicSpdyStream*());
84 MOCK_METHOD0(CreateOutgoingUnidirectionalStream, QuicSpdyStream*());
85
86 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
87 const QuicCryptoServerConfig* crypto_config,
88 QuicCompressedCertsCache* compressed_certs_cache) override {
89 return new QuicCryptoServerStream(
90 crypto_config, compressed_certs_cache,
91 GetQuicReloadableFlag(enable_quic_stateless_reject_support), this,
92 stream_helper());
93 }
94
95 void SetCryptoStream(QuicCryptoServerStream* crypto_stream) {
96 crypto_stream_ = crypto_stream;
97 }
98
99 QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
100 return crypto_stream_;
101 }
102
103 const QuicCryptoServerStreamBase* GetCryptoStream() const override {
104 return crypto_stream_;
105 }
106
107 QuicCryptoServerStream::Helper* stream_helper() {
108 return QuicServerSessionBase::stream_helper();
109 }
110
111 private:
112 QuicCryptoServerStreamBase* crypto_stream_;
113};
114
115class TestDispatcher : public QuicDispatcher {
116 public:
117 TestDispatcher(const QuicConfig* config,
118 const QuicCryptoServerConfig* crypto_config,
QUICHE teamc65d1d12019-03-19 20:58:04 -0700119 QuicVersionManager* version_manager,
120 QuicRandom* random)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121 : QuicDispatcher(config,
122 crypto_config,
123 version_manager,
124 QuicMakeUnique<MockQuicConnectionHelper>(),
125 std::unique_ptr<QuicCryptoServerStream::Helper>(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700126 new QuicSimpleCryptoServerStreamHelper(random)),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127 QuicMakeUnique<MockAlarmFactory>(),
128 kQuicDefaultConnectionIdLength) {}
129
130 MOCK_METHOD4(CreateQuicSession,
131 QuicServerSessionBase*(QuicConnectionId connection_id,
132 const QuicSocketAddress& peer_address,
133 QuicStringPiece alpn,
134 const quic::ParsedQuicVersion& version));
135
136 MOCK_METHOD2(ShouldCreateOrBufferPacketForConnection,
137 bool(QuicConnectionId connection_id, bool ietf_quic));
138
139 struct TestQuicPerPacketContext : public QuicPerPacketContext {
vasilvvc48c8712019-03-11 13:38:16 -0700140 std::string custom_packet_context;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141 };
142
143 std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
144 auto test_context = QuicMakeUnique<TestQuicPerPacketContext>();
145 test_context->custom_packet_context = custom_packet_context_;
146 return std::move(test_context);
147 }
148
149 void RestorePerPacketContext(
150 std::unique_ptr<QuicPerPacketContext> context) override {
151 TestQuicPerPacketContext* test_context =
152 static_cast<TestQuicPerPacketContext*>(context.get());
153 custom_packet_context_ = test_context->custom_packet_context;
154 }
155
vasilvvc48c8712019-03-11 13:38:16 -0700156 std::string custom_packet_context_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157
158 using QuicDispatcher::current_client_address;
159 using QuicDispatcher::current_peer_address;
160 using QuicDispatcher::current_self_address;
QUICHE team963d57e2019-03-21 10:58:47 -0700161 using QuicDispatcher::SetAllowShortInitialConnectionIds;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500162 using QuicDispatcher::writer;
163};
164
165// A Connection class which unregisters the session from the dispatcher when
166// sending connection close.
167// It'd be slightly more realistic to do this from the Session but it would
168// involve a lot more mocking.
169class MockServerConnection : public MockQuicConnection {
170 public:
171 MockServerConnection(QuicConnectionId connection_id,
172 MockQuicConnectionHelper* helper,
173 MockAlarmFactory* alarm_factory,
174 QuicDispatcher* dispatcher)
175 : MockQuicConnection(connection_id,
176 helper,
177 alarm_factory,
178 Perspective::IS_SERVER),
179 dispatcher_(dispatcher) {}
180
181 void UnregisterOnConnectionClosed() {
182 QUIC_LOG(ERROR) << "Unregistering " << connection_id();
183 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
184 "Unregistering.",
185 ConnectionCloseSource::FROM_SELF);
186 }
187
188 private:
189 QuicDispatcher* dispatcher_;
190};
191
192class QuicDispatcherTest : public QuicTest {
193 public:
194 QuicDispatcherTest()
195 : QuicDispatcherTest(crypto_test_utils::ProofSourceForTesting()) {}
196
197 ParsedQuicVersionVector AllSupportedVersionsIncludingTls() {
198 SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
199 return AllSupportedVersions();
200 }
201
202 explicit QuicDispatcherTest(std::unique_ptr<ProofSource> proof_source)
203 :
204
205 version_manager_(AllSupportedVersionsIncludingTls()),
206 crypto_config_(QuicCryptoServerConfig::TESTING,
207 QuicRandom::GetInstance(),
208 std::move(proof_source),
209 KeyExchangeSource::Default(),
210 TlsServerHandshaker::CreateSslCtx()),
211 server_address_(QuicIpAddress::Any4(), 5),
QUICHE teamc65d1d12019-03-19 20:58:04 -0700212 dispatcher_(
213 new NiceMock<TestDispatcher>(&config_,
214 &crypto_config_,
215 &version_manager_,
216 mock_helper_.GetRandomGenerator())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217 time_wait_list_manager_(nullptr),
218 session1_(nullptr),
219 session2_(nullptr),
220 store_(nullptr) {}
221
222 void SetUp() override {
223 dispatcher_->InitializeWithWriter(new MockPacketWriter());
224 // Set the counter to some value to start with.
225 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
226 dispatcher_.get(), kMaxNumSessionsToCreate);
227 ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_, _))
228 .WillByDefault(Return(true));
229 }
230
231 MockQuicConnection* connection1() {
232 if (session1_ == nullptr) {
233 return nullptr;
234 }
235 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
236 }
237
238 MockQuicConnection* connection2() {
239 if (session2_ == nullptr) {
240 return nullptr;
241 }
242 return reinterpret_cast<MockQuicConnection*>(session2_->connection());
243 }
244
245 // Process a packet with an 8 byte connection id,
246 // 6 byte packet number, default path id, and packet number 1,
247 // using the first supported version.
248 void ProcessPacket(QuicSocketAddress peer_address,
249 QuicConnectionId connection_id,
250 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700251 const std::string& data) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 ProcessPacket(peer_address, connection_id, has_version_flag, data,
253 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
254 }
255
256 // Process a packet with a default path id, and packet number 1,
257 // using the first supported version.
258 void ProcessPacket(QuicSocketAddress peer_address,
259 QuicConnectionId connection_id,
260 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700261 const std::string& data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262 QuicConnectionIdIncluded connection_id_included,
263 QuicPacketNumberLength packet_number_length) {
264 ProcessPacket(peer_address, connection_id, has_version_flag, data,
265 connection_id_included, packet_number_length, 1);
266 }
267
268 // Process a packet using the first supported version.
269 void ProcessPacket(QuicSocketAddress peer_address,
270 QuicConnectionId connection_id,
271 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700272 const std::string& data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500273 QuicConnectionIdIncluded connection_id_included,
274 QuicPacketNumberLength packet_number_length,
275 uint64_t packet_number) {
276 ProcessPacket(peer_address, connection_id, has_version_flag,
277 CurrentSupportedVersions().front(), data,
278 connection_id_included, packet_number_length, packet_number);
279 }
280
281 // Processes a packet.
282 void ProcessPacket(QuicSocketAddress peer_address,
283 QuicConnectionId connection_id,
284 bool has_version_flag,
285 ParsedQuicVersion version,
vasilvvc48c8712019-03-11 13:38:16 -0700286 const std::string& data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 QuicConnectionIdIncluded connection_id_included,
288 QuicPacketNumberLength packet_number_length,
289 uint64_t packet_number) {
290 ParsedQuicVersionVector versions(SupportedVersions(version));
291 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
292 connection_id, EmptyQuicConnectionId(), has_version_flag, false,
293 packet_number, data, connection_id_included, CONNECTION_ID_ABSENT,
294 packet_number_length, &versions));
295 std::unique_ptr<QuicReceivedPacket> received_packet(
296 ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
297
298 if (ChloExtractor::Extract(*packet, versions, {}, nullptr,
299 connection_id.length())) {
300 // Add CHLO packet to the beginning to be verified first, because it is
301 // also processed first by new session.
302 data_connection_map_[connection_id].push_front(
vasilvvc48c8712019-03-11 13:38:16 -0700303 std::string(packet->data(), packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500304 } else {
305 // For non-CHLO, always append to last.
306 data_connection_map_[connection_id].push_back(
vasilvvc48c8712019-03-11 13:38:16 -0700307 std::string(packet->data(), packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500308 }
309 dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
310 }
311
312 void ValidatePacket(QuicConnectionId conn_id,
313 const QuicEncryptedPacket& packet) {
314 EXPECT_EQ(data_connection_map_[conn_id].front().length(),
315 packet.AsStringPiece().length());
316 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
317 data_connection_map_[conn_id].pop_front();
318 }
319
320 QuicServerSessionBase* CreateSession(
321 TestDispatcher* dispatcher,
322 const QuicConfig& config,
323 QuicConnectionId connection_id,
324 const QuicSocketAddress& peer_address,
325 MockQuicConnectionHelper* helper,
326 MockAlarmFactory* alarm_factory,
327 const QuicCryptoServerConfig* crypto_config,
328 QuicCompressedCertsCache* compressed_certs_cache,
329 TestQuicSpdyServerSession** session) {
330 MockServerConnection* connection = new MockServerConnection(
331 connection_id, helper, alarm_factory, dispatcher);
332 connection->SetQuicPacketWriter(dispatcher->writer(),
333 /*owns_writer=*/false);
334 *session = new TestQuicSpdyServerSession(config, connection, crypto_config,
335 compressed_certs_cache);
336 connection->set_visitor(*session);
337 ON_CALL(*connection, CloseConnection(_, _, _))
338 .WillByDefault(WithoutArgs(Invoke(
339 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
340 return *session;
341 }
342
343 void CreateTimeWaitListManager() {
344 time_wait_list_manager_ = new MockTimeWaitListManager(
345 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
346 mock_helper_.GetClock(), &mock_alarm_factory_);
347 // dispatcher_ takes the ownership of time_wait_list_manager_.
348 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
349 time_wait_list_manager_);
350 }
351
vasilvvc48c8712019-03-11 13:38:16 -0700352 std::string SerializeCHLO() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 CryptoHandshakeMessage client_hello;
354 client_hello.set_tag(kCHLO);
355 client_hello.SetStringPiece(kALPN, "hq");
vasilvvc48c8712019-03-11 13:38:16 -0700356 return std::string(client_hello.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500357 }
358
vasilvvc48c8712019-03-11 13:38:16 -0700359 std::string SerializeTlsClientHello() { return ""; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500360
361 void MarkSession1Deleted() { session1_ = nullptr; }
362
363 MockQuicConnectionHelper mock_helper_;
364 MockAlarmFactory mock_alarm_factory_;
365 QuicConfig config_;
366 QuicVersionManager version_manager_;
367 QuicCryptoServerConfig crypto_config_;
368 QuicSocketAddress server_address_;
369 std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
370 MockTimeWaitListManager* time_wait_list_manager_;
371 TestQuicSpdyServerSession* session1_;
372 TestQuicSpdyServerSession* session2_;
vasilvvc48c8712019-03-11 13:38:16 -0700373 std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500374 QuicBufferedPacketStore* store_;
375};
376
377TEST_F(QuicDispatcherTest, TlsClientHelloCreatesSession) {
QUICHE teamea740082019-03-11 17:58:43 -0700378 if (!QuicVersionUsesCryptoFrames(
379 CurrentSupportedVersions().front().transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500380 // TLS is only supported in versions 47 and greater.
381 return;
382 }
383 FLAGS_quic_supports_tls_handshake = true;
384 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
385
386 EXPECT_CALL(*dispatcher_,
387 CreateQuicSession(TestConnectionId(1), client_address,
388 QuicStringPiece(""), _))
389 .WillOnce(testing::Return(CreateSession(
390 dispatcher_.get(), config_, TestConnectionId(1), client_address,
391 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
392 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
393 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
394 ProcessUdpPacket(_, _, _))
395 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
396 ValidatePacket(TestConnectionId(1), packet);
397 })));
398 EXPECT_CALL(*dispatcher_,
399 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
400 ProcessPacket(
401 client_address, TestConnectionId(1), true,
402 ParsedQuicVersion(PROTOCOL_TLS1_3,
403 CurrentSupportedVersions().front().transport_version),
404 SerializeCHLO(), CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
405 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
406 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
407}
408
409TEST_F(QuicDispatcherTest, ProcessPackets) {
410 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
411
412 EXPECT_CALL(*dispatcher_,
413 CreateQuicSession(TestConnectionId(1), client_address,
414 QuicStringPiece("hq"), _))
415 .WillOnce(testing::Return(CreateSession(
416 dispatcher_.get(), config_, TestConnectionId(1), client_address,
417 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
418 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
419 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
420 ProcessUdpPacket(_, _, _))
421 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
422 ValidatePacket(TestConnectionId(1), packet);
423 })));
424 EXPECT_CALL(*dispatcher_,
425 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
426 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
427 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
428 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
429
430 EXPECT_CALL(*dispatcher_,
431 CreateQuicSession(TestConnectionId(2), client_address,
432 QuicStringPiece("hq"), _))
433 .WillOnce(testing::Return(CreateSession(
434 dispatcher_.get(), config_, TestConnectionId(2), client_address,
435 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
436 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
437 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
438 ProcessUdpPacket(_, _, _))
439 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
440 ValidatePacket(TestConnectionId(2), packet);
441 })));
442 EXPECT_CALL(*dispatcher_,
443 ShouldCreateOrBufferPacketForConnection(TestConnectionId(2), _));
444 ProcessPacket(client_address, TestConnectionId(2), true, SerializeCHLO());
445
446 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
447 ProcessUdpPacket(_, _, _))
448 .Times(1)
449 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
450 ValidatePacket(TestConnectionId(1), packet);
451 })));
452 ProcessPacket(client_address, TestConnectionId(1), false, "data");
453}
454
455// Regression test of b/93325907.
456TEST_F(QuicDispatcherTest, DispatcherDoesNotRejectPacketNumberZero) {
457 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
458
459 EXPECT_CALL(*dispatcher_,
460 CreateQuicSession(TestConnectionId(1), client_address,
461 QuicStringPiece("hq"), _))
462 .WillOnce(testing::Return(CreateSession(
463 dispatcher_.get(), config_, TestConnectionId(1), client_address,
464 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
465 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
466 // Verify both packets 1 and 2 are processed by connection 1.
467 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
468 ProcessUdpPacket(_, _, _))
469 .Times(2)
470 .WillRepeatedly(
471 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
472 ValidatePacket(TestConnectionId(1), packet);
473 })));
474 EXPECT_CALL(*dispatcher_,
475 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
476 ProcessPacket(
477 client_address, TestConnectionId(1), true,
478 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
479 CurrentSupportedVersions().front().transport_version),
480 SerializeCHLO(), CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
481 // Packet number 256 with packet number length 1 would be considered as 0 in
482 // dispatcher.
483 ProcessPacket(
484 client_address, TestConnectionId(1), false,
485 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
486 CurrentSupportedVersions().front().transport_version),
487 "", CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
488 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
489 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
490}
491
492TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
493 CreateTimeWaitListManager();
494 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
495
496 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
497 EXPECT_CALL(*time_wait_list_manager_,
498 SendVersionNegotiationPacket(_, _, _, _, _, _))
499 .Times(1);
500 QuicTransportVersion version =
501 static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
502 ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
503 // Pad the CHLO message with enough data to make the packet large enough
504 // to trigger version negotiation.
vasilvvc48c8712019-03-11 13:38:16 -0700505 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 DCHECK_LE(1200u, chlo.length());
507 ProcessPacket(client_address, TestConnectionId(1), true, parsed_version, chlo,
508 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
509}
510
511TEST_F(QuicDispatcherTest, NoVersionNegotiationWithSmallPacket) {
512 CreateTimeWaitListManager();
513 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
514
515 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
516 EXPECT_CALL(*time_wait_list_manager_,
517 SendVersionNegotiationPacket(_, _, _, _, _, _))
518 .Times(0);
519 QuicTransportVersion version =
520 static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
521 ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
vasilvvc48c8712019-03-11 13:38:16 -0700522 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500523 // Truncate to 1100 bytes of payload which results in a packet just
524 // under 1200 bytes after framing, packet, and encryption overhead.
525 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700526 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500527 DCHECK_EQ(1100u, truncated_chlo.length());
528 ProcessPacket(client_address, TestConnectionId(1), true, parsed_version,
529 truncated_chlo, CONNECTION_ID_PRESENT,
530 PACKET_4BYTE_PACKET_NUMBER, 1);
531}
532
533// Disabling CHLO size validation allows the dispatcher to send version
534// negotiation packets in response to a CHLO that is otherwise too small.
535TEST_F(QuicDispatcherTest, VersionNegotiationWithoutChloSizeValidation) {
536 crypto_config_.set_validate_chlo_size(false);
537
538 CreateTimeWaitListManager();
539 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
540
541 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
542 EXPECT_CALL(*time_wait_list_manager_,
543 SendVersionNegotiationPacket(_, _, _, _, _, _))
544 .Times(1);
545 QuicTransportVersion version =
546 static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
547 ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
vasilvvc48c8712019-03-11 13:38:16 -0700548 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500549 // Truncate to 1100 bytes of payload which results in a packet just
550 // under 1200 bytes after framing, packet, and encryption overhead.
551 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700552 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500553 DCHECK_EQ(1100u, truncated_chlo.length());
554 ProcessPacket(client_address, TestConnectionId(1), true, parsed_version,
555 truncated_chlo, CONNECTION_ID_PRESENT,
556 PACKET_4BYTE_PACKET_NUMBER, 1);
557}
558
559TEST_F(QuicDispatcherTest, Shutdown) {
560 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
561
562 EXPECT_CALL(*dispatcher_,
563 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
564 .WillOnce(testing::Return(CreateSession(
565 dispatcher_.get(), config_, TestConnectionId(1), client_address,
566 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
567 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
568 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
569 ProcessUdpPacket(_, _, _))
570 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
571 ValidatePacket(TestConnectionId(1), packet);
572 })));
573
574 EXPECT_CALL(*dispatcher_,
575 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
576 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
577
578 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
579 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
580
581 dispatcher_->Shutdown();
582}
583
584TEST_F(QuicDispatcherTest, TimeWaitListManager) {
585 CreateTimeWaitListManager();
586
587 // Create a new session.
588 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
589 QuicConnectionId connection_id = TestConnectionId(1);
590 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
591 QuicStringPiece("hq"), _))
592 .WillOnce(testing::Return(CreateSession(
593 dispatcher_.get(), config_, connection_id, client_address,
594 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
595 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
596 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
597 ProcessUdpPacket(_, _, _))
598 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
599 ValidatePacket(TestConnectionId(1), packet);
600 })));
601
602 EXPECT_CALL(*dispatcher_,
603 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
604 ProcessPacket(client_address, connection_id, true, SerializeCHLO());
605
606 // Now close the connection, which should add it to the time wait list.
607 session1_->connection()->CloseConnection(
608 QUIC_INVALID_VERSION,
609 "Server: Packet 2 without version flag before version negotiated.",
610 ConnectionCloseBehavior::SILENT_CLOSE);
611 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
612
613 // Dispatcher forwards subsequent packets for this connection_id to the time
614 // wait list manager.
615 EXPECT_CALL(*time_wait_list_manager_,
616 ProcessPacket(_, _, connection_id, _, _))
617 .Times(1);
618 EXPECT_CALL(*time_wait_list_manager_,
619 AddConnectionIdToTimeWait(_, _, _, _, _))
620 .Times(0);
621 ProcessPacket(client_address, connection_id, true, "data");
622}
623
624TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
625 CreateTimeWaitListManager();
626
627 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
628 QuicConnectionId connection_id = TestConnectionId(1);
629 // Dispatcher forwards all packets for this connection_id to the time wait
630 // list manager.
631 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
632 .Times(0);
633 EXPECT_CALL(*time_wait_list_manager_,
634 ProcessPacket(_, _, connection_id, _, _))
635 .Times(1);
636 EXPECT_CALL(*time_wait_list_manager_,
637 AddConnectionIdToTimeWait(_, _, _, _, _))
638 .Times(1);
639 ProcessPacket(client_address, connection_id, false, SerializeCHLO());
640}
641
QUICHE teamc65d1d12019-03-19 20:58:04 -0700642// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
QUICHE team963d57e2019-03-21 10:58:47 -0700643TEST_F(QuicDispatcherTest, LongConnectionIdLengthReplaced) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700644 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
645 CurrentSupportedVersions()[0].transport_version)) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700646 // When variable length connection IDs are not supported, the connection
647 // fails. See StrayPacketTruncatedConnectionId.
QUICHE team8e2e4532019-03-14 14:37:56 -0700648 return;
649 }
QUICHE team8e2e4532019-03-14 14:37:56 -0700650 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
651
QUICHE teamc65d1d12019-03-19 20:58:04 -0700652 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
653 QuicConnectionId fixed_connection_id =
654 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
655
656 EXPECT_CALL(*dispatcher_,
657 CreateQuicSession(fixed_connection_id, client_address,
658 QuicStringPiece("hq"), _))
659 .WillOnce(testing::Return(CreateSession(
660 dispatcher_.get(), config_, fixed_connection_id, client_address,
661 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
662 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
663 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
664 ProcessUdpPacket(_, _, _))
665 .WillOnce(WithArg<2>(
666 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
667 ValidatePacket(bad_connection_id, packet);
668 })));
669 EXPECT_CALL(*dispatcher_,
670 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
671 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
672 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
673 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
QUICHE team8e2e4532019-03-14 14:37:56 -0700674}
675
QUICHE team963d57e2019-03-21 10:58:47 -0700676// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
677TEST_F(QuicDispatcherTest, InvalidShortConnectionIdLengthReplaced) {
678 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
679 CurrentSupportedVersions()[0].transport_version)) {
680 // When variable length connection IDs are not supported, the connection
681 // fails. See StrayPacketTruncatedConnectionId.
682 return;
683 }
684 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
685
686 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
687 QuicConnectionId fixed_connection_id =
688 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
689
690 // Disable validation of invalid short connection IDs.
691 dispatcher_->SetAllowShortInitialConnectionIds(true);
692 // Note that StrayPacketTruncatedConnectionId covers the case where the
693 // validation is still enabled.
694
695 EXPECT_CALL(*dispatcher_,
696 CreateQuicSession(fixed_connection_id, client_address,
697 QuicStringPiece("hq"), _))
698 .WillOnce(testing::Return(CreateSession(
699 dispatcher_.get(), config_, fixed_connection_id, client_address,
700 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
701 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
702 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
703 ProcessUdpPacket(_, _, _))
704 .WillOnce(WithArg<2>(
705 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
706 ValidatePacket(bad_connection_id, packet);
707 })));
708 EXPECT_CALL(*dispatcher_,
709 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
710 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
711 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
712 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
713}
714
QUICHE teamc65d1d12019-03-19 20:58:04 -0700715// Makes sure TestConnectionId(1) creates a new connection and
716// TestConnectionIdNineBytesLong(2) gets replaced.
QUICHE team8e2e4532019-03-14 14:37:56 -0700717TEST_F(QuicDispatcherTest, MixGoodAndBadConnectionIdLengthPackets) {
718 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
719 CurrentSupportedVersions()[0].transport_version)) {
720 return;
721 }
QUICHE teamc65d1d12019-03-19 20:58:04 -0700722
QUICHE team8e2e4532019-03-14 14:37:56 -0700723 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700724 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
725 QuicConnectionId fixed_connection_id =
726 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
QUICHE team8e2e4532019-03-14 14:37:56 -0700727
728 EXPECT_CALL(*dispatcher_,
729 CreateQuicSession(TestConnectionId(1), client_address,
730 QuicStringPiece("hq"), _))
731 .WillOnce(testing::Return(CreateSession(
732 dispatcher_.get(), config_, TestConnectionId(1), client_address,
733 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
734 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
735 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
736 ProcessUdpPacket(_, _, _))
737 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
738 ValidatePacket(TestConnectionId(1), packet);
739 })));
740 EXPECT_CALL(*dispatcher_,
741 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
742 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
743 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
744 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
745
QUICHE teamc65d1d12019-03-19 20:58:04 -0700746 EXPECT_CALL(*dispatcher_,
747 CreateQuicSession(fixed_connection_id, client_address,
748 QuicStringPiece("hq"), _))
749 .WillOnce(testing::Return(CreateSession(
750 dispatcher_.get(), config_, fixed_connection_id, client_address,
751 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
752 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
753 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
754 ProcessUdpPacket(_, _, _))
755 .WillOnce(WithArg<2>(
756 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
757 ValidatePacket(bad_connection_id, packet);
758 })));
759 EXPECT_CALL(*dispatcher_,
760 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
761 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
QUICHE team8e2e4532019-03-14 14:37:56 -0700762
763 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
764 ProcessUdpPacket(_, _, _))
765 .Times(1)
766 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
767 ValidatePacket(TestConnectionId(1), packet);
768 })));
769 ProcessPacket(client_address, TestConnectionId(1), false, "data");
770}
771
QUICHE teama6ef0a62019-03-07 20:34:33 -0500772TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) {
773 CreateTimeWaitListManager();
774
775 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
776
777 // dispatcher_ should drop this packet.
778 EXPECT_CALL(*dispatcher_,
779 CreateQuicSession(TestConnectionId(1), client_address,
780 QuicStringPiece("hq"), _))
781 .Times(0);
782 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
783 EXPECT_CALL(*time_wait_list_manager_,
784 AddConnectionIdToTimeWait(_, _, _, _, _))
785 .Times(0);
786 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
787}
788
789TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
790 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
791 QuicConnectionId connection_id = TestConnectionId(1);
792
793 EXPECT_CALL(*dispatcher_,
794 CreateQuicSession(TestConnectionId(1), client_address,
795 QuicStringPiece("hq"), _))
796 .WillOnce(testing::Return(CreateSession(
797 dispatcher_.get(), config_, TestConnectionId(1), client_address,
798 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
799 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
800 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
801 ProcessUdpPacket(_, _, _))
802 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
803 ValidatePacket(TestConnectionId(1), packet);
804 })));
805
806 // A packet whose packet number is the largest that is allowed to start a
807 // connection.
808 EXPECT_CALL(*dispatcher_,
809 ShouldCreateOrBufferPacketForConnection(connection_id, _));
810 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
811 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
812 QuicDispatcher::kMaxReasonableInitialPacketNumber);
813 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
814 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
815}
816
817TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
818 CreateTimeWaitListManager();
819 SetQuicRestartFlag(quic_enable_accept_random_ipn, false);
820 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
821 QuicConnectionId connection_id = TestConnectionId(1);
822
823 // Dispatcher forwards this packet for this connection_id to the time wait
824 // list manager.
825 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
826 .Times(0);
827 EXPECT_CALL(*time_wait_list_manager_,
828 ProcessPacket(_, _, TestConnectionId(1), _, _))
829 .Times(1);
830 EXPECT_CALL(*time_wait_list_manager_,
831 ProcessPacket(_, _, TestConnectionId(2), _, _))
832 .Times(1);
833 EXPECT_CALL(*time_wait_list_manager_,
834 AddConnectionIdToTimeWait(_, _, _, _, _))
835 .Times(2);
836 // A packet whose packet number is one to large to be allowed to start a
837 // connection.
838 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
839 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
840 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
841 connection_id = TestConnectionId(2);
842 SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
843 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
844 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
845 MaxRandomInitialPacketNumber().ToUint64() +
846 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
847}
848
849TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
850 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
851 "Supported versions out of sync");
852 SetQuicReloadableFlag(quic_disable_version_39, false);
853 SetQuicReloadableFlag(quic_enable_version_43, true);
854 SetQuicReloadableFlag(quic_enable_version_44, true);
855 SetQuicReloadableFlag(quic_enable_version_46, true);
856 SetQuicReloadableFlag(quic_enable_version_47, true);
857 SetQuicReloadableFlag(quic_enable_version_99, true);
858 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
859 uint64_t conn_id = 1;
860 QuicConnectionId connection_id = TestConnectionId(conn_id);
861
862 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
863 QuicStringPiece("hq"), _))
864 .Times(0);
865 ParsedQuicVersion version(
866 PROTOCOL_QUIC_CRYPTO,
867 static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1));
868 ProcessPacket(client_address, connection_id, true, version, SerializeCHLO(),
869 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
870 connection_id = TestConnectionId(++conn_id);
871 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
872 QuicStringPiece("hq"), _))
873 .WillOnce(testing::Return(CreateSession(
874 dispatcher_.get(), config_, connection_id, client_address,
875 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
876 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
877 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
878 ProcessUdpPacket(_, _, _))
879 .WillOnce(WithArg<2>(
880 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
881 ValidatePacket(connection_id, packet);
882 })));
883 EXPECT_CALL(*dispatcher_,
884 ShouldCreateOrBufferPacketForConnection(connection_id, _));
885 ProcessPacket(client_address, connection_id, true,
886 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
887 QuicVersionMin().transport_version),
888 SerializeCHLO(), CONNECTION_ID_PRESENT,
889 PACKET_4BYTE_PACKET_NUMBER, 1);
890 connection_id = TestConnectionId(++conn_id);
891 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
892 QuicStringPiece("hq"), _))
893 .WillOnce(testing::Return(CreateSession(
894 dispatcher_.get(), config_, connection_id, client_address,
895 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
896 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
897 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
898 ProcessUdpPacket(_, _, _))
899 .WillOnce(WithArg<2>(
900 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
901 ValidatePacket(connection_id, packet);
902 })));
903 EXPECT_CALL(*dispatcher_,
904 ShouldCreateOrBufferPacketForConnection(connection_id, _));
905 ProcessPacket(client_address, connection_id, true, QuicVersionMax(),
906 SerializeCHLO(), CONNECTION_ID_PRESENT,
907 PACKET_4BYTE_PACKET_NUMBER, 1);
908
909 // Turn off version 47.
910 SetQuicReloadableFlag(quic_enable_version_47, false);
911 connection_id = TestConnectionId(++conn_id);
912 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
913 QuicStringPiece("hq"), _))
914 .Times(0);
915 ProcessPacket(client_address, connection_id, true,
916 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
917 SerializeCHLO(), CONNECTION_ID_PRESENT,
918 PACKET_4BYTE_PACKET_NUMBER, 1);
919
920 // Turn on version 47.
921 SetQuicReloadableFlag(quic_enable_version_47, true);
922 connection_id = TestConnectionId(++conn_id);
923 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
924 QuicStringPiece("hq"), _))
925 .WillOnce(testing::Return(CreateSession(
926 dispatcher_.get(), config_, connection_id, client_address,
927 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
928 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
929 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
930 ProcessUdpPacket(_, _, _))
931 .WillOnce(WithArg<2>(
932 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
933 ValidatePacket(connection_id, packet);
934 })));
935 EXPECT_CALL(*dispatcher_,
936 ShouldCreateOrBufferPacketForConnection(connection_id, _));
937 ProcessPacket(client_address, connection_id, true,
938 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
939 SerializeCHLO(), CONNECTION_ID_PRESENT,
940 PACKET_4BYTE_PACKET_NUMBER, 1);
941
942 // Turn off version 46.
943 SetQuicReloadableFlag(quic_enable_version_46, false);
944 connection_id = TestConnectionId(++conn_id);
945 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
946 QuicStringPiece("hq"), _))
947 .Times(0);
948 ProcessPacket(client_address, connection_id, true,
949 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
950 SerializeCHLO(), CONNECTION_ID_PRESENT,
951 PACKET_4BYTE_PACKET_NUMBER, 1);
952
953 // Turn on version 46.
954 SetQuicReloadableFlag(quic_enable_version_46, true);
955 connection_id = TestConnectionId(++conn_id);
956 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
957 QuicStringPiece("hq"), _))
958 .WillOnce(testing::Return(CreateSession(
959 dispatcher_.get(), config_, connection_id, client_address,
960 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
961 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
962 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
963 ProcessUdpPacket(_, _, _))
964 .WillOnce(WithArg<2>(
965 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
966 ValidatePacket(connection_id, packet);
967 })));
968 EXPECT_CALL(*dispatcher_,
969 ShouldCreateOrBufferPacketForConnection(connection_id, _));
970 ProcessPacket(client_address, connection_id, true,
971 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
972 SerializeCHLO(), CONNECTION_ID_PRESENT,
973 PACKET_4BYTE_PACKET_NUMBER, 1);
974
975 // Turn off version 44.
976 SetQuicReloadableFlag(quic_enable_version_44, false);
977 connection_id = TestConnectionId(++conn_id);
978 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
979 QuicStringPiece("hq"), _))
980 .Times(0);
981 ProcessPacket(client_address, connection_id, true,
982 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44),
983 SerializeCHLO(), CONNECTION_ID_PRESENT,
984 PACKET_4BYTE_PACKET_NUMBER, 1);
985
986 // Turn on version 44.
987 SetQuicReloadableFlag(quic_enable_version_44, true);
988 connection_id = TestConnectionId(++conn_id);
989 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
990 QuicStringPiece("hq"), _))
991 .WillOnce(testing::Return(CreateSession(
992 dispatcher_.get(), config_, connection_id, client_address,
993 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
994 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
995 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
996 ProcessUdpPacket(_, _, _))
997 .WillOnce(WithArg<2>(
998 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
999 ValidatePacket(connection_id, packet);
1000 })));
1001 EXPECT_CALL(*dispatcher_,
1002 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1003 ProcessPacket(client_address, connection_id, true,
1004 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44),
1005 SerializeCHLO(), CONNECTION_ID_PRESENT,
1006 PACKET_4BYTE_PACKET_NUMBER, 1);
1007
1008 // Turn off version 43.
1009 SetQuicReloadableFlag(quic_enable_version_43, false);
1010 connection_id = TestConnectionId(++conn_id);
1011 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1012 QuicStringPiece("hq"), _))
1013 .Times(0);
1014 ProcessPacket(client_address, connection_id, true,
1015 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
1016 SerializeCHLO(), CONNECTION_ID_PRESENT,
1017 PACKET_4BYTE_PACKET_NUMBER, 1);
1018
1019 // Turn on version 43.
1020 SetQuicReloadableFlag(quic_enable_version_43, true);
1021 connection_id = TestConnectionId(++conn_id);
1022 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1023 QuicStringPiece("hq"), _))
1024 .WillOnce(testing::Return(CreateSession(
1025 dispatcher_.get(), config_, connection_id, client_address,
1026 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1027 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1028 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1029 ProcessUdpPacket(_, _, _))
1030 .WillOnce(WithArg<2>(
1031 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1032 ValidatePacket(connection_id, packet);
1033 })));
1034 EXPECT_CALL(*dispatcher_,
1035 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1036 ProcessPacket(client_address, connection_id, true,
1037 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
1038 SerializeCHLO(), CONNECTION_ID_PRESENT,
1039 PACKET_4BYTE_PACKET_NUMBER, 1);
1040
1041 // Turn off version 39.
1042 SetQuicReloadableFlag(quic_disable_version_39, true);
1043 connection_id = TestConnectionId(++conn_id);
1044 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1045 QuicStringPiece("hq"), _))
1046 .Times(0);
1047 ProcessPacket(client_address, connection_id, true,
1048 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1049 SerializeCHLO(), CONNECTION_ID_PRESENT,
1050 PACKET_4BYTE_PACKET_NUMBER, 1);
1051
1052 // Turn on version 39.
1053 SetQuicReloadableFlag(quic_disable_version_39, false);
1054 connection_id = TestConnectionId(++conn_id);
1055 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1056 QuicStringPiece("hq"), _))
1057 .WillOnce(testing::Return(CreateSession(
1058 dispatcher_.get(), config_, connection_id, client_address,
1059 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1060 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1061 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1062 ProcessUdpPacket(_, _, _))
1063 .WillOnce(WithArg<2>(
1064 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1065 ValidatePacket(connection_id, packet);
1066 })));
1067 EXPECT_CALL(*dispatcher_,
1068 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1069 ProcessPacket(client_address, connection_id, true,
1070 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1071 SerializeCHLO(), CONNECTION_ID_PRESENT,
1072 PACKET_4BYTE_PACKET_NUMBER, 1);
1073}
1074
1075// Enables mocking of the handshake-confirmation for stateless rejects.
1076class MockQuicCryptoServerStream : public QuicCryptoServerStream {
1077 public:
1078 MockQuicCryptoServerStream(const QuicCryptoServerConfig& crypto_config,
1079 QuicCompressedCertsCache* compressed_certs_cache,
1080 QuicServerSessionBase* session,
1081 QuicCryptoServerStream::Helper* helper)
1082 : QuicCryptoServerStream(
1083 &crypto_config,
1084 compressed_certs_cache,
1085 GetQuicReloadableFlag(enable_quic_stateless_reject_support),
1086 session,
1087 helper),
1088 handshake_confirmed_(false) {}
1089 MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
1090 MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
1091 delete;
1092
1093 void set_handshake_confirmed_for_testing(bool handshake_confirmed) {
1094 handshake_confirmed_ = handshake_confirmed;
1095 }
1096
1097 bool handshake_confirmed() const override { return handshake_confirmed_; }
1098
1099 private:
1100 bool handshake_confirmed_;
1101};
1102
1103struct StatelessRejectTestParams {
1104 StatelessRejectTestParams(bool enable_stateless_rejects_via_flag,
1105 bool client_supports_statelesss_rejects,
1106 bool crypto_handshake_successful)
1107 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
1108 client_supports_statelesss_rejects(client_supports_statelesss_rejects),
1109 crypto_handshake_successful(crypto_handshake_successful) {}
1110
1111 friend std::ostream& operator<<(std::ostream& os,
1112 const StatelessRejectTestParams& p) {
1113 os << "{ enable_stateless_rejects_via_flag: "
1114 << p.enable_stateless_rejects_via_flag << std::endl;
1115 os << " client_supports_statelesss_rejects: "
1116 << p.client_supports_statelesss_rejects << std::endl;
1117 os << " crypto_handshake_successful: " << p.crypto_handshake_successful
1118 << " }";
1119 return os;
1120 }
1121
1122 // This only enables the stateless reject feature via the feature-flag.
1123 // This should be a no-op if the peer does not support them.
1124 bool enable_stateless_rejects_via_flag;
1125 // Whether or not the client supports stateless rejects.
1126 bool client_supports_statelesss_rejects;
1127 // Should the initial crypto handshake succeed or not.
1128 bool crypto_handshake_successful;
1129};
1130
1131// Constructs various test permutations for stateless rejects.
1132std::vector<StatelessRejectTestParams> GetStatelessRejectTestParams() {
1133 std::vector<StatelessRejectTestParams> params;
1134 for (bool enable_stateless_rejects_via_flag : {true, false}) {
1135 for (bool client_supports_statelesss_rejects : {true, false}) {
1136 for (bool crypto_handshake_successful : {true, false}) {
1137 params.push_back(StatelessRejectTestParams(
1138 enable_stateless_rejects_via_flag,
1139 client_supports_statelesss_rejects, crypto_handshake_successful));
1140 }
1141 }
1142 }
1143 return params;
1144}
1145
1146class QuicDispatcherStatelessRejectTest
1147 : public QuicDispatcherTest,
1148 public testing::WithParamInterface<StatelessRejectTestParams> {
1149 public:
1150 QuicDispatcherStatelessRejectTest()
1151 : QuicDispatcherTest(), crypto_stream1_(nullptr) {}
1152
1153 ~QuicDispatcherStatelessRejectTest() override {
1154 if (crypto_stream1_) {
1155 delete crypto_stream1_;
1156 }
1157 }
1158
1159 // This test setup assumes that all testing will be done using
1160 // crypto_stream1_.
1161 void SetUp() override {
1162 QuicDispatcherTest::SetUp();
1163 SetQuicReloadableFlag(enable_quic_stateless_reject_support,
1164 GetParam().enable_stateless_rejects_via_flag);
1165 }
1166
1167 // Returns true or false, depending on whether the server will emit
1168 // a stateless reject, depending upon the parameters of the test.
1169 bool ExpectStatelessReject() {
1170 return GetParam().enable_stateless_rejects_via_flag &&
1171 !GetParam().crypto_handshake_successful &&
1172 GetParam().client_supports_statelesss_rejects;
1173 }
1174
1175 // Sets up dispatcher_, session1_, and crypto_stream1_ based on
1176 // the test parameters.
1177 QuicServerSessionBase* CreateSessionBasedOnTestParams(
1178 QuicConnectionId connection_id,
1179 const QuicSocketAddress& client_address) {
1180 CreateSession(dispatcher_.get(), config_, connection_id, client_address,
1181 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1182 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_);
1183
1184 crypto_stream1_ = new MockQuicCryptoServerStream(
1185 crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1186 session1_, session1_->stream_helper());
1187 session1_->SetCryptoStream(crypto_stream1_);
1188 crypto_stream1_->set_handshake_confirmed_for_testing(
1189 GetParam().crypto_handshake_successful);
1190 crypto_stream1_->SetPeerSupportsStatelessRejects(
1191 GetParam().client_supports_statelesss_rejects);
1192 return session1_;
1193 }
1194
1195 MockQuicCryptoServerStream* crypto_stream1_;
1196};
1197
1198// Parameterized test for stateless rejects. Should test all
1199// combinations of enabling/disabling, reject/no-reject for stateless
1200// rejects.
1201INSTANTIATE_TEST_SUITE_P(QuicDispatcherStatelessRejectTests,
1202 QuicDispatcherStatelessRejectTest,
1203 ::testing::ValuesIn(GetStatelessRejectTestParams()));
1204
1205TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
1206 CreateTimeWaitListManager();
1207
1208 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1209 QuicConnectionId connection_id = TestConnectionId(1);
1210 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1211 QuicStringPiece("hq"), _))
1212 .WillOnce(testing::Return(
1213 CreateSessionBasedOnTestParams(connection_id, client_address)));
1214 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1215 ProcessUdpPacket(_, _, _))
1216 .WillOnce(WithArg<2>(
1217 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1218 ValidatePacket(connection_id, packet);
1219 })));
1220 EXPECT_CALL(*dispatcher_,
1221 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1222 .Times(1);
1223
1224 // Process the first packet for the connection.
1225 ProcessPacket(client_address, connection_id, true, SerializeCHLO());
1226 if (ExpectStatelessReject()) {
1227 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1228 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
1229 // If this is a stateless reject, the crypto stream will close the
1230 // connection.
1231 session1_->connection()->CloseConnection(
1232 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
1233 ConnectionCloseBehavior::SILENT_CLOSE);
1234 }
1235
1236 // Send a second packet and check the results. If this is a stateless reject,
1237 // the existing connection_id will go on the time-wait list.
1238 EXPECT_EQ(ExpectStatelessReject(),
1239 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1240 if (ExpectStatelessReject()) {
1241 // The second packet will be processed on the time-wait list.
1242 EXPECT_CALL(*time_wait_list_manager_,
1243 ProcessPacket(_, _, connection_id, _, _))
1244 .Times(1);
1245 } else {
1246 // The second packet will trigger a packet-validation
1247 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1248 ProcessUdpPacket(_, _, _))
1249 .Times(1)
1250 .WillOnce(WithArg<2>(
1251 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1252 ValidatePacket(connection_id, packet);
1253 })));
1254 }
1255 ProcessPacket(client_address, connection_id, true, "data");
1256}
1257
1258TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
1259 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
1260 CreateTimeWaitListManager();
1261
1262 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1263 QuicConnectionId connection_id = TestConnectionId(1);
1264 if (GetParam().enable_stateless_rejects_via_flag) {
1265 EXPECT_CALL(*dispatcher_,
1266 CreateQuicSession(connection_id, client_address, _, _))
1267 .Times(0);
1268 } else {
1269 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1270 QuicStringPiece("h2"), _))
1271 .WillOnce(testing::Return(
1272 CreateSessionBasedOnTestParams(connection_id, client_address)));
1273 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1274 ProcessUdpPacket(_, _, _))
1275 .WillOnce(WithArg<2>(
1276 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1277 ValidatePacket(connection_id, packet);
1278 })));
1279 }
1280
1281 QUIC_LOG(INFO) << "ExpectStatelessReject: " << ExpectStatelessReject();
1282 QUIC_LOG(INFO) << "Params: " << GetParam();
1283 // Process the first packet for the connection.
1284 CryptoHandshakeMessage client_hello =
1285 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
1286 {"KEXS", "C255"},
1287 {"COPT", "SREJ"},
1288 {"NONC", "1234567890123456789012"},
1289 {"ALPN", "h2"},
1290 {"VER\0", "Q025"}},
1291 kClientHelloMinimumSize);
1292
1293 if (GetParam().enable_stateless_rejects_via_flag) {
1294 EXPECT_CALL(*time_wait_list_manager_,
1295 ProcessPacket(_, _, connection_id, _, _))
1296 .Times(1);
1297 } else {
1298 EXPECT_CALL(*dispatcher_,
1299 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1300 .Times(1);
1301 }
1302 ProcessPacket(client_address, connection_id, true,
vasilvvc48c8712019-03-11 13:38:16 -07001303 std::string(client_hello.GetSerialized().AsStringPiece()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001304
1305 if (GetParam().enable_stateless_rejects_via_flag) {
1306 EXPECT_EQ(true,
1307 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1308 }
1309}
1310
1311TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
1312 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
1313 CreateTimeWaitListManager();
1314
1315 const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1316 const QuicConnectionId connection_id = TestConnectionId(1);
1317
1318 EXPECT_CALL(*dispatcher_,
1319 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1320 .Times(1);
1321 ProcessPacket(client_address, connection_id, true, "NOT DATA FOR A CHLO");
1322
1323 // Process the first packet for the connection.
1324 CryptoHandshakeMessage client_hello =
1325 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
1326 {"KEXS", "C255"},
1327 {"NONC", "1234567890123456789012"},
1328 {"ALPN", "h3"},
1329 {"VER\0", "Q025"}},
1330 kClientHelloMinimumSize);
1331
1332 // If stateless rejects are enabled then a connection will be created now
1333 // and the buffered packet will be processed
1334 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1335 QuicStringPiece("h3"), _))
1336 .WillOnce(testing::Return(
1337 CreateSessionBasedOnTestParams(connection_id, client_address)));
1338 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1339 ProcessUdpPacket(_, client_address, _))
1340 .WillOnce(WithArg<2>(
1341 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1342 ValidatePacket(connection_id, packet);
1343 })));
1344 // Expect both packets to be passed to ProcessUdpPacket(). And one of them
1345 // is already expected in CreateSessionBasedOnTestParams().
1346 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1347 ProcessUdpPacket(_, client_address, _))
1348 .WillOnce(WithArg<2>(
1349 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1350 ValidatePacket(connection_id, packet);
1351 })))
1352 .RetiresOnSaturation();
1353 ProcessPacket(client_address, connection_id, true,
vasilvvc48c8712019-03-11 13:38:16 -07001354 std::string(client_hello.GetSerialized().AsStringPiece()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001355 EXPECT_FALSE(
1356 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1357}
1358
1359// Verify the stopgap test: Packets with truncated connection IDs should be
1360// dropped.
1361class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
1362
1363// Packets with truncated connection IDs should be dropped.
1364TEST_F(QuicDispatcherTestStrayPacketConnectionId,
1365 StrayPacketTruncatedConnectionId) {
1366 CreateTimeWaitListManager();
1367
1368 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1369 QuicConnectionId connection_id = TestConnectionId(1);
1370 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
1371 .Times(0);
QUICHE team963d57e2019-03-21 10:58:47 -07001372 if (CurrentSupportedVersions()[0].transport_version > QUIC_VERSION_43 &&
1373 !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
1374 CurrentSupportedVersions()[0].transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001375 // This IETF packet has invalid connection ID length.
1376 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1377 .Times(0);
1378 EXPECT_CALL(*time_wait_list_manager_,
1379 AddConnectionIdToTimeWait(_, _, _, _, _))
1380 .Times(0);
1381 } else {
QUICHE team8e2e4532019-03-14 14:37:56 -07001382 // This is either:
1383 // - a GQUIC packet considered as IETF QUIC packet with short header
1384 // with unacceptable packet number or
1385 // - an IETF QUIC packet with bad connection ID length which is rejected.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001386 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1387 .Times(1);
1388 EXPECT_CALL(*time_wait_list_manager_,
1389 AddConnectionIdToTimeWait(_, _, _, _, _))
1390 .Times(1);
1391 }
1392 ProcessPacket(client_address, connection_id, true, "data",
1393 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1394}
1395
1396class BlockingWriter : public QuicPacketWriterWrapper {
1397 public:
1398 BlockingWriter() : write_blocked_(false) {}
1399
1400 bool IsWriteBlocked() const override { return write_blocked_; }
1401 void SetWritable() override { write_blocked_ = false; }
1402
1403 WriteResult WritePacket(const char* buffer,
1404 size_t buf_len,
1405 const QuicIpAddress& self_client_address,
1406 const QuicSocketAddress& peer_client_address,
1407 PerPacketOptions* options) override {
1408 // It would be quite possible to actually implement this method here with
1409 // the fake blocked status, but it would be significantly more work in
1410 // Chromium, and since it's not called anyway, don't bother.
1411 QUIC_LOG(DFATAL) << "Not supported";
1412 return WriteResult();
1413 }
1414
1415 bool write_blocked_;
1416};
1417
1418class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
1419 public:
1420 void SetUp() override {
1421 QuicDispatcherTest::SetUp();
1422 writer_ = new BlockingWriter;
1423 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1424
1425 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1426
1427 EXPECT_CALL(*dispatcher_,
1428 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1429 .WillOnce(testing::Return(CreateSession(
1430 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1431 &helper_, &alarm_factory_, &crypto_config_,
1432 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1433 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1434 ProcessUdpPacket(_, _, _))
1435 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1436 ValidatePacket(TestConnectionId(1), packet);
1437 })));
1438 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1439 TestConnectionId(1), _));
1440 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
1441
1442 EXPECT_CALL(*dispatcher_,
1443 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1444 .WillOnce(testing::Return(CreateSession(
1445 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1446 &helper_, &alarm_factory_, &crypto_config_,
1447 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
1448 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1449 ProcessUdpPacket(_, _, _))
1450 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1451 ValidatePacket(TestConnectionId(2), packet);
1452 })));
1453 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1454 TestConnectionId(2), _));
1455 ProcessPacket(client_address, TestConnectionId(2), true, SerializeCHLO());
1456
1457 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1458 }
1459
1460 void TearDown() override {
1461 if (connection1() != nullptr) {
1462 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1463 }
1464
1465 if (connection2() != nullptr) {
1466 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1467 }
1468 dispatcher_->Shutdown();
1469 }
1470
1471 // Set the dispatcher's writer to be blocked. By default, all connections use
1472 // the same writer as the dispatcher in this test.
1473 void SetBlocked() {
1474 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1475 writer_->write_blocked_ = true;
1476 }
1477
1478 // Simulate what happens when connection1 gets blocked when writing.
1479 void BlockConnection1() {
1480 Connection1Writer()->write_blocked_ = true;
1481 dispatcher_->OnWriteBlocked(connection1());
1482 }
1483
1484 BlockingWriter* Connection1Writer() {
1485 return static_cast<BlockingWriter*>(connection1()->writer());
1486 }
1487
1488 // Simulate what happens when connection2 gets blocked when writing.
1489 void BlockConnection2() {
1490 Connection2Writer()->write_blocked_ = true;
1491 dispatcher_->OnWriteBlocked(connection2());
1492 }
1493
1494 BlockingWriter* Connection2Writer() {
1495 return static_cast<BlockingWriter*>(connection2()->writer());
1496 }
1497
1498 protected:
1499 MockQuicConnectionHelper helper_;
1500 MockAlarmFactory alarm_factory_;
1501 BlockingWriter* writer_;
1502 QuicDispatcher::WriteBlockedList* blocked_list_;
1503};
1504
1505TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
1506 // No OnCanWrite calls because no connections are blocked.
1507 dispatcher_->OnCanWrite();
1508
1509 // Register connection 1 for events, and make sure it's notified.
1510 SetBlocked();
1511 dispatcher_->OnWriteBlocked(connection1());
1512 EXPECT_CALL(*connection1(), OnCanWrite());
1513 dispatcher_->OnCanWrite();
1514
1515 // It should get only one notification.
1516 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1517 dispatcher_->OnCanWrite();
1518 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1519}
1520
1521TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
1522 // Make sure we handle events in order.
1523 InSequence s;
1524 SetBlocked();
1525 dispatcher_->OnWriteBlocked(connection1());
1526 dispatcher_->OnWriteBlocked(connection2());
1527 EXPECT_CALL(*connection1(), OnCanWrite());
1528 EXPECT_CALL(*connection2(), OnCanWrite());
1529 dispatcher_->OnCanWrite();
1530
1531 // Check the other ordering.
1532 SetBlocked();
1533 dispatcher_->OnWriteBlocked(connection2());
1534 dispatcher_->OnWriteBlocked(connection1());
1535 EXPECT_CALL(*connection2(), OnCanWrite());
1536 EXPECT_CALL(*connection1(), OnCanWrite());
1537 dispatcher_->OnCanWrite();
1538}
1539
1540TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
1541 // Add and remove one connction.
1542 SetBlocked();
1543 dispatcher_->OnWriteBlocked(connection1());
1544 blocked_list_->erase(connection1());
1545 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1546 dispatcher_->OnCanWrite();
1547
1548 // Add and remove one connction and make sure it doesn't affect others.
1549 SetBlocked();
1550 dispatcher_->OnWriteBlocked(connection1());
1551 dispatcher_->OnWriteBlocked(connection2());
1552 blocked_list_->erase(connection1());
1553 EXPECT_CALL(*connection2(), OnCanWrite());
1554 dispatcher_->OnCanWrite();
1555
1556 // Add it, remove it, and add it back and make sure things are OK.
1557 SetBlocked();
1558 dispatcher_->OnWriteBlocked(connection1());
1559 blocked_list_->erase(connection1());
1560 dispatcher_->OnWriteBlocked(connection1());
1561 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1562 dispatcher_->OnCanWrite();
1563}
1564
1565TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
1566 // Make sure a double add does not necessitate a double remove.
1567 SetBlocked();
1568 dispatcher_->OnWriteBlocked(connection1());
1569 dispatcher_->OnWriteBlocked(connection1());
1570 blocked_list_->erase(connection1());
1571 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1572 dispatcher_->OnCanWrite();
1573
1574 // Make sure a double add does not result in two OnCanWrite calls.
1575 SetBlocked();
1576 dispatcher_->OnWriteBlocked(connection1());
1577 dispatcher_->OnWriteBlocked(connection1());
1578 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1579 dispatcher_->OnCanWrite();
1580}
1581
1582TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
1583 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1584 // into the write blocked list.
1585 InSequence s;
1586 SetBlocked();
1587 dispatcher_->OnWriteBlocked(connection1());
1588 dispatcher_->OnWriteBlocked(connection2());
1589 EXPECT_CALL(*connection1(), OnCanWrite())
1590 .WillOnce(
1591 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1592 EXPECT_CALL(*connection2(), OnCanWrite());
1593 dispatcher_->OnCanWrite();
1594
1595 // connection1 should be still in the write blocked list.
1596 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1597
1598 // Now call OnCanWrite again, connection1 should get its second chance.
1599 EXPECT_CALL(*connection1(), OnCanWrite());
1600 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1601 dispatcher_->OnCanWrite();
1602 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1603}
1604
1605TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
1606 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1607 // into the write blocked list.
1608 InSequence s;
1609 SetBlocked();
1610 dispatcher_->OnWriteBlocked(connection1());
1611 dispatcher_->OnWriteBlocked(connection2());
1612 EXPECT_CALL(*connection1(), OnCanWrite());
1613 EXPECT_CALL(*connection2(), OnCanWrite())
1614 .WillOnce(
1615 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1616 dispatcher_->OnCanWrite();
1617
1618 // connection2 should be still in the write blocked list.
1619 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1620
1621 // Now call OnCanWrite again, connection2 should get its second chance.
1622 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1623 EXPECT_CALL(*connection2(), OnCanWrite());
1624 dispatcher_->OnCanWrite();
1625 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1626}
1627
1628TEST_F(QuicDispatcherWriteBlockedListTest,
1629 OnCanWriteHandleBlockBothConnections) {
1630 // Both connections get blocked in OnCanWrite, and added back into the write
1631 // blocked list.
1632 InSequence s;
1633 SetBlocked();
1634 dispatcher_->OnWriteBlocked(connection1());
1635 dispatcher_->OnWriteBlocked(connection2());
1636 EXPECT_CALL(*connection1(), OnCanWrite())
1637 .WillOnce(
1638 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1639 EXPECT_CALL(*connection2(), OnCanWrite())
1640 .WillOnce(
1641 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1642 dispatcher_->OnCanWrite();
1643
1644 // Both connections should be still in the write blocked list.
1645 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1646
1647 // Now call OnCanWrite again, both connections should get its second chance.
1648 EXPECT_CALL(*connection1(), OnCanWrite());
1649 EXPECT_CALL(*connection2(), OnCanWrite());
1650 dispatcher_->OnCanWrite();
1651 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1652}
1653
1654TEST_F(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
1655 // By default, all connections share the same packet writer with the
1656 // dispatcher.
1657 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1658 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1659
1660 // Test the case where connection1 shares the same packet writer as the
1661 // dispatcher, whereas connection2 owns it's packet writer.
1662 // Change connection2's writer.
1663 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1664 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1665
1666 BlockConnection2();
1667 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1668
1669 EXPECT_CALL(*connection2(), OnCanWrite());
1670 dispatcher_->OnCanWrite();
1671 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1672}
1673
1674TEST_F(QuicDispatcherWriteBlockedListTest,
1675 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001676 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1677 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1678 ConnectionCloseSource::FROM_SELF);
1679
1680 SetBlocked();
1681
1682 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1683 SetBlocked();
1684 dispatcher_->OnWriteBlocked(connection1());
1685 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1686
1687 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1688 "QuicConnection was in WriteBlockedList before destruction");
1689 MarkSession1Deleted();
1690}
1691
1692// Tests that bufferring packets works in stateful reject, expensive stateless
1693// reject and cheap stateless reject.
1694struct BufferedPacketStoreTestParams {
1695 BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag,
1696 bool support_cheap_stateless_reject)
1697 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
1698 support_cheap_stateless_reject(support_cheap_stateless_reject) {}
1699
1700 friend std::ostream& operator<<(std::ostream& os,
1701 const BufferedPacketStoreTestParams& p) {
1702 os << "{ enable_stateless_rejects_via_flag: "
1703 << p.enable_stateless_rejects_via_flag << std::endl;
1704 os << " support_cheap_stateless_reject: "
1705 << p.support_cheap_stateless_reject << " }";
1706 return os;
1707 }
1708
1709 // This only enables the stateless reject feature via the feature-flag.
1710 // This should be a no-op if the peer does not support them.
1711 bool enable_stateless_rejects_via_flag;
1712 // Whether to do cheap stateless or not.
1713 bool support_cheap_stateless_reject;
1714};
1715
1716std::vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() {
1717 std::vector<BufferedPacketStoreTestParams> params;
1718 for (bool enable_stateless_rejects_via_flag : {true, false}) {
1719 for (bool support_cheap_stateless_reject : {true, false}) {
1720 params.push_back(BufferedPacketStoreTestParams(
1721 enable_stateless_rejects_via_flag, support_cheap_stateless_reject));
1722 }
1723 }
1724 return params;
1725}
1726
1727// A dispatcher whose stateless rejector will always ACCEPTs CHLO.
1728class BufferedPacketStoreTest
1729 : public QuicDispatcherTest,
1730 public testing::WithParamInterface<BufferedPacketStoreTestParams> {
1731 public:
1732 BufferedPacketStoreTest()
1733 : QuicDispatcherTest(),
1734 server_addr_(QuicSocketAddress(QuicIpAddress::Any4(), 5)),
1735 client_addr_(QuicIpAddress::Loopback4(), 1234),
1736 signed_config_(new QuicSignedServerConfig) {
1737 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
1738 GetParam().support_cheap_stateless_reject);
1739 SetQuicReloadableFlag(enable_quic_stateless_reject_support,
1740 GetParam().enable_stateless_rejects_via_flag);
1741 }
1742
1743 void SetUp() override {
1744 QuicDispatcherTest::SetUp();
1745 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
1746
1747 QuicTransportVersion version = AllSupportedTransportVersions().front();
1748 CryptoHandshakeMessage chlo =
1749 crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
1750 &crypto_config_);
1751 chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
1752 // Pass an inchoate CHLO.
1753 crypto_test_utils::GenerateFullCHLO(
1754 chlo, &crypto_config_, server_addr_, client_addr_, version, clock_,
1755 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1756 &full_chlo_);
1757 }
1758
vasilvvc48c8712019-03-11 13:38:16 -07001759 std::string SerializeFullCHLO() {
1760 return std::string(full_chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001761 }
1762
1763 protected:
1764 QuicSocketAddress server_addr_;
1765 QuicSocketAddress client_addr_;
1766 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
1767 const QuicClock* clock_;
1768 CryptoHandshakeMessage full_chlo_;
1769};
1770
1771INSTANTIATE_TEST_SUITE_P(
1772 BufferedPacketStoreTests,
1773 BufferedPacketStoreTest,
1774 ::testing::ValuesIn(GetBufferedPacketStoreTestParams()));
1775
1776TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
1777 InSequence s;
1778 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1779 QuicConnectionId conn_id = TestConnectionId(1);
1780 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1781 // should trigger ShouldCreateOrBufferPacketForConnection().
1782 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id, _))
1783 .Times(1);
1784 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
1785 ProcessPacket(client_address, conn_id, true,
1786 QuicStrCat("data packet ", i + 1), CONNECTION_ID_PRESENT,
1787 PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
1788 }
1789 EXPECT_EQ(0u, dispatcher_->session_map().size())
1790 << "No session should be created before CHLO arrives.";
1791
1792 // Pop out the last packet as it is also be dropped by the store.
1793 data_connection_map_[conn_id].pop_back();
1794 // When CHLO arrives, a new session should be created, and all packets
1795 // buffered should be delivered to the session.
1796 EXPECT_CALL(*dispatcher_,
1797 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1798 .WillOnce(testing::Return(CreateSession(
1799 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1800 &mock_alarm_factory_, &crypto_config_,
1801 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1802
1803 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1804 // should be delivered in arrival order.
1805 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1806 ProcessUdpPacket(_, _, _))
1807 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1808 .WillRepeatedly(
1809 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1810 ValidatePacket(conn_id, packet);
1811 })));
1812 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1813}
1814
1815TEST_P(BufferedPacketStoreTest,
1816 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1817 InSequence s;
1818 // A bunch of non-CHLO should be buffered upon arrival.
1819 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1820 for (size_t i = 1; i <= kNumConnections; ++i) {
1821 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1822 QuicConnectionId conn_id = TestConnectionId(i);
1823 EXPECT_CALL(*dispatcher_,
1824 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1825 ProcessPacket(client_address, conn_id, true,
1826 QuicStrCat("data packet on connection ", i),
1827 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1828 /*packet_number=*/2);
1829 }
1830
1831 // Pop out the packet on last connection as it shouldn't be enqueued in store
1832 // as well.
1833 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1834
1835 // Reset session creation counter to ensure processing CHLO can always
1836 // create session.
1837 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
1838 kNumConnections);
1839 // Process CHLOs to create session for these connections.
1840 for (size_t i = 1; i <= kNumConnections; ++i) {
1841 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1842 QuicConnectionId conn_id = TestConnectionId(i);
1843 if (i == kNumConnections) {
1844 EXPECT_CALL(*dispatcher_,
1845 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1846 }
1847 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address,
1848 QuicStringPiece(), _))
1849 .WillOnce(testing::Return(CreateSession(
1850 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1851 &mock_alarm_factory_, &crypto_config_,
1852 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1853 // First |kNumConnections| - 1 connections should have buffered
1854 // a packet in store. The rest should have been dropped.
1855 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
1856 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1857 ProcessUdpPacket(_, client_address, _))
1858 .Times(num_packet_to_process)
1859 .WillRepeatedly(WithArg<2>(
1860 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1861 ValidatePacket(conn_id, packet);
1862 })));
1863
1864 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1865 }
1866}
1867
1868// Tests that store delivers empty packet list if CHLO arrives firstly.
1869TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
1870 QuicConnectionId conn_id = TestConnectionId(1);
1871 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1872 EXPECT_CALL(*dispatcher_,
1873 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1874 EXPECT_CALL(*dispatcher_,
1875 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1876 .WillOnce(testing::Return(CreateSession(
1877 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1878 &mock_alarm_factory_, &crypto_config_,
1879 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1880 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1881 ProcessUdpPacket(_, client_address, _));
1882 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1883}
1884
1885// Tests that a retransmitted CHLO arrives after a connection for the
1886// CHLO has been created.
1887TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
1888 InSequence s;
1889 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1890 QuicConnectionId conn_id = TestConnectionId(1);
1891 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1892 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1893 /*packet_number=*/2);
1894
1895 // When CHLO arrives, a new session should be created, and all packets
1896 // buffered should be delivered to the session.
1897 EXPECT_CALL(*dispatcher_,
1898 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1899 .Times(1) // Only triggered by 1st CHLO.
1900 .WillOnce(testing::Return(CreateSession(
1901 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1902 &mock_alarm_factory_, &crypto_config_,
1903 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1904 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1905 ProcessUdpPacket(_, _, _))
1906 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
1907 .WillRepeatedly(
1908 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1909 ValidatePacket(conn_id, packet);
1910 })));
1911 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1912
1913 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1914}
1915
1916// Tests that expiration of a connection add connection id to time wait list.
1917TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
1918 InSequence s;
1919 CreateTimeWaitListManager();
1920 QuicBufferedPacketStore* store =
1921 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1922 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
1923
1924 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1925 QuicConnectionId conn_id = TestConnectionId(1);
1926 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1927 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1928 /*packet_number=*/2);
1929
1930 mock_helper_.AdvanceTime(
1931 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
1932 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
1933 // Cancel alarm as if it had been fired.
1934 alarm->Cancel();
1935 store->OnExpirationTimeout();
1936 // New arrived CHLO will be dropped because this connection is in time wait
1937 // list.
1938 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
1939 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
1940 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1941}
1942
1943TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
1944 // Process more than (|kMaxNumSessionsToCreate| +
1945 // |kDefaultMaxConnectionsInStore|) CHLOs,
1946 // the first |kMaxNumSessionsToCreate| should create connections immediately,
1947 // the next |kDefaultMaxConnectionsInStore| should be buffered,
1948 // the rest should be dropped.
1949 QuicBufferedPacketStore* store =
1950 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1951 const size_t kNumCHLOs =
1952 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
1953 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
1954 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1955 TestConnectionId(conn_id), _));
1956 if (conn_id <= kMaxNumSessionsToCreate) {
1957 EXPECT_CALL(*dispatcher_,
1958 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1959 QuicStringPiece(), _))
1960 .WillOnce(testing::Return(CreateSession(
1961 dispatcher_.get(), config_, TestConnectionId(conn_id),
1962 client_addr_, &mock_helper_, &mock_alarm_factory_,
1963 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1964 &session1_)));
1965 EXPECT_CALL(
1966 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1967 ProcessUdpPacket(_, _, _))
1968 .WillOnce(WithArg<2>(
1969 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1970 ValidatePacket(TestConnectionId(conn_id), packet);
1971 })));
1972 }
1973 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1974 SerializeFullCHLO());
1975 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
1976 conn_id > kMaxNumSessionsToCreate) {
1977 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
1978 } else {
1979 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
1980 // connections immediately, and the last CHLO should be dropped as the
1981 // store is full.
1982 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
1983 }
1984 }
1985
1986 // Graduately consume buffered CHLOs. The buffered connections should be
1987 // created but the dropped one shouldn't.
1988 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
1989 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
1990 ++conn_id) {
1991 EXPECT_CALL(*dispatcher_,
1992 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1993 QuicStringPiece(), _))
1994 .WillOnce(testing::Return(CreateSession(
1995 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
1996 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1997 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1998 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1999 ProcessUdpPacket(_, _, _))
2000 .WillOnce(WithArg<2>(
2001 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2002 ValidatePacket(TestConnectionId(conn_id), packet);
2003 })));
2004 }
2005 EXPECT_CALL(*dispatcher_,
2006 CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_,
2007 QuicStringPiece(), _))
2008 .Times(0);
2009
2010 while (store->HasChlosBuffered()) {
2011 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2012 }
2013
2014 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
2015 kDefaultMaxConnectionsInStore),
2016 session1_->connection_id());
2017}
2018
2019// Duplicated CHLO shouldn't be buffered.
2020TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
2021 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
2022 ++conn_id) {
2023 // Last CHLO will be buffered. Others will create connection right away.
2024 if (conn_id <= kMaxNumSessionsToCreate) {
2025 EXPECT_CALL(*dispatcher_,
2026 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2027 QuicStringPiece(), _))
2028 .WillOnce(testing::Return(CreateSession(
2029 dispatcher_.get(), config_, TestConnectionId(conn_id),
2030 client_addr_, &mock_helper_, &mock_alarm_factory_,
2031 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2032 &session1_)));
2033 EXPECT_CALL(
2034 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2035 ProcessUdpPacket(_, _, _))
2036 .WillOnce(WithArg<2>(
2037 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2038 ValidatePacket(TestConnectionId(conn_id), packet);
2039 })));
2040 }
2041 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2042 SerializeFullCHLO());
2043 }
2044 // Retransmit CHLO on last connection should be dropped.
2045 QuicConnectionId last_connection =
2046 TestConnectionId(kMaxNumSessionsToCreate + 1);
2047 ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO());
2048
2049 size_t packets_buffered = 2;
2050
2051 // Reset counter and process buffered CHLO.
2052 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
2053 QuicStringPiece(), _))
2054 .WillOnce(testing::Return(CreateSession(
2055 dispatcher_.get(), config_, last_connection, client_addr_,
2056 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2057 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2058 // Only one packet(CHLO) should be process.
2059 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2060 ProcessUdpPacket(_, _, _))
2061 .Times(packets_buffered)
2062 .WillRepeatedly(WithArg<2>(
2063 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
2064 ValidatePacket(last_connection, packet);
2065 })));
2066 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2067}
2068
2069TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
2070 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2071 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2072 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2073 // Last CHLO will be buffered. Others will create connection right away.
2074 if (conn_id <= kMaxNumSessionsToCreate) {
2075 EXPECT_CALL(*dispatcher_,
2076 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2077 QuicStringPiece(), _))
2078 .WillOnce(testing::Return(CreateSession(
2079 dispatcher_.get(), config_, TestConnectionId(conn_id),
2080 client_addr_, &mock_helper_, &mock_alarm_factory_,
2081 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2082 &session1_)));
2083 EXPECT_CALL(
2084 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2085 ProcessUdpPacket(_, _, _))
2086 .WillRepeatedly(WithArg<2>(
2087 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2088 ValidatePacket(TestConnectionId(conn_id), packet);
2089 })));
2090 }
2091 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2092 SerializeFullCHLO());
2093 }
2094
2095 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
2096 // last one should be dropped.
2097 for (uint64_t packet_number = 2;
2098 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
2099 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
2100 }
2101
2102 // Reset counter and process buffered CHLO.
2103 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
2104 QuicStringPiece(), _))
2105 .WillOnce(testing::Return(CreateSession(
2106 dispatcher_.get(), config_, last_connection_id, client_addr_,
2107 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2108 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2109 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
2110 // should be process.
2111 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2112 ProcessUdpPacket(_, _, _))
2113 .Times(kDefaultMaxUndecryptablePackets + 1)
2114 .WillRepeatedly(WithArg<2>(
2115 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
2116 ValidatePacket(last_connection_id, packet);
2117 })));
2118 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2119}
2120
2121// Tests that when dispatcher's packet buffer is full, a CHLO on connection
2122// which doesn't have buffered CHLO should be buffered.
2123TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
2124 QuicBufferedPacketStore* store =
2125 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2126
2127 uint64_t conn_id = 1;
2128 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, "data packet",
2129 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
2130 /*packet_number=*/1);
2131 // Fill packet buffer to full with CHLOs on other connections. Need to feed
2132 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
2133 // session directly.
2134 for (conn_id = 2;
2135 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
2136 ++conn_id) {
2137 if (conn_id <= kMaxNumSessionsToCreate + 1) {
2138 EXPECT_CALL(*dispatcher_,
2139 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2140 QuicStringPiece(), _))
2141 .WillOnce(testing::Return(CreateSession(
2142 dispatcher_.get(), config_, TestConnectionId(conn_id),
2143 client_addr_, &mock_helper_, &mock_alarm_factory_,
2144 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2145 &session1_)));
2146 EXPECT_CALL(
2147 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2148 ProcessUdpPacket(_, _, _))
2149 .WillOnce(WithArg<2>(
2150 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2151 ValidatePacket(TestConnectionId(conn_id), packet);
2152 })));
2153 }
2154 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2155 SerializeFullCHLO());
2156 }
2157 EXPECT_FALSE(store->HasChloForConnection(
2158 /*connection_id=*/TestConnectionId(1)));
2159
2160 // CHLO on connection 1 should still be buffered.
2161 ProcessPacket(client_addr_, /*connection_id=*/TestConnectionId(1), true,
2162 SerializeFullCHLO());
2163 EXPECT_TRUE(store->HasChloForConnection(
2164 /*connection_id=*/TestConnectionId(1)));
2165}
2166
2167// Regression test for b/117874922.
2168TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
2169 // Turn off version 99, such that the preferred version is not supported by
2170 // the server.
2171 SetQuicReloadableFlag(quic_enable_version_99, false);
2172 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
2173 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
2174 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
2175 // Last 5 CHLOs will be buffered. Others will create connection right away.
2176 ParsedQuicVersion version =
2177 supported_versions[(conn_id - 1) % supported_versions.size()];
2178 if (conn_id <= kMaxNumSessionsToCreate) {
2179 EXPECT_CALL(*dispatcher_,
2180 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2181 QuicStringPiece(), version))
2182 .WillOnce(testing::Return(CreateSession(
2183 dispatcher_.get(), config_, TestConnectionId(conn_id),
2184 client_addr_, &mock_helper_, &mock_alarm_factory_,
2185 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2186 &session1_)));
2187 EXPECT_CALL(
2188 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2189 ProcessUdpPacket(_, _, _))
2190 .WillRepeatedly(WithArg<2>(
2191 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2192 ValidatePacket(TestConnectionId(conn_id), packet);
2193 })));
2194 }
2195 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, version,
2196 SerializeFullCHLO(), CONNECTION_ID_PRESENT,
2197 PACKET_4BYTE_PACKET_NUMBER, 1);
2198 }
2199
2200 // Process buffered CHLOs. Verify the version is correct.
2201 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2202 conn_id <= last_connection_id; ++conn_id) {
2203 ParsedQuicVersion version =
2204 supported_versions[(conn_id - 1) % supported_versions.size()];
2205 EXPECT_CALL(*dispatcher_,
2206 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2207 QuicStringPiece(), version))
2208 .WillOnce(testing::Return(CreateSession(
2209 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2210 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2211 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2212 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2213 ProcessUdpPacket(_, _, _))
2214 .WillRepeatedly(WithArg<2>(
2215 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2216 ValidatePacket(TestConnectionId(conn_id), packet);
2217 })));
2218 }
2219 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2220}
2221
2222// Test which exercises the async GetProof codepaths, especially in the context
2223// of stateless rejection.
2224class AsyncGetProofTest : public QuicDispatcherTest {
2225 public:
2226 AsyncGetProofTest()
2227 : QuicDispatcherTest(
2228 std::unique_ptr<FakeProofSource>(new FakeProofSource())),
2229 client_addr_(QuicIpAddress::Loopback4(), 1234),
2230 client_addr_2_(QuicIpAddress::Loopback4(), 1357),
2231 crypto_config_peer_(&crypto_config_),
2232 server_addr_(QuicIpAddress::Any4(), 5),
2233 signed_config_(new QuicSignedServerConfig) {
2234 SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
2235 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
2236 }
2237
2238 void SetUp() override {
2239 QuicDispatcherTest::SetUp();
2240
2241 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
2242 QuicTransportVersion version = AllSupportedTransportVersions().front();
2243 chlo_ = crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
2244 &crypto_config_);
2245 chlo_.SetVector(kCOPT, QuicTagVector{kSREJ});
2246 chlo_.SetStringPiece(kALPN, "HTTP/1");
2247 // Pass an inchoate CHLO.
2248 crypto_test_utils::GenerateFullCHLO(
2249 chlo_, &crypto_config_, server_addr_, client_addr_, version, clock_,
2250 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2251 &full_chlo_);
2252
2253 crypto_test_utils::GenerateFullCHLO(
2254 chlo_, &crypto_config_, server_addr_, client_addr_2_, version, clock_,
2255 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2256 &full_chlo_2_);
2257
2258 GetFakeProofSource()->Activate();
2259 }
2260
2261 FakeProofSource* GetFakeProofSource() const {
2262 return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
2263 }
2264
vasilvvc48c8712019-03-11 13:38:16 -07002265 std::string SerializeFullCHLO() {
2266 return std::string(full_chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002267 }
2268
vasilvvc48c8712019-03-11 13:38:16 -07002269 std::string SerializeFullCHLOForClient2() {
2270 return std::string(full_chlo_2_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002271 }
2272
vasilvvc48c8712019-03-11 13:38:16 -07002273 std::string SerializeCHLO() {
2274 return std::string(chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002275 }
2276
2277 // Sets up a session, and crypto stream based on the test parameters.
2278 QuicServerSessionBase* GetSession(QuicConnectionId connection_id,
2279 QuicSocketAddress client_address) {
2280 auto it = sessions_.find(connection_id);
2281 if (it != sessions_.end()) {
2282 return it->second.session;
2283 }
2284
2285 TestQuicSpdyServerSession* session;
2286 CreateSession(dispatcher_.get(), config_, connection_id, client_address,
2287 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2288 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session);
2289
2290 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream(
2291 new MockQuicCryptoServerStream(
2292 crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2293 session, session->stream_helper()));
2294 session->SetCryptoStream(crypto_stream.get());
2295 crypto_stream->SetPeerSupportsStatelessRejects(true);
2296 const bool ok =
2297 sessions_
2298 .insert(std::make_pair(
2299 connection_id, SessionInfo{session, std::move(crypto_stream)}))
2300 .second;
2301 CHECK(ok);
2302 return session;
2303 }
2304
2305 protected:
2306 const QuicSocketAddress client_addr_;
2307 const QuicSocketAddress client_addr_2_;
2308 CryptoHandshakeMessage chlo_;
2309
2310 private:
2311 QuicCryptoServerConfigPeer crypto_config_peer_;
2312 QuicSocketAddress server_addr_;
2313 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
2314 const QuicClock* clock_;
2315 CryptoHandshakeMessage full_chlo_; // CHLO for client_addr_
2316 CryptoHandshakeMessage full_chlo_2_; // CHLO for client_addr_2_
2317
2318 struct SessionInfo {
2319 TestQuicSpdyServerSession* session;
2320 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream;
2321 };
2322 std::map<QuicConnectionId, SessionInfo> sessions_;
2323};
2324
2325// Test a simple situation of connections which the StatelessRejector will
2326// accept.
2327TEST_F(AsyncGetProofTest, BasicAccept) {
2328 QuicConnectionId conn_id = TestConnectionId(1);
2329
2330 testing::MockFunction<void(int check_point)> check;
2331 {
2332 InSequence s;
2333
2334 EXPECT_CALL(check, Call(1));
2335 EXPECT_CALL(*dispatcher_,
2336 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2337 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2338 QuicStringPiece("HTTP/1"), _))
2339 .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
2340 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2341 GetSession(conn_id, client_addr_)->connection()),
2342 ProcessUdpPacket(_, _, _))
2343 .WillOnce(WithArg<2>(
2344 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2345 ValidatePacket(conn_id, packet);
2346 })));
2347
2348 EXPECT_CALL(check, Call(2));
2349 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2350 GetSession(conn_id, client_addr_)->connection()),
2351 ProcessUdpPacket(_, _, _))
2352 .WillOnce(WithArg<2>(
2353 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2354 ValidatePacket(conn_id, packet);
2355 })));
2356 }
2357
2358 // Send a CHLO that the StatelessRejector will accept.
2359 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2360 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2361
2362 check.Call(1);
2363 // Complete the ProofSource::GetProof call and verify that a session is
2364 // created.
2365 GetFakeProofSource()->InvokePendingCallback(0);
2366 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2367
2368 check.Call(2);
2369 // Verify that a data packet gets processed immediately.
2370 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2371}
2372
2373TEST_F(AsyncGetProofTest, RestorePacketContext) {
2374 QuicConnectionId conn_id_1 = TestConnectionId(1);
2375 QuicConnectionId conn_id_2 = TestConnectionId(2);
2376
2377 testing::MockFunction<void(int check_point)> check;
2378 {
2379 InSequence s;
2380 EXPECT_CALL(check, Call(1));
2381 EXPECT_CALL(*dispatcher_,
2382 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2383
2384 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2385 QuicStringPiece("HTTP/1"), _))
2386 .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
2387 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2388 GetSession(conn_id_1, client_addr_)->connection()),
2389 ProcessUdpPacket(_, _, _))
2390 .WillRepeatedly(WithArg<2>(
2391 Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
2392 ValidatePacket(conn_id_1, packet);
2393 })));
2394
2395 EXPECT_CALL(check, Call(2));
2396
2397 EXPECT_CALL(*dispatcher_,
2398 ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
2399 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_2_,
2400 QuicStringPiece("HTTP/1"), _))
2401 .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_2_)));
2402 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2403 GetSession(conn_id_2, client_addr_2_)->connection()),
2404 ProcessUdpPacket(_, _, _))
2405 .WillOnce(WithArg<2>(
2406 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2407 ValidatePacket(conn_id_2, packet);
2408 })));
2409 }
2410
2411 // Send a CHLO that the StatelessRejector will accept.
2412 dispatcher_->custom_packet_context_ = "connection 1";
2413 ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
2414 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2415
2416 // Send another CHLO that the StatelessRejector will accept.
2417 dispatcher_->custom_packet_context_ = "connection 2";
2418 ProcessPacket(client_addr_2_, conn_id_2, true, SerializeFullCHLOForClient2());
2419 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2420
2421 // Complete the first ProofSource::GetProof call and verify that a session is
2422 // created.
2423 check.Call(1);
2424
2425 EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
2426 EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
2427 EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
2428
2429 // Runs the async proof callback for conn_id_1 from client_addr_.
2430 GetFakeProofSource()->InvokePendingCallback(0);
2431
2432 EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
2433 EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
2434 EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
2435
2436 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2437
2438 // Complete the second ProofSource::GetProof call and verify that a session is
2439 // created.
2440 check.Call(2);
2441
2442 EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
2443 EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
2444 EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
2445
2446 // Runs the async proof callback for conn_id_2 from client_addr_2_.
2447 GetFakeProofSource()->InvokePendingCallback(0);
2448
2449 EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
2450 EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
2451 EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
2452
2453 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2454}
2455
2456// Test a simple situation of connections which the StatelessRejector will
2457// reject.
2458TEST_F(AsyncGetProofTest, BasicReject) {
2459 CreateTimeWaitListManager();
2460
2461 QuicConnectionId conn_id = TestConnectionId(1);
2462
2463 testing::MockFunction<void(int check_point)> check;
2464 {
2465 InSequence s;
2466 EXPECT_CALL(check, Call(1));
2467 EXPECT_CALL(*time_wait_list_manager_,
2468 AddConnectionIdToTimeWait(conn_id, _, _, _, _));
2469 EXPECT_CALL(*time_wait_list_manager_,
2470 ProcessPacket(_, client_addr_, conn_id, _, _));
2471
2472 EXPECT_CALL(check, Call(2));
2473 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2474 QuicStringPiece("hq"), _))
2475 .Times(0);
2476 EXPECT_CALL(*time_wait_list_manager_,
2477 ProcessPacket(_, client_addr_, conn_id, _, _));
2478 }
2479
2480 // Send a CHLO that the StatelessRejector will reject.
2481 ProcessPacket(client_addr_, conn_id, true, SerializeCHLO());
2482 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2483
2484 // Complete the ProofSource::GetProof call and verify that the connection and
2485 // packet are processed by the time wait list manager.
2486 check.Call(1);
2487 GetFakeProofSource()->InvokePendingCallback(0);
2488 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2489
2490 // Verify that a data packet is passed to the time wait list manager.
2491 check.Call(2);
2492 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2493}
2494
2495// Test a situation with multiple interleaved connections which the
2496// StatelessRejector will accept.
2497TEST_F(AsyncGetProofTest, MultipleAccept) {
2498 QuicConnectionId conn_id_1 = TestConnectionId(1);
2499 QuicConnectionId conn_id_2 = TestConnectionId(2);
2500 QuicBufferedPacketStore* store =
2501 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2502
2503 testing::MockFunction<void(int check_point)> check;
2504 {
2505 InSequence s;
2506 EXPECT_CALL(check, Call(1));
2507 EXPECT_CALL(*dispatcher_,
2508 ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
2509 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_,
2510 QuicStringPiece("HTTP/1"), _))
2511 .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_)));
2512 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2513 GetSession(conn_id_2, client_addr_)->connection()),
2514 ProcessUdpPacket(_, _, _))
2515 .WillOnce(WithArg<2>(
2516 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2517 ValidatePacket(conn_id_2, packet);
2518 })));
2519
2520 EXPECT_CALL(check, Call(2));
2521 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2522 GetSession(conn_id_2, client_addr_)->connection()),
2523 ProcessUdpPacket(_, _, _))
2524 .WillOnce(WithArg<2>(
2525 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2526 ValidatePacket(conn_id_2, packet);
2527 })));
2528
2529 EXPECT_CALL(check, Call(3));
2530 EXPECT_CALL(*dispatcher_,
2531 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2532
2533 EXPECT_CALL(check, Call(4));
2534 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2535 QuicStringPiece("HTTP/1"), _))
2536 .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
2537 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2538 GetSession(conn_id_1, client_addr_)->connection()),
2539 ProcessUdpPacket(_, _, _))
2540 .WillRepeatedly(WithArg<2>(
2541 Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
2542 ValidatePacket(conn_id_1, packet);
2543 })));
2544 }
2545
2546 // Send a CHLO that the StatelessRejector will accept.
2547 ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
2548 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2549
2550 // Send another CHLO that the StatelessRejector will accept.
2551 ProcessPacket(client_addr_, conn_id_2, true, SerializeFullCHLO());
2552 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2553
2554 // Complete the second ProofSource::GetProof call and verify that a session is
2555 // created.
2556 check.Call(1);
2557 GetFakeProofSource()->InvokePendingCallback(1);
2558 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2559
2560 // Verify that a data packet on that connection gets processed immediately.
2561 check.Call(2);
2562 ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
2563
2564 // Verify that a data packet on the other connection does not get processed
2565 // yet.
2566 check.Call(3);
2567 ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
2568 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2569 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2570
2571 // Complete the first ProofSource::GetProof call and verify that a session is
2572 // created and the buffered packet is processed.
2573 check.Call(4);
2574 GetFakeProofSource()->InvokePendingCallback(0);
2575 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2576}
2577
2578// Test a situation with multiple interleaved connections which the
2579// StatelessRejector will reject.
2580TEST_F(AsyncGetProofTest, MultipleReject) {
2581 CreateTimeWaitListManager();
2582
2583 QuicConnectionId conn_id_1 = TestConnectionId(1);
2584 QuicConnectionId conn_id_2 = TestConnectionId(2);
2585 QuicBufferedPacketStore* store =
2586 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2587
2588 testing::MockFunction<void(int check_point)> check;
2589 {
2590 InSequence s;
2591
2592 EXPECT_CALL(check, Call(1));
2593 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_, _, _))
2594 .Times(0);
2595 EXPECT_CALL(*time_wait_list_manager_,
2596 AddConnectionIdToTimeWait(conn_id_2, _, _, _, _));
2597 EXPECT_CALL(*time_wait_list_manager_,
2598 ProcessPacket(_, client_addr_, conn_id_2, _, _));
2599
2600 EXPECT_CALL(check, Call(2));
2601 EXPECT_CALL(*time_wait_list_manager_,
2602 ProcessPacket(_, client_addr_, conn_id_2, _, _));
2603
2604 EXPECT_CALL(check, Call(3));
2605 EXPECT_CALL(*dispatcher_,
2606 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2607
2608 EXPECT_CALL(check, Call(4));
2609 EXPECT_CALL(*time_wait_list_manager_,
2610 AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
2611 EXPECT_CALL(*time_wait_list_manager_,
2612 ProcessPacket(_, client_addr_, conn_id_1, _, _));
2613 }
2614
2615 // Send a CHLO that the StatelessRejector will reject.
2616 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2617 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2618
2619 // Send another CHLO that the StatelessRejector will reject.
2620 ProcessPacket(client_addr_, conn_id_2, true, SerializeCHLO());
2621 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2622
2623 // Complete the second ProofSource::GetProof call and verify that the
2624 // connection and packet are processed by the time wait manager.
2625 check.Call(1);
2626 GetFakeProofSource()->InvokePendingCallback(1);
2627 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2628
2629 // Verify that a data packet on that connection gets processed immediately by
2630 // the time wait manager.
2631 check.Call(2);
2632 ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
2633
2634 // Verify that a data packet on the first connection gets buffered.
2635 check.Call(3);
2636 ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
2637 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2638 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2639
2640 // Complete the first ProofSource::GetProof call and verify that the CHLO is
2641 // processed by the time wait manager and the remaining packets are discarded.
2642 check.Call(4);
2643 GetFakeProofSource()->InvokePendingCallback(0);
2644 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2645 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2646 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2647}
2648
2649// Test a situation with multiple identical CHLOs which the StatelessRejector
2650// will reject.
2651TEST_F(AsyncGetProofTest, MultipleIdenticalReject) {
2652 CreateTimeWaitListManager();
2653
2654 QuicConnectionId conn_id_1 = TestConnectionId(1);
2655 QuicBufferedPacketStore* store =
2656 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2657
2658 testing::MockFunction<void(int check_point)> check;
2659 {
2660 InSequence s;
2661 EXPECT_CALL(check, Call(1));
2662 EXPECT_CALL(*dispatcher_,
2663 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2664
2665 EXPECT_CALL(check, Call(2));
2666 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2667 QuicStringPiece(), _))
2668 .Times(0);
2669 EXPECT_CALL(*time_wait_list_manager_,
2670 AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
2671 EXPECT_CALL(*time_wait_list_manager_,
2672 ProcessPacket(_, client_addr_, conn_id_1, _, _));
2673 }
2674
2675 // Send a CHLO that the StatelessRejector will reject.
2676 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2677 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2678 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2679
2680 // Send an identical CHLO which should get buffered.
2681 check.Call(1);
2682 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2683 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2684 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2685
2686 // Complete the ProofSource::GetProof call and verify that the CHLO is
2687 // rejected and the copy is discarded.
2688 check.Call(2);
2689 GetFakeProofSource()->InvokePendingCallback(0);
2690 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2691 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2692}
2693
2694// Test dispatcher behavior when packets time out of the buffer while CHLO
2695// validation is still pending.
2696TEST_F(AsyncGetProofTest, BufferTimeout) {
2697 CreateTimeWaitListManager();
2698
2699 QuicConnectionId conn_id = TestConnectionId(1);
2700 QuicBufferedPacketStore* store =
2701 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2702 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2703
2704 testing::MockFunction<void(int check_point)> check;
2705 {
2706 InSequence s;
2707 EXPECT_CALL(check, Call(1));
2708 EXPECT_CALL(*dispatcher_,
2709 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2710
2711 EXPECT_CALL(check, Call(2));
2712 EXPECT_CALL(*time_wait_list_manager_,
2713 ProcessPacket(_, client_addr_, conn_id, _, _));
2714 EXPECT_CALL(*dispatcher_,
2715 CreateQuicSession(conn_id, client_addr_, QuicStringPiece(), _))
2716 .Times(0);
2717 }
2718
2719 // Send a CHLO that the StatelessRejector will accept.
2720 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2721 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2722 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2723
2724 // Send a data packet that will get buffered
2725 check.Call(1);
2726 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2727 EXPECT_TRUE(store->HasBufferedPackets(conn_id));
2728
2729 // Pretend that enough time has gone by for the packets to get expired out of
2730 // the buffer
2731 mock_helper_.AdvanceTime(
2732 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2733 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
2734 store->OnExpirationTimeout();
2735 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2736 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2737
2738 // Now allow the CHLO validation to complete, and verify that no connection
2739 // gets created.
2740 check.Call(2);
2741 GetFakeProofSource()->InvokePendingCallback(0);
2742 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2743 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2744 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2745}
2746
2747// Test behavior when packets time out of the buffer *and* the connection times
2748// out of the time wait manager while CHLO validation is still pending. This
2749// *should* be impossible, but anything can happen with timing conditions.
2750TEST_F(AsyncGetProofTest, TimeWaitTimeout) {
2751 QuicConnectionId conn_id = TestConnectionId(1);
2752 QuicBufferedPacketStore* store =
2753 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2754 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2755 CreateTimeWaitListManager();
2756 QuicTimeWaitListManagerPeer::set_clock(time_wait_list_manager_,
2757 mock_helper_.GetClock());
2758
2759 testing::MockFunction<void(int check_point)> check;
2760 {
2761 InSequence s;
2762 EXPECT_CALL(check, Call(1));
2763 EXPECT_CALL(*dispatcher_,
2764 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2765
2766 EXPECT_CALL(check, Call(2));
2767 EXPECT_CALL(*dispatcher_,
2768 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2769 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2770 QuicStringPiece("HTTP/1"), _))
2771 .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
2772 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2773 GetSession(conn_id, client_addr_)->connection()),
2774 ProcessUdpPacket(_, _, _))
2775 .WillOnce(WithArg<2>(
2776 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2777 ValidatePacket(conn_id, packet);
2778 })));
2779 }
2780
2781 // Send a CHLO that the StatelessRejector will accept.
2782 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2783 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2784 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2785
2786 // Send a data packet that will get buffered
2787 check.Call(1);
2788 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2789 EXPECT_TRUE(store->HasBufferedPackets(conn_id));
2790
2791 // Pretend that enough time has gone by for the packets to get expired out of
2792 // the buffer
2793 mock_helper_.AdvanceTime(
2794 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2795 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
2796 store->OnExpirationTimeout();
2797 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2798 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2799
2800 // Pretend that enough time has gone by for the connection ID to be removed
2801 // from the time wait manager
2802 mock_helper_.AdvanceTime(
2803 QuicTimeWaitListManagerPeer::time_wait_period(time_wait_list_manager_));
2804 QuicTimeWaitListManagerPeer::expiration_alarm(time_wait_list_manager_)
2805 ->Cancel();
2806 time_wait_list_manager_->CleanUpOldConnectionIds();
2807 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2808
2809 // Now allow the CHLO validation to complete. Expect that a connection is
2810 // indeed created, since QUIC has forgotten that this connection ever existed.
2811 // This is a miniscule corner case which should never happen in the wild, so
2812 // really we are just verifying that the dispatcher does not explode in this
2813 // situation.
2814 check.Call(2);
2815 GetFakeProofSource()->InvokePendingCallback(0);
2816 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2817 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2818 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2819}
2820
2821// Regression test for
2822// https://bugs.chromium.org/p/chromium/issues/detail?id=748289
2823TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
2824 // This test mimics the scenario that dispatcher's framer can have different
2825 // version when async proof returns.
2826 // When dispatcher sends SREJ, the SREJ frame can be serialized in
2827 // different endianness which causes the client to close the connection
2828 // because of QUIC_INVALID_STREAM_DATA.
2829
2830 SetQuicReloadableFlag(quic_disable_version_39, false);
2831 SetQuicReloadableFlag(quic_enable_version_43, true);
2832 ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
2833 chlo_.SetVersion(kVER, chlo_version);
2834 // Send a CHLO with v43. Dispatcher framer's version is set to v43.
2835 ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
2836 SerializeCHLO(), CONNECTION_ID_PRESENT,
2837 PACKET_4BYTE_PACKET_NUMBER, 1);
2838
2839 // Send another CHLO with v39. Dispatcher framer's version is set to v39.
2840 chlo_version.transport_version = QUIC_VERSION_39;
2841 chlo_.SetVersion(kVER, chlo_version);
2842 // Invalidate the cached serialized form.
2843 chlo_.MarkDirty();
2844 ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
2845 SerializeCHLO(), CONNECTION_ID_PRESENT,
2846 PACKET_4BYTE_PACKET_NUMBER, 1);
2847 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2848
2849 // Complete the ProofSource::GetProof call for v43. This would cause the
2850 // version mismatch between the CHLO packet and the dispatcher.
2851 GetFakeProofSource()->InvokePendingCallback(0);
2852 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2853}
2854
2855// Regression test for b/116200989.
2856TEST_F(AsyncGetProofTest, DispatcherHasWrongLastPacketIsIetfQuic) {
2857 // Process a packet of v44.
2858 ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44);
2859 chlo_.SetVersion(kVER, chlo_version);
2860 ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
2861 SerializeCHLO(), CONNECTION_ID_PRESENT,
2862 PACKET_4BYTE_PACKET_NUMBER, 1);
2863
2864 // Process another packet of v43.
2865 chlo_version.transport_version = QUIC_VERSION_43;
2866 chlo_.SetVersion(kVER, chlo_version);
2867 // Invalidate the cached serialized form.
2868 chlo_.MarkDirty();
2869 ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
2870 SerializeCHLO(), CONNECTION_ID_PRESENT,
2871 PACKET_4BYTE_PACKET_NUMBER, 1);
2872 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2873
2874 // Complete the ProofSource::GetProof call for v44.
2875 GetFakeProofSource()->InvokePendingCallback(0);
2876 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2877
2878 // Complete the ProofSource::GetProof call for v43.
2879 GetFakeProofSource()->InvokePendingCallback(0);
2880 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2881}
2882
2883} // namespace
2884} // namespace test
2885} // namespace quic