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