blob: 16d25847ce0156a69e7cf62f433866a5ddb30d9f [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() {
wub49855982019-05-01 14:16:26 -0700198 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 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 }
wub49855982019-05-01 14:16:26 -0700383 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500384 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) {
nharper55fa6132019-05-07 19:37:21 -0700818 if (CurrentSupportedVersions().front().HasHeaderProtection()) {
819 // When header protection is in use, we don't put packets in the time wait
820 // list manager based on packet number.
821 return;
822 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500823 CreateTimeWaitListManager();
824 SetQuicRestartFlag(quic_enable_accept_random_ipn, false);
825 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
826 QuicConnectionId connection_id = TestConnectionId(1);
827
828 // Dispatcher forwards this packet for this connection_id to the time wait
829 // list manager.
830 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
831 .Times(0);
832 EXPECT_CALL(*time_wait_list_manager_,
833 ProcessPacket(_, _, TestConnectionId(1), _, _))
834 .Times(1);
835 EXPECT_CALL(*time_wait_list_manager_,
836 ProcessPacket(_, _, TestConnectionId(2), _, _))
837 .Times(1);
838 EXPECT_CALL(*time_wait_list_manager_,
839 AddConnectionIdToTimeWait(_, _, _, _, _))
840 .Times(2);
841 // A packet whose packet number is one to large to be allowed to start a
842 // connection.
843 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
844 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
845 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
846 connection_id = TestConnectionId(2);
847 SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
848 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
849 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
850 MaxRandomInitialPacketNumber().ToUint64() +
851 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
852}
853
854TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
855 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
856 "Supported versions out of sync");
857 SetQuicReloadableFlag(quic_disable_version_39, false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858 SetQuicReloadableFlag(quic_enable_version_44, true);
859 SetQuicReloadableFlag(quic_enable_version_46, true);
860 SetQuicReloadableFlag(quic_enable_version_47, true);
861 SetQuicReloadableFlag(quic_enable_version_99, true);
862 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
863 uint64_t conn_id = 1;
864 QuicConnectionId connection_id = TestConnectionId(conn_id);
865
866 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
867 QuicStringPiece("hq"), _))
868 .Times(0);
869 ParsedQuicVersion version(
870 PROTOCOL_QUIC_CRYPTO,
871 static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1));
872 ProcessPacket(client_address, connection_id, true, version, SerializeCHLO(),
873 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
874 connection_id = TestConnectionId(++conn_id);
875 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
876 QuicStringPiece("hq"), _))
877 .WillOnce(testing::Return(CreateSession(
878 dispatcher_.get(), config_, connection_id, client_address,
879 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
880 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
881 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
882 ProcessUdpPacket(_, _, _))
883 .WillOnce(WithArg<2>(
884 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
885 ValidatePacket(connection_id, packet);
886 })));
887 EXPECT_CALL(*dispatcher_,
888 ShouldCreateOrBufferPacketForConnection(connection_id, _));
889 ProcessPacket(client_address, connection_id, true,
890 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
891 QuicVersionMin().transport_version),
892 SerializeCHLO(), CONNECTION_ID_PRESENT,
893 PACKET_4BYTE_PACKET_NUMBER, 1);
894 connection_id = TestConnectionId(++conn_id);
895 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
896 QuicStringPiece("hq"), _))
897 .WillOnce(testing::Return(CreateSession(
898 dispatcher_.get(), config_, connection_id, client_address,
899 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
900 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
901 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
902 ProcessUdpPacket(_, _, _))
903 .WillOnce(WithArg<2>(
904 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
905 ValidatePacket(connection_id, packet);
906 })));
907 EXPECT_CALL(*dispatcher_,
908 ShouldCreateOrBufferPacketForConnection(connection_id, _));
909 ProcessPacket(client_address, connection_id, true, QuicVersionMax(),
910 SerializeCHLO(), CONNECTION_ID_PRESENT,
911 PACKET_4BYTE_PACKET_NUMBER, 1);
912
913 // Turn off version 47.
914 SetQuicReloadableFlag(quic_enable_version_47, false);
915 connection_id = TestConnectionId(++conn_id);
916 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
917 QuicStringPiece("hq"), _))
918 .Times(0);
919 ProcessPacket(client_address, connection_id, true,
920 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
921 SerializeCHLO(), CONNECTION_ID_PRESENT,
922 PACKET_4BYTE_PACKET_NUMBER, 1);
923
924 // Turn on version 47.
925 SetQuicReloadableFlag(quic_enable_version_47, true);
926 connection_id = TestConnectionId(++conn_id);
927 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
928 QuicStringPiece("hq"), _))
929 .WillOnce(testing::Return(CreateSession(
930 dispatcher_.get(), config_, connection_id, client_address,
931 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
932 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
933 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
934 ProcessUdpPacket(_, _, _))
935 .WillOnce(WithArg<2>(
936 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
937 ValidatePacket(connection_id, packet);
938 })));
939 EXPECT_CALL(*dispatcher_,
940 ShouldCreateOrBufferPacketForConnection(connection_id, _));
941 ProcessPacket(client_address, connection_id, true,
942 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
943 SerializeCHLO(), CONNECTION_ID_PRESENT,
944 PACKET_4BYTE_PACKET_NUMBER, 1);
945
946 // Turn off version 46.
947 SetQuicReloadableFlag(quic_enable_version_46, false);
948 connection_id = TestConnectionId(++conn_id);
949 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
950 QuicStringPiece("hq"), _))
951 .Times(0);
952 ProcessPacket(client_address, connection_id, true,
953 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
954 SerializeCHLO(), CONNECTION_ID_PRESENT,
955 PACKET_4BYTE_PACKET_NUMBER, 1);
956
957 // Turn on version 46.
958 SetQuicReloadableFlag(quic_enable_version_46, true);
959 connection_id = TestConnectionId(++conn_id);
960 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
961 QuicStringPiece("hq"), _))
962 .WillOnce(testing::Return(CreateSession(
963 dispatcher_.get(), config_, connection_id, client_address,
964 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
965 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
966 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
967 ProcessUdpPacket(_, _, _))
968 .WillOnce(WithArg<2>(
969 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
970 ValidatePacket(connection_id, packet);
971 })));
972 EXPECT_CALL(*dispatcher_,
973 ShouldCreateOrBufferPacketForConnection(connection_id, _));
974 ProcessPacket(client_address, connection_id, true,
975 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
976 SerializeCHLO(), CONNECTION_ID_PRESENT,
977 PACKET_4BYTE_PACKET_NUMBER, 1);
978
979 // Turn off version 44.
980 SetQuicReloadableFlag(quic_enable_version_44, false);
981 connection_id = TestConnectionId(++conn_id);
982 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
983 QuicStringPiece("hq"), _))
984 .Times(0);
985 ProcessPacket(client_address, connection_id, true,
986 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44),
987 SerializeCHLO(), CONNECTION_ID_PRESENT,
988 PACKET_4BYTE_PACKET_NUMBER, 1);
989
990 // Turn on version 44.
991 SetQuicReloadableFlag(quic_enable_version_44, true);
992 connection_id = TestConnectionId(++conn_id);
993 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
994 QuicStringPiece("hq"), _))
995 .WillOnce(testing::Return(CreateSession(
996 dispatcher_.get(), config_, connection_id, client_address,
997 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
998 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
999 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1000 ProcessUdpPacket(_, _, _))
1001 .WillOnce(WithArg<2>(
1002 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1003 ValidatePacket(connection_id, packet);
1004 })));
1005 EXPECT_CALL(*dispatcher_,
1006 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1007 ProcessPacket(client_address, connection_id, true,
1008 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44),
1009 SerializeCHLO(), CONNECTION_ID_PRESENT,
1010 PACKET_4BYTE_PACKET_NUMBER, 1);
1011
QUICHE teama6ef0a62019-03-07 20:34:33 -05001012 // Turn off version 39.
1013 SetQuicReloadableFlag(quic_disable_version_39, true);
1014 connection_id = TestConnectionId(++conn_id);
1015 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1016 QuicStringPiece("hq"), _))
1017 .Times(0);
1018 ProcessPacket(client_address, connection_id, true,
1019 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1020 SerializeCHLO(), CONNECTION_ID_PRESENT,
1021 PACKET_4BYTE_PACKET_NUMBER, 1);
1022
1023 // Turn on version 39.
1024 SetQuicReloadableFlag(quic_disable_version_39, false);
1025 connection_id = TestConnectionId(++conn_id);
1026 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1027 QuicStringPiece("hq"), _))
1028 .WillOnce(testing::Return(CreateSession(
1029 dispatcher_.get(), config_, connection_id, client_address,
1030 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1031 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1032 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1033 ProcessUdpPacket(_, _, _))
1034 .WillOnce(WithArg<2>(
1035 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1036 ValidatePacket(connection_id, packet);
1037 })));
1038 EXPECT_CALL(*dispatcher_,
1039 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1040 ProcessPacket(client_address, connection_id, true,
1041 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1042 SerializeCHLO(), CONNECTION_ID_PRESENT,
1043 PACKET_4BYTE_PACKET_NUMBER, 1);
1044}
1045
1046// Enables mocking of the handshake-confirmation for stateless rejects.
1047class MockQuicCryptoServerStream : public QuicCryptoServerStream {
1048 public:
1049 MockQuicCryptoServerStream(const QuicCryptoServerConfig& crypto_config,
1050 QuicCompressedCertsCache* compressed_certs_cache,
1051 QuicServerSessionBase* session,
1052 QuicCryptoServerStream::Helper* helper)
1053 : QuicCryptoServerStream(
1054 &crypto_config,
1055 compressed_certs_cache,
1056 GetQuicReloadableFlag(enable_quic_stateless_reject_support),
1057 session,
1058 helper),
1059 handshake_confirmed_(false) {}
1060 MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
1061 MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
1062 delete;
1063
1064 void set_handshake_confirmed_for_testing(bool handshake_confirmed) {
1065 handshake_confirmed_ = handshake_confirmed;
1066 }
1067
1068 bool handshake_confirmed() const override { return handshake_confirmed_; }
1069
1070 private:
1071 bool handshake_confirmed_;
1072};
1073
1074struct StatelessRejectTestParams {
1075 StatelessRejectTestParams(bool enable_stateless_rejects_via_flag,
1076 bool client_supports_statelesss_rejects,
1077 bool crypto_handshake_successful)
1078 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
1079 client_supports_statelesss_rejects(client_supports_statelesss_rejects),
1080 crypto_handshake_successful(crypto_handshake_successful) {}
1081
1082 friend std::ostream& operator<<(std::ostream& os,
1083 const StatelessRejectTestParams& p) {
1084 os << "{ enable_stateless_rejects_via_flag: "
1085 << p.enable_stateless_rejects_via_flag << std::endl;
1086 os << " client_supports_statelesss_rejects: "
1087 << p.client_supports_statelesss_rejects << std::endl;
1088 os << " crypto_handshake_successful: " << p.crypto_handshake_successful
1089 << " }";
1090 return os;
1091 }
1092
1093 // This only enables the stateless reject feature via the feature-flag.
1094 // This should be a no-op if the peer does not support them.
1095 bool enable_stateless_rejects_via_flag;
1096 // Whether or not the client supports stateless rejects.
1097 bool client_supports_statelesss_rejects;
1098 // Should the initial crypto handshake succeed or not.
1099 bool crypto_handshake_successful;
1100};
1101
1102// Constructs various test permutations for stateless rejects.
1103std::vector<StatelessRejectTestParams> GetStatelessRejectTestParams() {
1104 std::vector<StatelessRejectTestParams> params;
1105 for (bool enable_stateless_rejects_via_flag : {true, false}) {
1106 for (bool client_supports_statelesss_rejects : {true, false}) {
1107 for (bool crypto_handshake_successful : {true, false}) {
1108 params.push_back(StatelessRejectTestParams(
1109 enable_stateless_rejects_via_flag,
1110 client_supports_statelesss_rejects, crypto_handshake_successful));
1111 }
1112 }
1113 }
1114 return params;
1115}
1116
1117class QuicDispatcherStatelessRejectTest
1118 : public QuicDispatcherTest,
1119 public testing::WithParamInterface<StatelessRejectTestParams> {
1120 public:
1121 QuicDispatcherStatelessRejectTest()
1122 : QuicDispatcherTest(), crypto_stream1_(nullptr) {}
1123
1124 ~QuicDispatcherStatelessRejectTest() override {
1125 if (crypto_stream1_) {
1126 delete crypto_stream1_;
1127 }
1128 }
1129
1130 // This test setup assumes that all testing will be done using
1131 // crypto_stream1_.
1132 void SetUp() override {
1133 QuicDispatcherTest::SetUp();
1134 SetQuicReloadableFlag(enable_quic_stateless_reject_support,
1135 GetParam().enable_stateless_rejects_via_flag);
1136 }
1137
1138 // Returns true or false, depending on whether the server will emit
1139 // a stateless reject, depending upon the parameters of the test.
1140 bool ExpectStatelessReject() {
1141 return GetParam().enable_stateless_rejects_via_flag &&
1142 !GetParam().crypto_handshake_successful &&
1143 GetParam().client_supports_statelesss_rejects;
1144 }
1145
1146 // Sets up dispatcher_, session1_, and crypto_stream1_ based on
1147 // the test parameters.
1148 QuicServerSessionBase* CreateSessionBasedOnTestParams(
1149 QuicConnectionId connection_id,
1150 const QuicSocketAddress& client_address) {
1151 CreateSession(dispatcher_.get(), config_, connection_id, client_address,
1152 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1153 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_);
1154
1155 crypto_stream1_ = new MockQuicCryptoServerStream(
1156 crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1157 session1_, session1_->stream_helper());
1158 session1_->SetCryptoStream(crypto_stream1_);
1159 crypto_stream1_->set_handshake_confirmed_for_testing(
1160 GetParam().crypto_handshake_successful);
1161 crypto_stream1_->SetPeerSupportsStatelessRejects(
1162 GetParam().client_supports_statelesss_rejects);
1163 return session1_;
1164 }
1165
1166 MockQuicCryptoServerStream* crypto_stream1_;
1167};
1168
1169// Parameterized test for stateless rejects. Should test all
1170// combinations of enabling/disabling, reject/no-reject for stateless
1171// rejects.
1172INSTANTIATE_TEST_SUITE_P(QuicDispatcherStatelessRejectTests,
1173 QuicDispatcherStatelessRejectTest,
1174 ::testing::ValuesIn(GetStatelessRejectTestParams()));
1175
1176TEST_P(QuicDispatcherStatelessRejectTest, ParameterizedBasicTest) {
1177 CreateTimeWaitListManager();
1178
1179 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1180 QuicConnectionId connection_id = TestConnectionId(1);
1181 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1182 QuicStringPiece("hq"), _))
1183 .WillOnce(testing::Return(
1184 CreateSessionBasedOnTestParams(connection_id, client_address)));
1185 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1186 ProcessUdpPacket(_, _, _))
1187 .WillOnce(WithArg<2>(
1188 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1189 ValidatePacket(connection_id, packet);
1190 })));
1191 EXPECT_CALL(*dispatcher_,
1192 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1193 .Times(1);
1194
1195 // Process the first packet for the connection.
1196 ProcessPacket(client_address, connection_id, true, SerializeCHLO());
1197 if (ExpectStatelessReject()) {
1198 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1199 CloseConnection(QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, _, _));
1200 // If this is a stateless reject, the crypto stream will close the
1201 // connection.
1202 session1_->connection()->CloseConnection(
1203 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
1204 ConnectionCloseBehavior::SILENT_CLOSE);
1205 }
1206
1207 // Send a second packet and check the results. If this is a stateless reject,
1208 // the existing connection_id will go on the time-wait list.
1209 EXPECT_EQ(ExpectStatelessReject(),
1210 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1211 if (ExpectStatelessReject()) {
1212 // The second packet will be processed on the time-wait list.
1213 EXPECT_CALL(*time_wait_list_manager_,
1214 ProcessPacket(_, _, connection_id, _, _))
1215 .Times(1);
1216 } else {
1217 // The second packet will trigger a packet-validation
1218 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1219 ProcessUdpPacket(_, _, _))
1220 .Times(1)
1221 .WillOnce(WithArg<2>(
1222 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1223 ValidatePacket(connection_id, packet);
1224 })));
1225 }
1226 ProcessPacket(client_address, connection_id, true, "data");
1227}
1228
1229TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
1230 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
1231 CreateTimeWaitListManager();
1232
1233 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1234 QuicConnectionId connection_id = TestConnectionId(1);
1235 if (GetParam().enable_stateless_rejects_via_flag) {
1236 EXPECT_CALL(*dispatcher_,
1237 CreateQuicSession(connection_id, client_address, _, _))
1238 .Times(0);
1239 } else {
1240 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1241 QuicStringPiece("h2"), _))
1242 .WillOnce(testing::Return(
1243 CreateSessionBasedOnTestParams(connection_id, client_address)));
1244 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1245 ProcessUdpPacket(_, _, _))
1246 .WillOnce(WithArg<2>(
1247 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1248 ValidatePacket(connection_id, packet);
1249 })));
1250 }
1251
1252 QUIC_LOG(INFO) << "ExpectStatelessReject: " << ExpectStatelessReject();
1253 QUIC_LOG(INFO) << "Params: " << GetParam();
1254 // Process the first packet for the connection.
1255 CryptoHandshakeMessage client_hello =
1256 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
1257 {"KEXS", "C255"},
1258 {"COPT", "SREJ"},
1259 {"NONC", "1234567890123456789012"},
1260 {"ALPN", "h2"},
1261 {"VER\0", "Q025"}},
1262 kClientHelloMinimumSize);
1263
1264 if (GetParam().enable_stateless_rejects_via_flag) {
1265 EXPECT_CALL(*time_wait_list_manager_,
1266 ProcessPacket(_, _, connection_id, _, _))
1267 .Times(1);
1268 } else {
1269 EXPECT_CALL(*dispatcher_,
1270 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1271 .Times(1);
1272 }
1273 ProcessPacket(client_address, connection_id, true,
vasilvvc48c8712019-03-11 13:38:16 -07001274 std::string(client_hello.GetSerialized().AsStringPiece()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001275
1276 if (GetParam().enable_stateless_rejects_via_flag) {
1277 EXPECT_EQ(true,
1278 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1279 }
1280}
1281
1282TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
1283 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
1284 CreateTimeWaitListManager();
1285
1286 const QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1287 const QuicConnectionId connection_id = TestConnectionId(1);
1288
1289 EXPECT_CALL(*dispatcher_,
1290 ShouldCreateOrBufferPacketForConnection(connection_id, _))
1291 .Times(1);
1292 ProcessPacket(client_address, connection_id, true, "NOT DATA FOR A CHLO");
1293
1294 // Process the first packet for the connection.
1295 CryptoHandshakeMessage client_hello =
1296 crypto_test_utils::CreateCHLO({{"AEAD", "AESG"},
1297 {"KEXS", "C255"},
1298 {"NONC", "1234567890123456789012"},
1299 {"ALPN", "h3"},
1300 {"VER\0", "Q025"}},
1301 kClientHelloMinimumSize);
1302
1303 // If stateless rejects are enabled then a connection will be created now
1304 // and the buffered packet will be processed
1305 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1306 QuicStringPiece("h3"), _))
1307 .WillOnce(testing::Return(
1308 CreateSessionBasedOnTestParams(connection_id, client_address)));
1309 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1310 ProcessUdpPacket(_, client_address, _))
1311 .WillOnce(WithArg<2>(
1312 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1313 ValidatePacket(connection_id, packet);
1314 })));
1315 // Expect both packets to be passed to ProcessUdpPacket(). And one of them
1316 // is already expected in CreateSessionBasedOnTestParams().
1317 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1318 ProcessUdpPacket(_, client_address, _))
1319 .WillOnce(WithArg<2>(
1320 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1321 ValidatePacket(connection_id, packet);
1322 })))
1323 .RetiresOnSaturation();
1324 ProcessPacket(client_address, connection_id, true,
vasilvvc48c8712019-03-11 13:38:16 -07001325 std::string(client_hello.GetSerialized().AsStringPiece()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001326 EXPECT_FALSE(
1327 time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
1328}
1329
1330// Verify the stopgap test: Packets with truncated connection IDs should be
1331// dropped.
1332class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
1333
1334// Packets with truncated connection IDs should be dropped.
1335TEST_F(QuicDispatcherTestStrayPacketConnectionId,
1336 StrayPacketTruncatedConnectionId) {
1337 CreateTimeWaitListManager();
1338
1339 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1340 QuicConnectionId connection_id = TestConnectionId(1);
1341 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
1342 .Times(0);
QUICHE team963d57e2019-03-21 10:58:47 -07001343 if (CurrentSupportedVersions()[0].transport_version > QUIC_VERSION_43 &&
1344 !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
1345 CurrentSupportedVersions()[0].transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001346 // This IETF packet has invalid connection ID length.
1347 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1348 .Times(0);
1349 EXPECT_CALL(*time_wait_list_manager_,
1350 AddConnectionIdToTimeWait(_, _, _, _, _))
1351 .Times(0);
1352 } else {
QUICHE team8e2e4532019-03-14 14:37:56 -07001353 // This is either:
1354 // - a GQUIC packet considered as IETF QUIC packet with short header
1355 // with unacceptable packet number or
1356 // - an IETF QUIC packet with bad connection ID length which is rejected.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001357 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1358 .Times(1);
1359 EXPECT_CALL(*time_wait_list_manager_,
1360 AddConnectionIdToTimeWait(_, _, _, _, _))
1361 .Times(1);
1362 }
1363 ProcessPacket(client_address, connection_id, true, "data",
1364 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1365}
1366
1367class BlockingWriter : public QuicPacketWriterWrapper {
1368 public:
1369 BlockingWriter() : write_blocked_(false) {}
1370
1371 bool IsWriteBlocked() const override { return write_blocked_; }
1372 void SetWritable() override { write_blocked_ = false; }
1373
1374 WriteResult WritePacket(const char* buffer,
1375 size_t buf_len,
1376 const QuicIpAddress& self_client_address,
1377 const QuicSocketAddress& peer_client_address,
1378 PerPacketOptions* options) override {
1379 // It would be quite possible to actually implement this method here with
1380 // the fake blocked status, but it would be significantly more work in
1381 // Chromium, and since it's not called anyway, don't bother.
1382 QUIC_LOG(DFATAL) << "Not supported";
1383 return WriteResult();
1384 }
1385
1386 bool write_blocked_;
1387};
1388
1389class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
1390 public:
1391 void SetUp() override {
1392 QuicDispatcherTest::SetUp();
1393 writer_ = new BlockingWriter;
1394 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1395
1396 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1397
1398 EXPECT_CALL(*dispatcher_,
1399 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1400 .WillOnce(testing::Return(CreateSession(
1401 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1402 &helper_, &alarm_factory_, &crypto_config_,
1403 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1404 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1405 ProcessUdpPacket(_, _, _))
1406 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1407 ValidatePacket(TestConnectionId(1), packet);
1408 })));
1409 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1410 TestConnectionId(1), _));
1411 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
1412
1413 EXPECT_CALL(*dispatcher_,
1414 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1415 .WillOnce(testing::Return(CreateSession(
1416 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1417 &helper_, &alarm_factory_, &crypto_config_,
1418 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
1419 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1420 ProcessUdpPacket(_, _, _))
1421 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1422 ValidatePacket(TestConnectionId(2), packet);
1423 })));
1424 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1425 TestConnectionId(2), _));
1426 ProcessPacket(client_address, TestConnectionId(2), true, SerializeCHLO());
1427
1428 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1429 }
1430
1431 void TearDown() override {
1432 if (connection1() != nullptr) {
1433 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1434 }
1435
1436 if (connection2() != nullptr) {
1437 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1438 }
1439 dispatcher_->Shutdown();
1440 }
1441
1442 // Set the dispatcher's writer to be blocked. By default, all connections use
1443 // the same writer as the dispatcher in this test.
1444 void SetBlocked() {
1445 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1446 writer_->write_blocked_ = true;
1447 }
1448
1449 // Simulate what happens when connection1 gets blocked when writing.
1450 void BlockConnection1() {
1451 Connection1Writer()->write_blocked_ = true;
1452 dispatcher_->OnWriteBlocked(connection1());
1453 }
1454
1455 BlockingWriter* Connection1Writer() {
1456 return static_cast<BlockingWriter*>(connection1()->writer());
1457 }
1458
1459 // Simulate what happens when connection2 gets blocked when writing.
1460 void BlockConnection2() {
1461 Connection2Writer()->write_blocked_ = true;
1462 dispatcher_->OnWriteBlocked(connection2());
1463 }
1464
1465 BlockingWriter* Connection2Writer() {
1466 return static_cast<BlockingWriter*>(connection2()->writer());
1467 }
1468
1469 protected:
1470 MockQuicConnectionHelper helper_;
1471 MockAlarmFactory alarm_factory_;
1472 BlockingWriter* writer_;
1473 QuicDispatcher::WriteBlockedList* blocked_list_;
1474};
1475
1476TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
1477 // No OnCanWrite calls because no connections are blocked.
1478 dispatcher_->OnCanWrite();
1479
1480 // Register connection 1 for events, and make sure it's notified.
1481 SetBlocked();
1482 dispatcher_->OnWriteBlocked(connection1());
1483 EXPECT_CALL(*connection1(), OnCanWrite());
1484 dispatcher_->OnCanWrite();
1485
1486 // It should get only one notification.
1487 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1488 dispatcher_->OnCanWrite();
1489 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1490}
1491
1492TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
1493 // Make sure we handle events in order.
1494 InSequence s;
1495 SetBlocked();
1496 dispatcher_->OnWriteBlocked(connection1());
1497 dispatcher_->OnWriteBlocked(connection2());
1498 EXPECT_CALL(*connection1(), OnCanWrite());
1499 EXPECT_CALL(*connection2(), OnCanWrite());
1500 dispatcher_->OnCanWrite();
1501
1502 // Check the other ordering.
1503 SetBlocked();
1504 dispatcher_->OnWriteBlocked(connection2());
1505 dispatcher_->OnWriteBlocked(connection1());
1506 EXPECT_CALL(*connection2(), OnCanWrite());
1507 EXPECT_CALL(*connection1(), OnCanWrite());
1508 dispatcher_->OnCanWrite();
1509}
1510
1511TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
1512 // Add and remove one connction.
1513 SetBlocked();
1514 dispatcher_->OnWriteBlocked(connection1());
1515 blocked_list_->erase(connection1());
1516 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1517 dispatcher_->OnCanWrite();
1518
1519 // Add and remove one connction and make sure it doesn't affect others.
1520 SetBlocked();
1521 dispatcher_->OnWriteBlocked(connection1());
1522 dispatcher_->OnWriteBlocked(connection2());
1523 blocked_list_->erase(connection1());
1524 EXPECT_CALL(*connection2(), OnCanWrite());
1525 dispatcher_->OnCanWrite();
1526
1527 // Add it, remove it, and add it back and make sure things are OK.
1528 SetBlocked();
1529 dispatcher_->OnWriteBlocked(connection1());
1530 blocked_list_->erase(connection1());
1531 dispatcher_->OnWriteBlocked(connection1());
1532 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1533 dispatcher_->OnCanWrite();
1534}
1535
1536TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
1537 // Make sure a double add does not necessitate a double remove.
1538 SetBlocked();
1539 dispatcher_->OnWriteBlocked(connection1());
1540 dispatcher_->OnWriteBlocked(connection1());
1541 blocked_list_->erase(connection1());
1542 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1543 dispatcher_->OnCanWrite();
1544
1545 // Make sure a double add does not result in two OnCanWrite calls.
1546 SetBlocked();
1547 dispatcher_->OnWriteBlocked(connection1());
1548 dispatcher_->OnWriteBlocked(connection1());
1549 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1550 dispatcher_->OnCanWrite();
1551}
1552
1553TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
1554 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1555 // into the write blocked list.
1556 InSequence s;
1557 SetBlocked();
1558 dispatcher_->OnWriteBlocked(connection1());
1559 dispatcher_->OnWriteBlocked(connection2());
1560 EXPECT_CALL(*connection1(), OnCanWrite())
1561 .WillOnce(
1562 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1563 EXPECT_CALL(*connection2(), OnCanWrite());
1564 dispatcher_->OnCanWrite();
1565
1566 // connection1 should be still in the write blocked list.
1567 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1568
1569 // Now call OnCanWrite again, connection1 should get its second chance.
1570 EXPECT_CALL(*connection1(), OnCanWrite());
1571 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1572 dispatcher_->OnCanWrite();
1573 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1574}
1575
1576TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
1577 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1578 // into the write blocked list.
1579 InSequence s;
1580 SetBlocked();
1581 dispatcher_->OnWriteBlocked(connection1());
1582 dispatcher_->OnWriteBlocked(connection2());
1583 EXPECT_CALL(*connection1(), OnCanWrite());
1584 EXPECT_CALL(*connection2(), OnCanWrite())
1585 .WillOnce(
1586 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1587 dispatcher_->OnCanWrite();
1588
1589 // connection2 should be still in the write blocked list.
1590 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1591
1592 // Now call OnCanWrite again, connection2 should get its second chance.
1593 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1594 EXPECT_CALL(*connection2(), OnCanWrite());
1595 dispatcher_->OnCanWrite();
1596 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1597}
1598
1599TEST_F(QuicDispatcherWriteBlockedListTest,
1600 OnCanWriteHandleBlockBothConnections) {
1601 // Both connections get blocked in OnCanWrite, and added back into the write
1602 // blocked list.
1603 InSequence s;
1604 SetBlocked();
1605 dispatcher_->OnWriteBlocked(connection1());
1606 dispatcher_->OnWriteBlocked(connection2());
1607 EXPECT_CALL(*connection1(), OnCanWrite())
1608 .WillOnce(
1609 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1610 EXPECT_CALL(*connection2(), OnCanWrite())
1611 .WillOnce(
1612 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1613 dispatcher_->OnCanWrite();
1614
1615 // Both connections should be still in the write blocked list.
1616 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1617
1618 // Now call OnCanWrite again, both connections should get its second chance.
1619 EXPECT_CALL(*connection1(), OnCanWrite());
1620 EXPECT_CALL(*connection2(), OnCanWrite());
1621 dispatcher_->OnCanWrite();
1622 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1623}
1624
1625TEST_F(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
1626 // By default, all connections share the same packet writer with the
1627 // dispatcher.
1628 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1629 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1630
1631 // Test the case where connection1 shares the same packet writer as the
1632 // dispatcher, whereas connection2 owns it's packet writer.
1633 // Change connection2's writer.
1634 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1635 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1636
1637 BlockConnection2();
1638 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1639
1640 EXPECT_CALL(*connection2(), OnCanWrite());
1641 dispatcher_->OnCanWrite();
1642 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1643}
1644
1645TEST_F(QuicDispatcherWriteBlockedListTest,
1646 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001647 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1648 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1649 ConnectionCloseSource::FROM_SELF);
1650
1651 SetBlocked();
1652
1653 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1654 SetBlocked();
1655 dispatcher_->OnWriteBlocked(connection1());
1656 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1657
1658 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1659 "QuicConnection was in WriteBlockedList before destruction");
1660 MarkSession1Deleted();
1661}
1662
1663// Tests that bufferring packets works in stateful reject, expensive stateless
1664// reject and cheap stateless reject.
1665struct BufferedPacketStoreTestParams {
1666 BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag,
1667 bool support_cheap_stateless_reject)
1668 : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag),
1669 support_cheap_stateless_reject(support_cheap_stateless_reject) {}
1670
1671 friend std::ostream& operator<<(std::ostream& os,
1672 const BufferedPacketStoreTestParams& p) {
1673 os << "{ enable_stateless_rejects_via_flag: "
1674 << p.enable_stateless_rejects_via_flag << std::endl;
1675 os << " support_cheap_stateless_reject: "
1676 << p.support_cheap_stateless_reject << " }";
1677 return os;
1678 }
1679
1680 // This only enables the stateless reject feature via the feature-flag.
1681 // This should be a no-op if the peer does not support them.
1682 bool enable_stateless_rejects_via_flag;
1683 // Whether to do cheap stateless or not.
1684 bool support_cheap_stateless_reject;
1685};
1686
1687std::vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() {
1688 std::vector<BufferedPacketStoreTestParams> params;
1689 for (bool enable_stateless_rejects_via_flag : {true, false}) {
1690 for (bool support_cheap_stateless_reject : {true, false}) {
1691 params.push_back(BufferedPacketStoreTestParams(
1692 enable_stateless_rejects_via_flag, support_cheap_stateless_reject));
1693 }
1694 }
1695 return params;
1696}
1697
1698// A dispatcher whose stateless rejector will always ACCEPTs CHLO.
1699class BufferedPacketStoreTest
1700 : public QuicDispatcherTest,
1701 public testing::WithParamInterface<BufferedPacketStoreTestParams> {
1702 public:
1703 BufferedPacketStoreTest()
1704 : QuicDispatcherTest(),
1705 server_addr_(QuicSocketAddress(QuicIpAddress::Any4(), 5)),
1706 client_addr_(QuicIpAddress::Loopback4(), 1234),
1707 signed_config_(new QuicSignedServerConfig) {
1708 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects,
1709 GetParam().support_cheap_stateless_reject);
1710 SetQuicReloadableFlag(enable_quic_stateless_reject_support,
1711 GetParam().enable_stateless_rejects_via_flag);
1712 }
1713
1714 void SetUp() override {
1715 QuicDispatcherTest::SetUp();
1716 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
1717
1718 QuicTransportVersion version = AllSupportedTransportVersions().front();
1719 CryptoHandshakeMessage chlo =
1720 crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
1721 &crypto_config_);
1722 chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
1723 // Pass an inchoate CHLO.
1724 crypto_test_utils::GenerateFullCHLO(
1725 chlo, &crypto_config_, server_addr_, client_addr_, version, clock_,
1726 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1727 &full_chlo_);
1728 }
1729
vasilvvc48c8712019-03-11 13:38:16 -07001730 std::string SerializeFullCHLO() {
1731 return std::string(full_chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001732 }
1733
1734 protected:
1735 QuicSocketAddress server_addr_;
1736 QuicSocketAddress client_addr_;
1737 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
1738 const QuicClock* clock_;
1739 CryptoHandshakeMessage full_chlo_;
1740};
1741
1742INSTANTIATE_TEST_SUITE_P(
1743 BufferedPacketStoreTests,
1744 BufferedPacketStoreTest,
1745 ::testing::ValuesIn(GetBufferedPacketStoreTestParams()));
1746
1747TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
1748 InSequence s;
1749 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1750 QuicConnectionId conn_id = TestConnectionId(1);
1751 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1752 // should trigger ShouldCreateOrBufferPacketForConnection().
1753 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id, _))
1754 .Times(1);
1755 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
1756 ProcessPacket(client_address, conn_id, true,
1757 QuicStrCat("data packet ", i + 1), CONNECTION_ID_PRESENT,
1758 PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
1759 }
1760 EXPECT_EQ(0u, dispatcher_->session_map().size())
1761 << "No session should be created before CHLO arrives.";
1762
1763 // Pop out the last packet as it is also be dropped by the store.
1764 data_connection_map_[conn_id].pop_back();
1765 // When CHLO arrives, a new session should be created, and all packets
1766 // buffered should be delivered to the session.
1767 EXPECT_CALL(*dispatcher_,
1768 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1769 .WillOnce(testing::Return(CreateSession(
1770 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1771 &mock_alarm_factory_, &crypto_config_,
1772 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1773
1774 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1775 // should be delivered in arrival order.
1776 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1777 ProcessUdpPacket(_, _, _))
1778 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1779 .WillRepeatedly(
1780 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1781 ValidatePacket(conn_id, packet);
1782 })));
1783 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1784}
1785
1786TEST_P(BufferedPacketStoreTest,
1787 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1788 InSequence s;
1789 // A bunch of non-CHLO should be buffered upon arrival.
1790 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1791 for (size_t i = 1; i <= kNumConnections; ++i) {
1792 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1793 QuicConnectionId conn_id = TestConnectionId(i);
1794 EXPECT_CALL(*dispatcher_,
1795 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1796 ProcessPacket(client_address, conn_id, true,
1797 QuicStrCat("data packet on connection ", i),
1798 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1799 /*packet_number=*/2);
1800 }
1801
1802 // Pop out the packet on last connection as it shouldn't be enqueued in store
1803 // as well.
1804 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1805
1806 // Reset session creation counter to ensure processing CHLO can always
1807 // create session.
1808 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
1809 kNumConnections);
1810 // Process CHLOs to create session for these connections.
1811 for (size_t i = 1; i <= kNumConnections; ++i) {
1812 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1813 QuicConnectionId conn_id = TestConnectionId(i);
1814 if (i == kNumConnections) {
1815 EXPECT_CALL(*dispatcher_,
1816 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1817 }
1818 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address,
1819 QuicStringPiece(), _))
1820 .WillOnce(testing::Return(CreateSession(
1821 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1822 &mock_alarm_factory_, &crypto_config_,
1823 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1824 // First |kNumConnections| - 1 connections should have buffered
1825 // a packet in store. The rest should have been dropped.
1826 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
1827 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1828 ProcessUdpPacket(_, client_address, _))
1829 .Times(num_packet_to_process)
1830 .WillRepeatedly(WithArg<2>(
1831 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1832 ValidatePacket(conn_id, packet);
1833 })));
1834
1835 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1836 }
1837}
1838
1839// Tests that store delivers empty packet list if CHLO arrives firstly.
1840TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
1841 QuicConnectionId conn_id = TestConnectionId(1);
1842 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1843 EXPECT_CALL(*dispatcher_,
1844 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1845 EXPECT_CALL(*dispatcher_,
1846 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1847 .WillOnce(testing::Return(CreateSession(
1848 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1849 &mock_alarm_factory_, &crypto_config_,
1850 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1851 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1852 ProcessUdpPacket(_, client_address, _));
1853 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1854}
1855
1856// Tests that a retransmitted CHLO arrives after a connection for the
1857// CHLO has been created.
1858TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
1859 InSequence s;
1860 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1861 QuicConnectionId conn_id = TestConnectionId(1);
1862 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1863 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1864 /*packet_number=*/2);
1865
1866 // When CHLO arrives, a new session should be created, and all packets
1867 // buffered should be delivered to the session.
1868 EXPECT_CALL(*dispatcher_,
1869 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1870 .Times(1) // Only triggered by 1st CHLO.
1871 .WillOnce(testing::Return(CreateSession(
1872 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1873 &mock_alarm_factory_, &crypto_config_,
1874 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1875 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1876 ProcessUdpPacket(_, _, _))
1877 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
1878 .WillRepeatedly(
1879 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1880 ValidatePacket(conn_id, packet);
1881 })));
1882 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1883
1884 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1885}
1886
1887// Tests that expiration of a connection add connection id to time wait list.
1888TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
1889 InSequence s;
1890 CreateTimeWaitListManager();
1891 QuicBufferedPacketStore* store =
1892 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1893 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
1894
1895 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1896 QuicConnectionId conn_id = TestConnectionId(1);
1897 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1898 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1899 /*packet_number=*/2);
1900
1901 mock_helper_.AdvanceTime(
1902 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
1903 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
1904 // Cancel alarm as if it had been fired.
1905 alarm->Cancel();
1906 store->OnExpirationTimeout();
1907 // New arrived CHLO will be dropped because this connection is in time wait
1908 // list.
1909 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
1910 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
1911 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1912}
1913
1914TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
1915 // Process more than (|kMaxNumSessionsToCreate| +
1916 // |kDefaultMaxConnectionsInStore|) CHLOs,
1917 // the first |kMaxNumSessionsToCreate| should create connections immediately,
1918 // the next |kDefaultMaxConnectionsInStore| should be buffered,
1919 // the rest should be dropped.
1920 QuicBufferedPacketStore* store =
1921 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1922 const size_t kNumCHLOs =
1923 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
1924 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
1925 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1926 TestConnectionId(conn_id), _));
1927 if (conn_id <= kMaxNumSessionsToCreate) {
1928 EXPECT_CALL(*dispatcher_,
1929 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1930 QuicStringPiece(), _))
1931 .WillOnce(testing::Return(CreateSession(
1932 dispatcher_.get(), config_, TestConnectionId(conn_id),
1933 client_addr_, &mock_helper_, &mock_alarm_factory_,
1934 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1935 &session1_)));
1936 EXPECT_CALL(
1937 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1938 ProcessUdpPacket(_, _, _))
1939 .WillOnce(WithArg<2>(
1940 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1941 ValidatePacket(TestConnectionId(conn_id), packet);
1942 })));
1943 }
1944 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1945 SerializeFullCHLO());
1946 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
1947 conn_id > kMaxNumSessionsToCreate) {
1948 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
1949 } else {
1950 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
1951 // connections immediately, and the last CHLO should be dropped as the
1952 // store is full.
1953 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
1954 }
1955 }
1956
1957 // Graduately consume buffered CHLOs. The buffered connections should be
1958 // created but the dropped one shouldn't.
1959 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
1960 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
1961 ++conn_id) {
1962 EXPECT_CALL(*dispatcher_,
1963 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1964 QuicStringPiece(), _))
1965 .WillOnce(testing::Return(CreateSession(
1966 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
1967 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1968 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1969 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1970 ProcessUdpPacket(_, _, _))
1971 .WillOnce(WithArg<2>(
1972 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1973 ValidatePacket(TestConnectionId(conn_id), packet);
1974 })));
1975 }
1976 EXPECT_CALL(*dispatcher_,
1977 CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_,
1978 QuicStringPiece(), _))
1979 .Times(0);
1980
1981 while (store->HasChlosBuffered()) {
1982 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
1983 }
1984
1985 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
1986 kDefaultMaxConnectionsInStore),
1987 session1_->connection_id());
1988}
1989
1990// Duplicated CHLO shouldn't be buffered.
1991TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
1992 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
1993 ++conn_id) {
1994 // Last CHLO will be buffered. Others will create connection right away.
1995 if (conn_id <= kMaxNumSessionsToCreate) {
1996 EXPECT_CALL(*dispatcher_,
1997 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1998 QuicStringPiece(), _))
1999 .WillOnce(testing::Return(CreateSession(
2000 dispatcher_.get(), config_, TestConnectionId(conn_id),
2001 client_addr_, &mock_helper_, &mock_alarm_factory_,
2002 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2003 &session1_)));
2004 EXPECT_CALL(
2005 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2006 ProcessUdpPacket(_, _, _))
2007 .WillOnce(WithArg<2>(
2008 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2009 ValidatePacket(TestConnectionId(conn_id), packet);
2010 })));
2011 }
2012 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2013 SerializeFullCHLO());
2014 }
2015 // Retransmit CHLO on last connection should be dropped.
2016 QuicConnectionId last_connection =
2017 TestConnectionId(kMaxNumSessionsToCreate + 1);
2018 ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO());
2019
2020 size_t packets_buffered = 2;
2021
2022 // Reset counter and process buffered CHLO.
2023 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
2024 QuicStringPiece(), _))
2025 .WillOnce(testing::Return(CreateSession(
2026 dispatcher_.get(), config_, last_connection, client_addr_,
2027 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2028 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2029 // Only one packet(CHLO) should be process.
2030 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2031 ProcessUdpPacket(_, _, _))
2032 .Times(packets_buffered)
2033 .WillRepeatedly(WithArg<2>(
2034 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
2035 ValidatePacket(last_connection, packet);
2036 })));
2037 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2038}
2039
2040TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
2041 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2042 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2043 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2044 // Last CHLO will be buffered. Others will create connection right away.
2045 if (conn_id <= kMaxNumSessionsToCreate) {
2046 EXPECT_CALL(*dispatcher_,
2047 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2048 QuicStringPiece(), _))
2049 .WillOnce(testing::Return(CreateSession(
2050 dispatcher_.get(), config_, TestConnectionId(conn_id),
2051 client_addr_, &mock_helper_, &mock_alarm_factory_,
2052 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2053 &session1_)));
2054 EXPECT_CALL(
2055 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2056 ProcessUdpPacket(_, _, _))
2057 .WillRepeatedly(WithArg<2>(
2058 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2059 ValidatePacket(TestConnectionId(conn_id), packet);
2060 })));
2061 }
2062 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2063 SerializeFullCHLO());
2064 }
2065
2066 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
2067 // last one should be dropped.
2068 for (uint64_t packet_number = 2;
2069 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
2070 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
2071 }
2072
2073 // Reset counter and process buffered CHLO.
2074 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
2075 QuicStringPiece(), _))
2076 .WillOnce(testing::Return(CreateSession(
2077 dispatcher_.get(), config_, last_connection_id, client_addr_,
2078 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2079 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2080 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
2081 // should be process.
2082 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2083 ProcessUdpPacket(_, _, _))
2084 .Times(kDefaultMaxUndecryptablePackets + 1)
2085 .WillRepeatedly(WithArg<2>(
2086 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
2087 ValidatePacket(last_connection_id, packet);
2088 })));
2089 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2090}
2091
2092// Tests that when dispatcher's packet buffer is full, a CHLO on connection
2093// which doesn't have buffered CHLO should be buffered.
2094TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
2095 QuicBufferedPacketStore* store =
2096 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2097
2098 uint64_t conn_id = 1;
2099 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, "data packet",
2100 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
2101 /*packet_number=*/1);
2102 // Fill packet buffer to full with CHLOs on other connections. Need to feed
2103 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
2104 // session directly.
2105 for (conn_id = 2;
2106 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
2107 ++conn_id) {
2108 if (conn_id <= kMaxNumSessionsToCreate + 1) {
2109 EXPECT_CALL(*dispatcher_,
2110 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2111 QuicStringPiece(), _))
2112 .WillOnce(testing::Return(CreateSession(
2113 dispatcher_.get(), config_, TestConnectionId(conn_id),
2114 client_addr_, &mock_helper_, &mock_alarm_factory_,
2115 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2116 &session1_)));
2117 EXPECT_CALL(
2118 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2119 ProcessUdpPacket(_, _, _))
2120 .WillOnce(WithArg<2>(
2121 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2122 ValidatePacket(TestConnectionId(conn_id), packet);
2123 })));
2124 }
2125 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
2126 SerializeFullCHLO());
2127 }
2128 EXPECT_FALSE(store->HasChloForConnection(
2129 /*connection_id=*/TestConnectionId(1)));
2130
2131 // CHLO on connection 1 should still be buffered.
2132 ProcessPacket(client_addr_, /*connection_id=*/TestConnectionId(1), true,
2133 SerializeFullCHLO());
2134 EXPECT_TRUE(store->HasChloForConnection(
2135 /*connection_id=*/TestConnectionId(1)));
2136}
2137
2138// Regression test for b/117874922.
2139TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
2140 // Turn off version 99, such that the preferred version is not supported by
2141 // the server.
2142 SetQuicReloadableFlag(quic_enable_version_99, false);
2143 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
2144 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
2145 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
2146 // Last 5 CHLOs will be buffered. Others will create connection right away.
2147 ParsedQuicVersion version =
2148 supported_versions[(conn_id - 1) % supported_versions.size()];
2149 if (conn_id <= kMaxNumSessionsToCreate) {
2150 EXPECT_CALL(*dispatcher_,
2151 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2152 QuicStringPiece(), version))
2153 .WillOnce(testing::Return(CreateSession(
2154 dispatcher_.get(), config_, TestConnectionId(conn_id),
2155 client_addr_, &mock_helper_, &mock_alarm_factory_,
2156 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2157 &session1_)));
2158 EXPECT_CALL(
2159 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2160 ProcessUdpPacket(_, _, _))
2161 .WillRepeatedly(WithArg<2>(
2162 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2163 ValidatePacket(TestConnectionId(conn_id), packet);
2164 })));
2165 }
2166 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, version,
2167 SerializeFullCHLO(), CONNECTION_ID_PRESENT,
2168 PACKET_4BYTE_PACKET_NUMBER, 1);
2169 }
2170
2171 // Process buffered CHLOs. Verify the version is correct.
2172 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2173 conn_id <= last_connection_id; ++conn_id) {
2174 ParsedQuicVersion version =
2175 supported_versions[(conn_id - 1) % supported_versions.size()];
2176 EXPECT_CALL(*dispatcher_,
2177 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2178 QuicStringPiece(), version))
2179 .WillOnce(testing::Return(CreateSession(
2180 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2181 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2182 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
2183 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2184 ProcessUdpPacket(_, _, _))
2185 .WillRepeatedly(WithArg<2>(
2186 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2187 ValidatePacket(TestConnectionId(conn_id), packet);
2188 })));
2189 }
2190 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2191}
2192
2193// Test which exercises the async GetProof codepaths, especially in the context
2194// of stateless rejection.
2195class AsyncGetProofTest : public QuicDispatcherTest {
2196 public:
2197 AsyncGetProofTest()
2198 : QuicDispatcherTest(
2199 std::unique_ptr<FakeProofSource>(new FakeProofSource())),
2200 client_addr_(QuicIpAddress::Loopback4(), 1234),
2201 client_addr_2_(QuicIpAddress::Loopback4(), 1357),
2202 crypto_config_peer_(&crypto_config_),
2203 server_addr_(QuicIpAddress::Any4(), 5),
2204 signed_config_(new QuicSignedServerConfig) {
2205 SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
2206 SetQuicReloadableFlag(quic_use_cheap_stateless_rejects, true);
2207 }
2208
2209 void SetUp() override {
2210 QuicDispatcherTest::SetUp();
2211
2212 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
2213 QuicTransportVersion version = AllSupportedTransportVersions().front();
2214 chlo_ = crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
2215 &crypto_config_);
2216 chlo_.SetVector(kCOPT, QuicTagVector{kSREJ});
2217 chlo_.SetStringPiece(kALPN, "HTTP/1");
2218 // Pass an inchoate CHLO.
2219 crypto_test_utils::GenerateFullCHLO(
2220 chlo_, &crypto_config_, server_addr_, client_addr_, version, clock_,
2221 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2222 &full_chlo_);
2223
2224 crypto_test_utils::GenerateFullCHLO(
2225 chlo_, &crypto_config_, server_addr_, client_addr_2_, version, clock_,
2226 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2227 &full_chlo_2_);
2228
2229 GetFakeProofSource()->Activate();
2230 }
2231
2232 FakeProofSource* GetFakeProofSource() const {
2233 return static_cast<FakeProofSource*>(crypto_config_peer_.GetProofSource());
2234 }
2235
vasilvvc48c8712019-03-11 13:38:16 -07002236 std::string SerializeFullCHLO() {
2237 return std::string(full_chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002238 }
2239
vasilvvc48c8712019-03-11 13:38:16 -07002240 std::string SerializeFullCHLOForClient2() {
2241 return std::string(full_chlo_2_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002242 }
2243
vasilvvc48c8712019-03-11 13:38:16 -07002244 std::string SerializeCHLO() {
2245 return std::string(chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002246 }
2247
2248 // Sets up a session, and crypto stream based on the test parameters.
2249 QuicServerSessionBase* GetSession(QuicConnectionId connection_id,
2250 QuicSocketAddress client_address) {
2251 auto it = sessions_.find(connection_id);
2252 if (it != sessions_.end()) {
2253 return it->second.session;
2254 }
2255
2256 TestQuicSpdyServerSession* session;
2257 CreateSession(dispatcher_.get(), config_, connection_id, client_address,
2258 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2259 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session);
2260
2261 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream(
2262 new MockQuicCryptoServerStream(
2263 crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2264 session, session->stream_helper()));
2265 session->SetCryptoStream(crypto_stream.get());
2266 crypto_stream->SetPeerSupportsStatelessRejects(true);
2267 const bool ok =
2268 sessions_
2269 .insert(std::make_pair(
2270 connection_id, SessionInfo{session, std::move(crypto_stream)}))
2271 .second;
2272 CHECK(ok);
2273 return session;
2274 }
2275
2276 protected:
2277 const QuicSocketAddress client_addr_;
2278 const QuicSocketAddress client_addr_2_;
2279 CryptoHandshakeMessage chlo_;
2280
2281 private:
2282 QuicCryptoServerConfigPeer crypto_config_peer_;
2283 QuicSocketAddress server_addr_;
2284 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
2285 const QuicClock* clock_;
2286 CryptoHandshakeMessage full_chlo_; // CHLO for client_addr_
2287 CryptoHandshakeMessage full_chlo_2_; // CHLO for client_addr_2_
2288
2289 struct SessionInfo {
2290 TestQuicSpdyServerSession* session;
2291 std::unique_ptr<MockQuicCryptoServerStream> crypto_stream;
2292 };
2293 std::map<QuicConnectionId, SessionInfo> sessions_;
2294};
2295
2296// Test a simple situation of connections which the StatelessRejector will
2297// accept.
2298TEST_F(AsyncGetProofTest, BasicAccept) {
2299 QuicConnectionId conn_id = TestConnectionId(1);
2300
2301 testing::MockFunction<void(int check_point)> check;
2302 {
2303 InSequence s;
2304
2305 EXPECT_CALL(check, Call(1));
2306 EXPECT_CALL(*dispatcher_,
2307 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2308 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2309 QuicStringPiece("HTTP/1"), _))
2310 .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
2311 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2312 GetSession(conn_id, client_addr_)->connection()),
2313 ProcessUdpPacket(_, _, _))
2314 .WillOnce(WithArg<2>(
2315 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2316 ValidatePacket(conn_id, packet);
2317 })));
2318
2319 EXPECT_CALL(check, Call(2));
2320 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2321 GetSession(conn_id, client_addr_)->connection()),
2322 ProcessUdpPacket(_, _, _))
2323 .WillOnce(WithArg<2>(
2324 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2325 ValidatePacket(conn_id, packet);
2326 })));
2327 }
2328
2329 // Send a CHLO that the StatelessRejector will accept.
2330 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2331 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2332
2333 check.Call(1);
2334 // Complete the ProofSource::GetProof call and verify that a session is
2335 // created.
2336 GetFakeProofSource()->InvokePendingCallback(0);
2337 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2338
2339 check.Call(2);
2340 // Verify that a data packet gets processed immediately.
2341 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2342}
2343
2344TEST_F(AsyncGetProofTest, RestorePacketContext) {
2345 QuicConnectionId conn_id_1 = TestConnectionId(1);
2346 QuicConnectionId conn_id_2 = TestConnectionId(2);
2347
2348 testing::MockFunction<void(int check_point)> check;
2349 {
2350 InSequence s;
2351 EXPECT_CALL(check, Call(1));
2352 EXPECT_CALL(*dispatcher_,
2353 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2354
2355 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2356 QuicStringPiece("HTTP/1"), _))
2357 .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
2358 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2359 GetSession(conn_id_1, client_addr_)->connection()),
2360 ProcessUdpPacket(_, _, _))
2361 .WillRepeatedly(WithArg<2>(
2362 Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
2363 ValidatePacket(conn_id_1, packet);
2364 })));
2365
2366 EXPECT_CALL(check, Call(2));
2367
2368 EXPECT_CALL(*dispatcher_,
2369 ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
2370 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_2_,
2371 QuicStringPiece("HTTP/1"), _))
2372 .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_2_)));
2373 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2374 GetSession(conn_id_2, client_addr_2_)->connection()),
2375 ProcessUdpPacket(_, _, _))
2376 .WillOnce(WithArg<2>(
2377 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2378 ValidatePacket(conn_id_2, packet);
2379 })));
2380 }
2381
2382 // Send a CHLO that the StatelessRejector will accept.
2383 dispatcher_->custom_packet_context_ = "connection 1";
2384 ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
2385 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2386
2387 // Send another CHLO that the StatelessRejector will accept.
2388 dispatcher_->custom_packet_context_ = "connection 2";
2389 ProcessPacket(client_addr_2_, conn_id_2, true, SerializeFullCHLOForClient2());
2390 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2391
2392 // Complete the first ProofSource::GetProof call and verify that a session is
2393 // created.
2394 check.Call(1);
2395
2396 EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
2397 EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
2398 EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
2399
2400 // Runs the async proof callback for conn_id_1 from client_addr_.
2401 GetFakeProofSource()->InvokePendingCallback(0);
2402
2403 EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
2404 EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
2405 EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
2406
2407 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2408
2409 // Complete the second ProofSource::GetProof call and verify that a session is
2410 // created.
2411 check.Call(2);
2412
2413 EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
2414 EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
2415 EXPECT_EQ("connection 1", dispatcher_->custom_packet_context_);
2416
2417 // Runs the async proof callback for conn_id_2 from client_addr_2_.
2418 GetFakeProofSource()->InvokePendingCallback(0);
2419
2420 EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
2421 EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
2422 EXPECT_EQ("connection 2", dispatcher_->custom_packet_context_);
2423
2424 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2425}
2426
2427// Test a simple situation of connections which the StatelessRejector will
2428// reject.
2429TEST_F(AsyncGetProofTest, BasicReject) {
2430 CreateTimeWaitListManager();
2431
2432 QuicConnectionId conn_id = TestConnectionId(1);
2433
2434 testing::MockFunction<void(int check_point)> check;
2435 {
2436 InSequence s;
2437 EXPECT_CALL(check, Call(1));
2438 EXPECT_CALL(*time_wait_list_manager_,
2439 AddConnectionIdToTimeWait(conn_id, _, _, _, _));
2440 EXPECT_CALL(*time_wait_list_manager_,
2441 ProcessPacket(_, client_addr_, conn_id, _, _));
2442
2443 EXPECT_CALL(check, Call(2));
2444 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2445 QuicStringPiece("hq"), _))
2446 .Times(0);
2447 EXPECT_CALL(*time_wait_list_manager_,
2448 ProcessPacket(_, client_addr_, conn_id, _, _));
2449 }
2450
2451 // Send a CHLO that the StatelessRejector will reject.
2452 ProcessPacket(client_addr_, conn_id, true, SerializeCHLO());
2453 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2454
2455 // Complete the ProofSource::GetProof call and verify that the connection and
2456 // packet are processed by the time wait list manager.
2457 check.Call(1);
2458 GetFakeProofSource()->InvokePendingCallback(0);
2459 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2460
2461 // Verify that a data packet is passed to the time wait list manager.
2462 check.Call(2);
2463 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2464}
2465
2466// Test a situation with multiple interleaved connections which the
2467// StatelessRejector will accept.
2468TEST_F(AsyncGetProofTest, MultipleAccept) {
2469 QuicConnectionId conn_id_1 = TestConnectionId(1);
2470 QuicConnectionId conn_id_2 = TestConnectionId(2);
2471 QuicBufferedPacketStore* store =
2472 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2473
2474 testing::MockFunction<void(int check_point)> check;
2475 {
2476 InSequence s;
2477 EXPECT_CALL(check, Call(1));
2478 EXPECT_CALL(*dispatcher_,
2479 ShouldCreateOrBufferPacketForConnection(conn_id_2, _));
2480 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_,
2481 QuicStringPiece("HTTP/1"), _))
2482 .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_)));
2483 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2484 GetSession(conn_id_2, client_addr_)->connection()),
2485 ProcessUdpPacket(_, _, _))
2486 .WillOnce(WithArg<2>(
2487 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2488 ValidatePacket(conn_id_2, packet);
2489 })));
2490
2491 EXPECT_CALL(check, Call(2));
2492 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2493 GetSession(conn_id_2, client_addr_)->connection()),
2494 ProcessUdpPacket(_, _, _))
2495 .WillOnce(WithArg<2>(
2496 Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
2497 ValidatePacket(conn_id_2, packet);
2498 })));
2499
2500 EXPECT_CALL(check, Call(3));
2501 EXPECT_CALL(*dispatcher_,
2502 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2503
2504 EXPECT_CALL(check, Call(4));
2505 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2506 QuicStringPiece("HTTP/1"), _))
2507 .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
2508 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2509 GetSession(conn_id_1, client_addr_)->connection()),
2510 ProcessUdpPacket(_, _, _))
2511 .WillRepeatedly(WithArg<2>(
2512 Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
2513 ValidatePacket(conn_id_1, packet);
2514 })));
2515 }
2516
2517 // Send a CHLO that the StatelessRejector will accept.
2518 ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
2519 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2520
2521 // Send another CHLO that the StatelessRejector will accept.
2522 ProcessPacket(client_addr_, conn_id_2, true, SerializeFullCHLO());
2523 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2524
2525 // Complete the second ProofSource::GetProof call and verify that a session is
2526 // created.
2527 check.Call(1);
2528 GetFakeProofSource()->InvokePendingCallback(1);
2529 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2530
2531 // Verify that a data packet on that connection gets processed immediately.
2532 check.Call(2);
2533 ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
2534
2535 // Verify that a data packet on the other connection does not get processed
2536 // yet.
2537 check.Call(3);
2538 ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
2539 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2540 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2541
2542 // Complete the first ProofSource::GetProof call and verify that a session is
2543 // created and the buffered packet is processed.
2544 check.Call(4);
2545 GetFakeProofSource()->InvokePendingCallback(0);
2546 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2547}
2548
2549// Test a situation with multiple interleaved connections which the
2550// StatelessRejector will reject.
2551TEST_F(AsyncGetProofTest, MultipleReject) {
2552 CreateTimeWaitListManager();
2553
2554 QuicConnectionId conn_id_1 = TestConnectionId(1);
2555 QuicConnectionId conn_id_2 = TestConnectionId(2);
2556 QuicBufferedPacketStore* store =
2557 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2558
2559 testing::MockFunction<void(int check_point)> check;
2560 {
2561 InSequence s;
2562
2563 EXPECT_CALL(check, Call(1));
2564 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_, _, _))
2565 .Times(0);
2566 EXPECT_CALL(*time_wait_list_manager_,
2567 AddConnectionIdToTimeWait(conn_id_2, _, _, _, _));
2568 EXPECT_CALL(*time_wait_list_manager_,
2569 ProcessPacket(_, client_addr_, conn_id_2, _, _));
2570
2571 EXPECT_CALL(check, Call(2));
2572 EXPECT_CALL(*time_wait_list_manager_,
2573 ProcessPacket(_, client_addr_, conn_id_2, _, _));
2574
2575 EXPECT_CALL(check, Call(3));
2576 EXPECT_CALL(*dispatcher_,
2577 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2578
2579 EXPECT_CALL(check, Call(4));
2580 EXPECT_CALL(*time_wait_list_manager_,
2581 AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
2582 EXPECT_CALL(*time_wait_list_manager_,
2583 ProcessPacket(_, client_addr_, conn_id_1, _, _));
2584 }
2585
2586 // Send a CHLO that the StatelessRejector will reject.
2587 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2588 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2589
2590 // Send another CHLO that the StatelessRejector will reject.
2591 ProcessPacket(client_addr_, conn_id_2, true, SerializeCHLO());
2592 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2593
2594 // Complete the second ProofSource::GetProof call and verify that the
2595 // connection and packet are processed by the time wait manager.
2596 check.Call(1);
2597 GetFakeProofSource()->InvokePendingCallback(1);
2598 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2599
2600 // Verify that a data packet on that connection gets processed immediately by
2601 // the time wait manager.
2602 check.Call(2);
2603 ProcessPacket(client_addr_, conn_id_2, true, "My name is Data");
2604
2605 // Verify that a data packet on the first connection gets buffered.
2606 check.Call(3);
2607 ProcessPacket(client_addr_, conn_id_1, true, "My name is Data");
2608 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2609 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2610
2611 // Complete the first ProofSource::GetProof call and verify that the CHLO is
2612 // processed by the time wait manager and the remaining packets are discarded.
2613 check.Call(4);
2614 GetFakeProofSource()->InvokePendingCallback(0);
2615 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2616 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2617 EXPECT_FALSE(store->HasBufferedPackets(conn_id_2));
2618}
2619
2620// Test a situation with multiple identical CHLOs which the StatelessRejector
2621// will reject.
2622TEST_F(AsyncGetProofTest, MultipleIdenticalReject) {
2623 CreateTimeWaitListManager();
2624
2625 QuicConnectionId conn_id_1 = TestConnectionId(1);
2626 QuicBufferedPacketStore* store =
2627 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2628
2629 testing::MockFunction<void(int check_point)> check;
2630 {
2631 InSequence s;
2632 EXPECT_CALL(check, Call(1));
2633 EXPECT_CALL(*dispatcher_,
2634 ShouldCreateOrBufferPacketForConnection(conn_id_1, _));
2635
2636 EXPECT_CALL(check, Call(2));
2637 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
2638 QuicStringPiece(), _))
2639 .Times(0);
2640 EXPECT_CALL(*time_wait_list_manager_,
2641 AddConnectionIdToTimeWait(conn_id_1, _, _, _, _));
2642 EXPECT_CALL(*time_wait_list_manager_,
2643 ProcessPacket(_, client_addr_, conn_id_1, _, _));
2644 }
2645
2646 // Send a CHLO that the StatelessRejector will reject.
2647 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2648 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2649 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2650
2651 // Send an identical CHLO which should get buffered.
2652 check.Call(1);
2653 ProcessPacket(client_addr_, conn_id_1, true, SerializeCHLO());
2654 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2655 EXPECT_TRUE(store->HasBufferedPackets(conn_id_1));
2656
2657 // Complete the ProofSource::GetProof call and verify that the CHLO is
2658 // rejected and the copy is discarded.
2659 check.Call(2);
2660 GetFakeProofSource()->InvokePendingCallback(0);
2661 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2662 EXPECT_FALSE(store->HasBufferedPackets(conn_id_1));
2663}
2664
2665// Test dispatcher behavior when packets time out of the buffer while CHLO
2666// validation is still pending.
2667TEST_F(AsyncGetProofTest, BufferTimeout) {
2668 CreateTimeWaitListManager();
2669
2670 QuicConnectionId conn_id = TestConnectionId(1);
2671 QuicBufferedPacketStore* store =
2672 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2673 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2674
2675 testing::MockFunction<void(int check_point)> check;
2676 {
2677 InSequence s;
2678 EXPECT_CALL(check, Call(1));
2679 EXPECT_CALL(*dispatcher_,
2680 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2681
2682 EXPECT_CALL(check, Call(2));
2683 EXPECT_CALL(*time_wait_list_manager_,
2684 ProcessPacket(_, client_addr_, conn_id, _, _));
2685 EXPECT_CALL(*dispatcher_,
2686 CreateQuicSession(conn_id, client_addr_, QuicStringPiece(), _))
2687 .Times(0);
2688 }
2689
2690 // Send a CHLO that the StatelessRejector will accept.
2691 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2692 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2693 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2694
2695 // Send a data packet that will get buffered
2696 check.Call(1);
2697 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2698 EXPECT_TRUE(store->HasBufferedPackets(conn_id));
2699
2700 // Pretend that enough time has gone by for the packets to get expired out of
2701 // the buffer
2702 mock_helper_.AdvanceTime(
2703 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2704 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
2705 store->OnExpirationTimeout();
2706 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2707 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2708
2709 // Now allow the CHLO validation to complete, and verify that no connection
2710 // gets created.
2711 check.Call(2);
2712 GetFakeProofSource()->InvokePendingCallback(0);
2713 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2714 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2715 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2716}
2717
2718// Test behavior when packets time out of the buffer *and* the connection times
2719// out of the time wait manager while CHLO validation is still pending. This
2720// *should* be impossible, but anything can happen with timing conditions.
2721TEST_F(AsyncGetProofTest, TimeWaitTimeout) {
2722 QuicConnectionId conn_id = TestConnectionId(1);
2723 QuicBufferedPacketStore* store =
2724 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2725 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2726 CreateTimeWaitListManager();
2727 QuicTimeWaitListManagerPeer::set_clock(time_wait_list_manager_,
2728 mock_helper_.GetClock());
2729
2730 testing::MockFunction<void(int check_point)> check;
2731 {
2732 InSequence s;
2733 EXPECT_CALL(check, Call(1));
2734 EXPECT_CALL(*dispatcher_,
2735 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2736
2737 EXPECT_CALL(check, Call(2));
2738 EXPECT_CALL(*dispatcher_,
2739 ShouldCreateOrBufferPacketForConnection(conn_id, _));
2740 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
2741 QuicStringPiece("HTTP/1"), _))
2742 .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
2743 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
2744 GetSession(conn_id, client_addr_)->connection()),
2745 ProcessUdpPacket(_, _, _))
2746 .WillOnce(WithArg<2>(
2747 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2748 ValidatePacket(conn_id, packet);
2749 })));
2750 }
2751
2752 // Send a CHLO that the StatelessRejector will accept.
2753 ProcessPacket(client_addr_, conn_id, true, SerializeFullCHLO());
2754 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2755 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2756
2757 // Send a data packet that will get buffered
2758 check.Call(1);
2759 ProcessPacket(client_addr_, conn_id, true, "My name is Data");
2760 EXPECT_TRUE(store->HasBufferedPackets(conn_id));
2761
2762 // Pretend that enough time has gone by for the packets to get expired out of
2763 // the buffer
2764 mock_helper_.AdvanceTime(
2765 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2766 QuicBufferedPacketStorePeer::expiration_alarm(store)->Cancel();
2767 store->OnExpirationTimeout();
2768 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2769 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2770
2771 // Pretend that enough time has gone by for the connection ID to be removed
2772 // from the time wait manager
2773 mock_helper_.AdvanceTime(
2774 QuicTimeWaitListManagerPeer::time_wait_period(time_wait_list_manager_));
2775 QuicTimeWaitListManagerPeer::expiration_alarm(time_wait_list_manager_)
2776 ->Cancel();
2777 time_wait_list_manager_->CleanUpOldConnectionIds();
2778 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2779
2780 // Now allow the CHLO validation to complete. Expect that a connection is
2781 // indeed created, since QUIC has forgotten that this connection ever existed.
2782 // This is a miniscule corner case which should never happen in the wild, so
2783 // really we are just verifying that the dispatcher does not explode in this
2784 // situation.
2785 check.Call(2);
2786 GetFakeProofSource()->InvokePendingCallback(0);
2787 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2788 EXPECT_FALSE(store->HasBufferedPackets(conn_id));
2789 EXPECT_FALSE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2790}
2791
2792// Regression test for
2793// https://bugs.chromium.org/p/chromium/issues/detail?id=748289
2794TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
2795 // This test mimics the scenario that dispatcher's framer can have different
2796 // version when async proof returns.
2797 // When dispatcher sends SREJ, the SREJ frame can be serialized in
2798 // different endianness which causes the client to close the connection
2799 // because of QUIC_INVALID_STREAM_DATA.
2800
2801 SetQuicReloadableFlag(quic_disable_version_39, false);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002802 ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
2803 chlo_.SetVersion(kVER, chlo_version);
2804 // Send a CHLO with v43. Dispatcher framer's version is set to v43.
2805 ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
2806 SerializeCHLO(), CONNECTION_ID_PRESENT,
2807 PACKET_4BYTE_PACKET_NUMBER, 1);
2808
2809 // Send another CHLO with v39. Dispatcher framer's version is set to v39.
2810 chlo_version.transport_version = QUIC_VERSION_39;
2811 chlo_.SetVersion(kVER, chlo_version);
2812 // Invalidate the cached serialized form.
2813 chlo_.MarkDirty();
2814 ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
2815 SerializeCHLO(), CONNECTION_ID_PRESENT,
2816 PACKET_4BYTE_PACKET_NUMBER, 1);
2817 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2818
2819 // Complete the ProofSource::GetProof call for v43. This would cause the
2820 // version mismatch between the CHLO packet and the dispatcher.
2821 GetFakeProofSource()->InvokePendingCallback(0);
2822 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2823}
2824
2825// Regression test for b/116200989.
2826TEST_F(AsyncGetProofTest, DispatcherHasWrongLastPacketIsIetfQuic) {
2827 // Process a packet of v44.
2828 ParsedQuicVersion chlo_version(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_44);
2829 chlo_.SetVersion(kVER, chlo_version);
2830 ProcessPacket(client_addr_, TestConnectionId(1), true, chlo_version,
2831 SerializeCHLO(), CONNECTION_ID_PRESENT,
2832 PACKET_4BYTE_PACKET_NUMBER, 1);
2833
2834 // Process another packet of v43.
2835 chlo_version.transport_version = QUIC_VERSION_43;
2836 chlo_.SetVersion(kVER, chlo_version);
2837 // Invalidate the cached serialized form.
2838 chlo_.MarkDirty();
2839 ProcessPacket(client_addr_, TestConnectionId(2), true, chlo_version,
2840 SerializeCHLO(), CONNECTION_ID_PRESENT,
2841 PACKET_4BYTE_PACKET_NUMBER, 1);
2842 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
2843
2844 // Complete the ProofSource::GetProof call for v44.
2845 GetFakeProofSource()->InvokePendingCallback(0);
2846 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
2847
2848 // Complete the ProofSource::GetProof call for v43.
2849 GetFakeProofSource()->InvokePendingCallback(0);
2850 ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
2851}
2852
2853} // namespace
2854} // namespace test
2855} // namespace quic