1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_dispatcher.h"
6
7 #include <cstddef>
8 #include <cstdint>
9 #include <map>
10 #include <memory>
11 #include <optional>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
16
17 #include "absl/base/macros.h"
18 #include "absl/strings/str_cat.h"
19 #include "absl/strings/string_view.h"
20 #include "quiche/quic/core/chlo_extractor.h"
21 #include "quiche/quic/core/connection_id_generator.h"
22 #include "quiche/quic/core/crypto/crypto_protocol.h"
23 #include "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
24 #include "quiche/quic/core/crypto/quic_crypto_client_config.h"
25 #include "quiche/quic/core/crypto/quic_crypto_server_config.h"
26 #include "quiche/quic/core/crypto/quic_random.h"
27 #include "quiche/quic/core/crypto/transport_parameters.h"
28 #include "quiche/quic/core/frames/quic_connection_close_frame.h"
29 #include "quiche/quic/core/http/quic_server_session_base.h"
30 #include "quiche/quic/core/http/quic_spdy_stream.h"
31 #include "quiche/quic/core/quic_config.h"
32 #include "quiche/quic/core/quic_connection.h"
33 #include "quiche/quic/core/quic_connection_id.h"
34 #include "quiche/quic/core/quic_constants.h"
35 #include "quiche/quic/core/quic_crypto_server_stream_base.h"
36 #include "quiche/quic/core/quic_crypto_stream.h"
37 #include "quiche/quic/core/quic_error_codes.h"
38 #include "quiche/quic/core/quic_packet_writer.h"
39 #include "quiche/quic/core/quic_packet_writer_wrapper.h"
40 #include "quiche/quic/core/quic_packets.h"
41 #include "quiche/quic/core/quic_stream.h"
42 #include "quiche/quic/core/quic_time.h"
43 #include "quiche/quic/core/quic_time_wait_list_manager.h"
44 #include "quiche/quic/core/quic_types.h"
45 #include "quiche/quic/core/quic_utils.h"
46 #include "quiche/quic/core/quic_version_manager.h"
47 #include "quiche/quic/core/quic_versions.h"
48 #include "quiche/quic/platform/api/quic_expect_bug.h"
49 #include "quiche/quic/platform/api/quic_flags.h"
50 #include "quiche/quic/platform/api/quic_ip_address.h"
51 #include "quiche/quic/platform/api/quic_logging.h"
52 #include "quiche/quic/platform/api/quic_socket_address.h"
53 #include "quiche/quic/platform/api/quic_test.h"
54 #include "quiche/quic/test_tools/crypto_test_utils.h"
55 #include "quiche/quic/test_tools/first_flight.h"
56 #include "quiche/quic/test_tools/mock_connection_id_generator.h"
57 #include "quiche/quic/test_tools/mock_quic_time_wait_list_manager.h"
58 #include "quiche/quic/test_tools/quic_buffered_packet_store_peer.h"
59 #include "quiche/quic/test_tools/quic_connection_peer.h"
60 #include "quiche/quic/test_tools/quic_dispatcher_peer.h"
61 #include "quiche/quic/test_tools/quic_test_utils.h"
62 #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
63 #include "quiche/common/platform/api/quiche_logging.h"
64 #include "quiche/common/test_tools/quiche_test_utils.h"
65
66 using testing::_;
67 using testing::AllOf;
68 using testing::ByMove;
69 using testing::ElementsAreArray;
70 using testing::Eq;
71 using testing::Field;
72 using testing::InSequence;
73 using testing::Invoke;
74 using testing::IsEmpty;
75 using testing::NiceMock;
76 using testing::Not;
77 using testing::Ref;
78 using testing::Return;
79 using testing::ReturnRef;
80 using testing::WithArg;
81 using testing::WithoutArgs;
82
83 static const size_t kDefaultMaxConnectionsInStore = 100;
84 static const size_t kMaxConnectionsWithoutCHLO =
85 kDefaultMaxConnectionsInStore / 2;
86 static const int16_t kMaxNumSessionsToCreate = 16;
87
88 namespace quic {
89 namespace test {
90 namespace {
91
92 const QuicConnectionId kReturnConnectionId{
93 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}};
94
95 class TestQuicSpdyServerSession : public QuicServerSessionBase {
96 public:
TestQuicSpdyServerSession(const QuicConfig & config,QuicConnection * connection,const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache)97 TestQuicSpdyServerSession(const QuicConfig& config,
98 QuicConnection* connection,
99 const QuicCryptoServerConfig* crypto_config,
100 QuicCompressedCertsCache* compressed_certs_cache)
101 : QuicServerSessionBase(config, CurrentSupportedVersions(), connection,
102 nullptr, nullptr, crypto_config,
103 compressed_certs_cache) {
104 Initialize();
105 }
106 TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
107 TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
108 delete;
109
~TestQuicSpdyServerSession()110 ~TestQuicSpdyServerSession() override { DeleteConnection(); }
111
112 MOCK_METHOD(void, OnConnectionClosed,
113 (const QuicConnectionCloseFrame& frame,
114 ConnectionCloseSource source),
115 (override));
116 MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (QuicStreamId id),
117 (override));
118 MOCK_METHOD(QuicSpdyStream*, CreateIncomingStream, (PendingStream*),
119 (override));
120 MOCK_METHOD(QuicSpdyStream*, CreateOutgoingBidirectionalStream, (),
121 (override));
122 MOCK_METHOD(QuicSpdyStream*, CreateOutgoingUnidirectionalStream, (),
123 (override));
124
CreateQuicCryptoServerStream(const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache)125 std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
126 const QuicCryptoServerConfig* crypto_config,
127 QuicCompressedCertsCache* compressed_certs_cache) override {
128 return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
129 stream_helper());
130 }
131
stream_helper()132 QuicCryptoServerStreamBase::Helper* stream_helper() {
133 return QuicServerSessionBase::stream_helper();
134 }
135 };
136
137 class TestDispatcher : public QuicDispatcher {
138 public:
TestDispatcher(const QuicConfig * config,const QuicCryptoServerConfig * crypto_config,QuicVersionManager * version_manager,QuicRandom * random,ConnectionIdGeneratorInterface & generator)139 TestDispatcher(const QuicConfig* config,
140 const QuicCryptoServerConfig* crypto_config,
141 QuicVersionManager* version_manager, QuicRandom* random,
142 ConnectionIdGeneratorInterface& generator)
143 : QuicDispatcher(config, crypto_config, version_manager,
144 std::make_unique<MockQuicConnectionHelper>(),
145 std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
146 new QuicSimpleCryptoServerStreamHelper()),
147 std::make_unique<TestAlarmFactory>(),
148 kQuicDefaultConnectionIdLength, generator),
149 random_(random) {
150 EXPECT_CALL(*this, ConnectionIdGenerator())
151 .WillRepeatedly(ReturnRef(generator));
152 }
153
154 MOCK_METHOD(std::unique_ptr<QuicSession>, CreateQuicSession,
155 (QuicConnectionId connection_id,
156 const QuicSocketAddress& self_address,
157 const QuicSocketAddress& peer_address, absl::string_view alpn,
158 const ParsedQuicVersion& version,
159 const ParsedClientHello& parsed_chlo,
160 ConnectionIdGeneratorInterface& connection_id_generator),
161 (override));
162 MOCK_METHOD(ConnectionIdGeneratorInterface&, ConnectionIdGenerator, (),
163 (override));
164
165 struct TestQuicPerPacketContext : public QuicPerPacketContext {
166 std::string custom_packet_context;
167 };
168
GetPerPacketContext() const169 std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
170 auto test_context = std::make_unique<TestQuicPerPacketContext>();
171 test_context->custom_packet_context = custom_packet_context_;
172 return std::move(test_context);
173 }
174
RestorePerPacketContext(std::unique_ptr<QuicPerPacketContext> context)175 void RestorePerPacketContext(
176 std::unique_ptr<QuicPerPacketContext> context) override {
177 TestQuicPerPacketContext* test_context =
178 static_cast<TestQuicPerPacketContext*>(context.get());
179 custom_packet_context_ = test_context->custom_packet_context;
180 }
181
182 std::string custom_packet_context_;
183
184 using QuicDispatcher::ConnectionIdGenerator;
185 using QuicDispatcher::MaybeDispatchPacket;
186 using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
187 using QuicDispatcher::writer;
188
189 QuicRandom* random_;
190 };
191
192 // A Connection class which unregisters the session from the dispatcher when
193 // sending connection close.
194 // It'd be slightly more realistic to do this from the Session but it would
195 // involve a lot more mocking.
196 class MockServerConnection : public MockQuicConnection {
197 public:
MockServerConnection(QuicConnectionId connection_id,MockQuicConnectionHelper * helper,MockAlarmFactory * alarm_factory,QuicDispatcher * dispatcher)198 MockServerConnection(QuicConnectionId connection_id,
199 MockQuicConnectionHelper* helper,
200 MockAlarmFactory* alarm_factory,
201 QuicDispatcher* dispatcher)
202 : MockQuicConnection(connection_id, helper, alarm_factory,
203 Perspective::IS_SERVER),
204 dispatcher_(dispatcher),
205 active_connection_ids_({connection_id}) {}
206
AddNewConnectionId(QuicConnectionId id)207 void AddNewConnectionId(QuicConnectionId id) {
208 if (!dispatcher_->TryAddNewConnectionId(active_connection_ids_.back(),
209 id)) {
210 return;
211 }
212 QuicConnectionPeer::SetServerConnectionId(this, id);
213 active_connection_ids_.push_back(id);
214 }
215
UnconditionallyAddNewConnectionIdForTest(QuicConnectionId id)216 void UnconditionallyAddNewConnectionIdForTest(QuicConnectionId id) {
217 dispatcher_->TryAddNewConnectionId(active_connection_ids_.back(), id);
218 active_connection_ids_.push_back(id);
219 }
220
RetireConnectionId(QuicConnectionId id)221 void RetireConnectionId(QuicConnectionId id) {
222 auto it = std::find(active_connection_ids_.begin(),
223 active_connection_ids_.end(), id);
224 QUICHE_DCHECK(it != active_connection_ids_.end());
225 dispatcher_->OnConnectionIdRetired(id);
226 active_connection_ids_.erase(it);
227 }
228
GetActiveServerConnectionIds() const229 std::vector<QuicConnectionId> GetActiveServerConnectionIds() const override {
230 std::vector<QuicConnectionId> result;
231 for (const auto& cid : active_connection_ids_) {
232 result.push_back(cid);
233 }
234 auto original_connection_id = GetOriginalDestinationConnectionId();
235 if (std::find(result.begin(), result.end(), original_connection_id) ==
236 result.end()) {
237 result.push_back(original_connection_id);
238 }
239 return result;
240 }
241
UnregisterOnConnectionClosed()242 void UnregisterOnConnectionClosed() {
243 QUIC_LOG(ERROR) << "Unregistering " << connection_id();
244 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
245 "Unregistering.",
246 ConnectionCloseSource::FROM_SELF);
247 }
248
249 private:
250 QuicDispatcher* dispatcher_;
251 std::vector<QuicConnectionId> active_connection_ids_;
252 };
253
254 class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
255 public:
QuicDispatcherTestBase()256 QuicDispatcherTestBase()
257 : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
258
QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)259 explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
260 : version_(GetParam()),
261 version_manager_(AllSupportedVersions()),
262 crypto_config_(QuicCryptoServerConfig::TESTING,
263 QuicRandom::GetInstance(), std::move(proof_source),
264 KeyExchangeSource::Default()),
265 server_address_(QuicIpAddress::Any4(), 5),
266 dispatcher_(new NiceMock<TestDispatcher>(
267 &config_, &crypto_config_, &version_manager_,
268 mock_helper_.GetRandomGenerator(), connection_id_generator_)),
269 time_wait_list_manager_(nullptr),
270 session1_(nullptr),
271 session2_(nullptr),
272 store_(nullptr),
273 connection_id_(1) {}
274
SetUp()275 void SetUp() override {
276 dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
277 // Set the counter to some value to start with.
278 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
279 dispatcher_.get(), kMaxNumSessionsToCreate);
280 }
281
connection1()282 MockQuicConnection* connection1() {
283 if (session1_ == nullptr) {
284 return nullptr;
285 }
286 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
287 }
288
connection2()289 MockQuicConnection* connection2() {
290 if (session2_ == nullptr) {
291 return nullptr;
292 }
293 return reinterpret_cast<MockQuicConnection*>(session2_->connection());
294 }
295
296 // Process a packet with an 8 byte connection id,
297 // 6 byte packet number, default path id, and packet number 1,
298 // using the version under test.
ProcessPacket(QuicSocketAddress peer_address,QuicConnectionId server_connection_id,bool has_version_flag,const std::string & data)299 void ProcessPacket(QuicSocketAddress peer_address,
300 QuicConnectionId server_connection_id,
301 bool has_version_flag, const std::string& data) {
302 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
303 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
304 }
305
306 // Process a packet with a default path id, and packet number 1,
307 // using the version under test.
ProcessPacket(QuicSocketAddress peer_address,QuicConnectionId server_connection_id,bool has_version_flag,const std::string & data,QuicConnectionIdIncluded server_connection_id_included,QuicPacketNumberLength packet_number_length)308 void ProcessPacket(QuicSocketAddress peer_address,
309 QuicConnectionId server_connection_id,
310 bool has_version_flag, const std::string& data,
311 QuicConnectionIdIncluded server_connection_id_included,
312 QuicPacketNumberLength packet_number_length) {
313 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
314 server_connection_id_included, packet_number_length, 1);
315 }
316
317 // Process a packet using the version under test.
ProcessPacket(QuicSocketAddress peer_address,QuicConnectionId server_connection_id,bool has_version_flag,const std::string & data,QuicConnectionIdIncluded server_connection_id_included,QuicPacketNumberLength packet_number_length,uint64_t packet_number)318 void ProcessPacket(QuicSocketAddress peer_address,
319 QuicConnectionId server_connection_id,
320 bool has_version_flag, const std::string& data,
321 QuicConnectionIdIncluded server_connection_id_included,
322 QuicPacketNumberLength packet_number_length,
323 uint64_t packet_number) {
324 ProcessPacket(peer_address, server_connection_id, has_version_flag,
325 version_, data, true, server_connection_id_included,
326 packet_number_length, packet_number);
327 }
328
329 // Processes a packet.
ProcessPacket(QuicSocketAddress peer_address,QuicConnectionId server_connection_id,bool has_version_flag,ParsedQuicVersion version,const std::string & data,bool full_padding,QuicConnectionIdIncluded server_connection_id_included,QuicPacketNumberLength packet_number_length,uint64_t packet_number)330 void ProcessPacket(QuicSocketAddress peer_address,
331 QuicConnectionId server_connection_id,
332 bool has_version_flag, ParsedQuicVersion version,
333 const std::string& data, bool full_padding,
334 QuicConnectionIdIncluded server_connection_id_included,
335 QuicPacketNumberLength packet_number_length,
336 uint64_t packet_number) {
337 ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
338 has_version_flag, version, data, full_padding,
339 server_connection_id_included, CONNECTION_ID_ABSENT,
340 packet_number_length, packet_number);
341 }
342
343 // Processes a packet.
ProcessPacket(QuicSocketAddress peer_address,QuicConnectionId server_connection_id,QuicConnectionId client_connection_id,bool has_version_flag,ParsedQuicVersion version,const std::string & data,bool full_padding,QuicConnectionIdIncluded server_connection_id_included,QuicConnectionIdIncluded client_connection_id_included,QuicPacketNumberLength packet_number_length,uint64_t packet_number)344 void ProcessPacket(QuicSocketAddress peer_address,
345 QuicConnectionId server_connection_id,
346 QuicConnectionId client_connection_id,
347 bool has_version_flag, ParsedQuicVersion version,
348 const std::string& data, bool full_padding,
349 QuicConnectionIdIncluded server_connection_id_included,
350 QuicConnectionIdIncluded client_connection_id_included,
351 QuicPacketNumberLength packet_number_length,
352 uint64_t packet_number) {
353 ParsedQuicVersionVector versions(SupportedVersions(version));
354 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
355 server_connection_id, client_connection_id, has_version_flag, false,
356 packet_number, data, full_padding, server_connection_id_included,
357 client_connection_id_included, packet_number_length, &versions));
358 std::unique_ptr<QuicReceivedPacket> received_packet(
359 ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
360 // Call ConnectionIdLength if the packet clears the Long Header bit, or
361 // if the test involves sending a connection ID that is too short
362 if (!has_version_flag || !version.AllowsVariableLengthConnectionIds() ||
363 server_connection_id.length() == 0 ||
364 server_connection_id_included == CONNECTION_ID_ABSENT) {
365 // Short headers will ask for the length
366 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(_))
367 .WillRepeatedly(Return(generated_connection_id_.has_value()
368 ? generated_connection_id_->length()
369 : kQuicDefaultConnectionIdLength));
370 }
371 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
372 server_connection_id);
373 }
374
ProcessReceivedPacket(std::unique_ptr<QuicReceivedPacket> received_packet,const QuicSocketAddress & peer_address,const ParsedQuicVersion & version,const QuicConnectionId & server_connection_id)375 void ProcessReceivedPacket(
376 std::unique_ptr<QuicReceivedPacket> received_packet,
377 const QuicSocketAddress& peer_address, const ParsedQuicVersion& version,
378 const QuicConnectionId& server_connection_id) {
379 if (version.UsesQuicCrypto() &&
380 ChloExtractor::Extract(*received_packet, version, {}, nullptr,
381 server_connection_id.length())) {
382 // Add CHLO packet to the beginning to be verified first, because it is
383 // also processed first by new session.
384 data_connection_map_[server_connection_id].push_front(
385 std::string(received_packet->data(), received_packet->length()));
386 } else {
387 // For non-CHLO, always append to last.
388 data_connection_map_[server_connection_id].push_back(
389 std::string(received_packet->data(), received_packet->length()));
390 }
391 dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
392 }
393
ValidatePacket(QuicConnectionId conn_id,const QuicEncryptedPacket & packet)394 void ValidatePacket(QuicConnectionId conn_id,
395 const QuicEncryptedPacket& packet) {
396 EXPECT_EQ(data_connection_map_[conn_id].front().length(),
397 packet.AsStringPiece().length());
398 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
399 data_connection_map_[conn_id].pop_front();
400 }
401
CreateSession(TestDispatcher * dispatcher,const QuicConfig & config,QuicConnectionId connection_id,const QuicSocketAddress &,MockQuicConnectionHelper * helper,MockAlarmFactory * alarm_factory,const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache,TestQuicSpdyServerSession ** session_ptr)402 std::unique_ptr<QuicSession> CreateSession(
403 TestDispatcher* dispatcher, const QuicConfig& config,
404 QuicConnectionId connection_id, const QuicSocketAddress& /*peer_address*/,
405 MockQuicConnectionHelper* helper, MockAlarmFactory* alarm_factory,
406 const QuicCryptoServerConfig* crypto_config,
407 QuicCompressedCertsCache* compressed_certs_cache,
408 TestQuicSpdyServerSession** session_ptr) {
409 MockServerConnection* connection = new MockServerConnection(
410 connection_id, helper, alarm_factory, dispatcher);
411 connection->SetQuicPacketWriter(dispatcher->writer(),
412 /*owns_writer=*/false);
413 auto session = std::make_unique<TestQuicSpdyServerSession>(
414 config, connection, crypto_config, compressed_certs_cache);
415 *session_ptr = session.get();
416 connection->set_visitor(session.get());
417 ON_CALL(*connection, CloseConnection(_, _, _))
418 .WillByDefault(WithoutArgs(Invoke(
419 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
420 return session;
421 }
422
CreateTimeWaitListManager()423 void CreateTimeWaitListManager() {
424 time_wait_list_manager_ = new MockTimeWaitListManager(
425 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
426 mock_helper_.GetClock(), &mock_alarm_factory_);
427 // dispatcher_ takes the ownership of time_wait_list_manager_.
428 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
429 time_wait_list_manager_);
430 }
431
SerializeCHLO()432 std::string SerializeCHLO() {
433 CryptoHandshakeMessage client_hello;
434 client_hello.set_tag(kCHLO);
435 client_hello.SetStringPiece(kALPN, ExpectedAlpn());
436 return std::string(client_hello.GetSerialized().AsStringPiece());
437 }
438
ProcessUndecryptableEarlyPacket(const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)439 void ProcessUndecryptableEarlyPacket(
440 const QuicSocketAddress& peer_address,
441 const QuicConnectionId& server_connection_id) {
442 ProcessUndecryptableEarlyPacket(version_, peer_address,
443 server_connection_id);
444 }
445
ProcessUndecryptableEarlyPacket(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)446 void ProcessUndecryptableEarlyPacket(
447 const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
448 const QuicConnectionId& server_connection_id) {
449 std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
450 GetUndecryptableEarlyPacket(version, server_connection_id);
451 std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
452 *encrypted_packet, mock_helper_.GetClock()->Now()));
453 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
454 server_connection_id);
455 }
456
ProcessFirstFlight(const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)457 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
458 const QuicConnectionId& server_connection_id) {
459 ProcessFirstFlight(version_, peer_address, server_connection_id);
460 }
461
ProcessFirstFlight(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)462 void ProcessFirstFlight(const ParsedQuicVersion& version,
463 const QuicSocketAddress& peer_address,
464 const QuicConnectionId& server_connection_id) {
465 ProcessFirstFlight(version, peer_address, server_connection_id,
466 EmptyQuicConnectionId());
467 }
468
ProcessFirstFlight(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id,const QuicConnectionId & client_connection_id)469 void ProcessFirstFlight(const ParsedQuicVersion& version,
470 const QuicSocketAddress& peer_address,
471 const QuicConnectionId& server_connection_id,
472 const QuicConnectionId& client_connection_id) {
473 ProcessFirstFlight(version, peer_address, server_connection_id,
474 client_connection_id, TestClientCryptoConfig());
475 }
476
ProcessFirstFlight(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id,const QuicConnectionId & client_connection_id,std::unique_ptr<QuicCryptoClientConfig> client_crypto_config)477 void ProcessFirstFlight(
478 const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
479 const QuicConnectionId& server_connection_id,
480 const QuicConnectionId& client_connection_id,
481 std::unique_ptr<QuicCryptoClientConfig> client_crypto_config) {
482 if (expect_generator_is_called_) {
483 if (version.AllowsVariableLengthConnectionIds()) {
484 EXPECT_CALL(connection_id_generator_,
485 MaybeReplaceConnectionId(server_connection_id, version))
486 .WillOnce(Return(generated_connection_id_));
487 } else {
488 EXPECT_CALL(connection_id_generator_,
489 MaybeReplaceConnectionId(server_connection_id, version))
490 .WillOnce(Return(std::nullopt));
491 }
492 }
493 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
494 GetFirstFlightOfPackets(version, DefaultQuicConfig(),
495 server_connection_id, client_connection_id,
496 std::move(client_crypto_config));
497 for (auto&& packet : packets) {
498 ProcessReceivedPacket(std::move(packet), peer_address, version,
499 server_connection_id);
500 }
501 }
502
TestClientCryptoConfig()503 std::unique_ptr<QuicCryptoClientConfig> TestClientCryptoConfig() {
504 auto client_crypto_config = std::make_unique<QuicCryptoClientConfig>(
505 crypto_test_utils::ProofVerifierForTesting());
506 if (address_token_.has_value()) {
507 client_crypto_config->LookupOrCreate(TestServerId())
508 ->set_source_address_token(*address_token_);
509 }
510 return client_crypto_config;
511 }
512
513 // If called, the first flight packets generated in |ProcessFirstFlight| will
514 // contain the given |address_token|.
SetAddressToken(std::string address_token)515 void SetAddressToken(std::string address_token) {
516 address_token_ = std::move(address_token);
517 }
518
ExpectedAlpnForVersion(ParsedQuicVersion version)519 std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
520 return AlpnForVersion(version);
521 }
522
ExpectedAlpn()523 std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
524
MatchParsedClientHello()525 auto MatchParsedClientHello() {
526 if (version_.UsesQuicCrypto()) {
527 return AllOf(
528 Field(&ParsedClientHello::alpns, ElementsAreArray({ExpectedAlpn()})),
529 Field(&ParsedClientHello::sni, Eq(TestHostname())),
530 Field(&ParsedClientHello::supported_groups, IsEmpty()));
531 }
532 return AllOf(
533 Field(&ParsedClientHello::alpns, ElementsAreArray({ExpectedAlpn()})),
534 Field(&ParsedClientHello::sni, Eq(TestHostname())),
535 Field(&ParsedClientHello::supported_groups, Not(IsEmpty())));
536 }
537
MarkSession1Deleted()538 void MarkSession1Deleted() { session1_ = nullptr; }
539
VerifyVersionSupported(ParsedQuicVersion version)540 void VerifyVersionSupported(ParsedQuicVersion version) {
541 expect_generator_is_called_ = true;
542 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
543 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
544 EXPECT_CALL(*dispatcher_,
545 CreateQuicSession(connection_id, _, client_address,
546 Eq(ExpectedAlpnForVersion(version)), _, _, _))
547 .WillOnce(Return(ByMove(CreateSession(
548 dispatcher_.get(), config_, connection_id, client_address,
549 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
550 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
551 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
552 ProcessUdpPacket(_, _, _))
553 .WillOnce(WithArg<2>(
554 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
555 ValidatePacket(connection_id, packet);
556 })));
557 ProcessFirstFlight(version, client_address, connection_id);
558 }
559
VerifyVersionNotSupported(ParsedQuicVersion version)560 void VerifyVersionNotSupported(ParsedQuicVersion version) {
561 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
562 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
563 EXPECT_CALL(*dispatcher_,
564 CreateQuicSession(connection_id, _, client_address, _, _, _, _))
565 .Times(0);
566 expect_generator_is_called_ = false;
567 ProcessFirstFlight(version, client_address, connection_id);
568 }
569
570 void TestTlsMultiPacketClientHello(bool add_reordering,
571 bool long_connection_id);
572
573 void TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
574 const QuicConnectionId& server_connection_id,
575 const QuicConnectionId& client_connection_id);
576
GetClearResetAddressesAlarm()577 TestAlarmFactory::TestAlarm* GetClearResetAddressesAlarm() {
578 return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
579 QuicDispatcherPeer::GetClearResetAddressesAlarm(dispatcher_.get()));
580 }
581
582 ParsedQuicVersion version_;
583 MockQuicConnectionHelper mock_helper_;
584 MockAlarmFactory mock_alarm_factory_;
585 QuicConfig config_;
586 QuicVersionManager version_manager_;
587 QuicCryptoServerConfig crypto_config_;
588 QuicSocketAddress server_address_;
589 // Set to false if the dispatcher won't create a session.
590 bool expect_generator_is_called_ = true;
591 // Set in conditions where the generator should return a different connection
592 // ID.
593 std::optional<QuicConnectionId> generated_connection_id_;
594 MockConnectionIdGenerator connection_id_generator_;
595 std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
596 MockTimeWaitListManager* time_wait_list_manager_;
597 TestQuicSpdyServerSession* session1_;
598 TestQuicSpdyServerSession* session2_;
599 std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
600 QuicBufferedPacketStore* store_;
601 uint64_t connection_id_;
602 std::optional<std::string> address_token_;
603 };
604
605 class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
606 class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
607
608 INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
609 QuicDispatcherTestAllVersions,
610 ::testing::ValuesIn(CurrentSupportedVersions()),
611 ::testing::PrintToStringParamName());
612
613 INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
614 QuicDispatcherTestOneVersion,
615 ::testing::Values(CurrentSupportedVersions().front()),
616 ::testing::PrintToStringParamName());
617
TEST_P(QuicDispatcherTestAllVersions,TlsClientHelloCreatesSession)618 TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
619 if (version_.UsesQuicCrypto()) {
620 return;
621 }
622 SetAddressToken("hsdifghdsaifnasdpfjdsk");
623
624 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
625
626 EXPECT_CALL(
627 *dispatcher_,
628 CreateQuicSession(TestConnectionId(1), _, client_address,
629 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
630 .WillOnce(Return(ByMove(CreateSession(
631 dispatcher_.get(), config_, TestConnectionId(1), client_address,
632 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
633 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
634 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
635 ProcessUdpPacket(_, _, _))
636 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
637 ValidatePacket(TestConnectionId(1), packet);
638 })));
639
640 ProcessFirstFlight(client_address, TestConnectionId(1));
641 }
642
TEST_P(QuicDispatcherTestAllVersions,TlsClientHelloCreatesSessionWithCorrectConnectionIdGenerator)643 TEST_P(QuicDispatcherTestAllVersions,
644 TlsClientHelloCreatesSessionWithCorrectConnectionIdGenerator) {
645 if (version_.UsesQuicCrypto()) {
646 return;
647 }
648 SetAddressToken("hsdifghdsaifnasdpfjdsk");
649
650 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
651 MockConnectionIdGenerator mock_connection_id_generator;
652 EXPECT_CALL(*dispatcher_, ConnectionIdGenerator())
653 .WillRepeatedly(ReturnRef(mock_connection_id_generator));
654 ConnectionIdGeneratorInterface& expected_generator =
655 mock_connection_id_generator;
656 EXPECT_CALL(mock_connection_id_generator,
657 MaybeReplaceConnectionId(TestConnectionId(1), version_))
658 .WillOnce(Return(std::nullopt));
659 EXPECT_CALL(*dispatcher_,
660 CreateQuicSession(TestConnectionId(1), _, client_address,
661 Eq(ExpectedAlpn()), _, MatchParsedClientHello(),
662 Ref(expected_generator)))
663 .WillOnce(Return(ByMove(CreateSession(
664 dispatcher_.get(), config_, TestConnectionId(1), client_address,
665 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
666 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
667 expect_generator_is_called_ = false;
668 ProcessFirstFlight(client_address, TestConnectionId(1));
669 }
670
TEST_P(QuicDispatcherTestAllVersions,VariableServerConnectionIdLength)671 TEST_P(QuicDispatcherTestAllVersions, VariableServerConnectionIdLength) {
672 QuicConnectionId old_id = TestConnectionId(1);
673 // Return a connection ID that is not expected_server_connection_id_length_
674 // bytes long.
675 if (version_.HasIetfQuicFrames()) {
676 generated_connection_id_ =
677 QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
678 0x09, 0x0a, 0x0b});
679 }
680 QuicConnectionId new_id =
681 generated_connection_id_.has_value() ? *generated_connection_id_ : old_id;
682 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
683 EXPECT_CALL(*dispatcher_,
684 CreateQuicSession(new_id, _, client_address, Eq(ExpectedAlpn()),
685 _, MatchParsedClientHello(), _))
686 .WillOnce(Return(ByMove(CreateSession(
687 dispatcher_.get(), config_, new_id, client_address, &mock_helper_,
688 &mock_alarm_factory_, &crypto_config_,
689 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
690 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
691 ProcessUdpPacket(_, _, _))
692 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
693 ValidatePacket(TestConnectionId(1), packet);
694 })));
695 ProcessFirstFlight(client_address, old_id);
696
697 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
698 ProcessUdpPacket(_, _, _))
699 .Times(1);
700 ProcessPacket(client_address, new_id, false, "foo");
701 }
702
TestTlsMultiPacketClientHello(bool add_reordering,bool long_connection_id)703 void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
704 bool add_reordering, bool long_connection_id) {
705 if (!version_.UsesTls()) {
706 return;
707 }
708 SetAddressToken("857293462398");
709
710 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
711 QuicConnectionId original_connection_id, new_connection_id;
712 if (long_connection_id) {
713 original_connection_id = TestConnectionIdNineBytesLong(1);
714 new_connection_id = kReturnConnectionId;
715 EXPECT_CALL(connection_id_generator_,
716 MaybeReplaceConnectionId(original_connection_id, version_))
717 .WillOnce(Return(new_connection_id));
718
719 } else {
720 original_connection_id = TestConnectionId();
721 new_connection_id = original_connection_id;
722 EXPECT_CALL(connection_id_generator_,
723 MaybeReplaceConnectionId(original_connection_id, version_))
724 .WillOnce(Return(std::nullopt));
725 }
726 QuicConfig client_config = DefaultQuicConfig();
727 // Add a 2000-byte custom parameter to increase the length of the CHLO.
728 constexpr auto kCustomParameterId =
729 static_cast<TransportParameters::TransportParameterId>(0xff33);
730 std::string kCustomParameterValue(2000, '-');
731 client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
732 kCustomParameterValue;
733 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
734 GetFirstFlightOfPackets(version_, client_config, original_connection_id,
735 EmptyQuicConnectionId(),
736 TestClientCryptoConfig());
737 ASSERT_EQ(packets.size(), 2u);
738 if (add_reordering) {
739 std::swap(packets[0], packets[1]);
740 }
741
742 // Processing the first packet should not create a new session.
743 ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
744 original_connection_id);
745
746 EXPECT_EQ(dispatcher_->NumSessions(), 0u)
747 << "No session should be created before the rest of the CHLO arrives.";
748
749 // Processing the second packet should create the new session.
750 EXPECT_CALL(
751 *dispatcher_,
752 CreateQuicSession(new_connection_id, _, client_address,
753 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
754 .WillOnce(Return(ByMove(CreateSession(
755 dispatcher_.get(), config_, new_connection_id, client_address,
756 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
757 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
758 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
759 ProcessUdpPacket(_, _, _))
760 .Times(2);
761
762 ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
763 original_connection_id);
764 EXPECT_EQ(dispatcher_->NumSessions(), 1u);
765 }
766
TEST_P(QuicDispatcherTestAllVersions,TlsMultiPacketClientHello)767 TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
768 TestTlsMultiPacketClientHello(/*add_reordering=*/false,
769 /*long_connection_id=*/false);
770 }
771
TEST_P(QuicDispatcherTestAllVersions,TlsMultiPacketClientHelloWithReordering)772 TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
773 TestTlsMultiPacketClientHello(/*add_reordering=*/true,
774 /*long_connection_id=*/false);
775 }
776
TEST_P(QuicDispatcherTestAllVersions,TlsMultiPacketClientHelloWithLongId)777 TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithLongId) {
778 TestTlsMultiPacketClientHello(/*add_reordering=*/false,
779 /*long_connection_id=*/true);
780 }
781
TEST_P(QuicDispatcherTestAllVersions,TlsMultiPacketClientHelloWithReorderingAndLongId)782 TEST_P(QuicDispatcherTestAllVersions,
783 TlsMultiPacketClientHelloWithReorderingAndLongId) {
784 TestTlsMultiPacketClientHello(/*add_reordering=*/true,
785 /*long_connection_id=*/true);
786 }
787
TEST_P(QuicDispatcherTestAllVersions,ProcessPackets)788 TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
789 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
790
791 EXPECT_CALL(
792 *dispatcher_,
793 CreateQuicSession(TestConnectionId(1), _, client_address,
794 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
795 .WillOnce(Return(ByMove(CreateSession(
796 dispatcher_.get(), config_, TestConnectionId(1), client_address,
797 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
798 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
799 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
800 ProcessUdpPacket(_, _, _))
801 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
802 ValidatePacket(TestConnectionId(1), packet);
803 })));
804 ProcessFirstFlight(client_address, TestConnectionId(1));
805
806 EXPECT_CALL(
807 *dispatcher_,
808 CreateQuicSession(TestConnectionId(2), _, client_address,
809 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
810 .WillOnce(Return(ByMove(CreateSession(
811 dispatcher_.get(), config_, TestConnectionId(2), client_address,
812 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
813 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
814 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
815 ProcessUdpPacket(_, _, _))
816 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
817 ValidatePacket(TestConnectionId(2), packet);
818 })));
819 ProcessFirstFlight(client_address, TestConnectionId(2));
820
821 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
822 ProcessUdpPacket(_, _, _))
823 .Times(1)
824 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
825 ValidatePacket(TestConnectionId(1), packet);
826 })));
827 ProcessPacket(client_address, TestConnectionId(1), false, "data");
828 }
829
830 // Regression test of b/93325907.
TEST_P(QuicDispatcherTestAllVersions,DispatcherDoesNotRejectPacketNumberZero)831 TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
832 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
833
834 EXPECT_CALL(*dispatcher_,
835 CreateQuicSession(TestConnectionId(1), _, client_address,
836 Eq(ExpectedAlpn()), _, _, _))
837 .WillOnce(Return(ByMove(CreateSession(
838 dispatcher_.get(), config_, TestConnectionId(1), client_address,
839 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
840 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
841 // Verify both packets 1 and 2 are processed by connection 1.
842 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
843 ProcessUdpPacket(_, _, _))
844 .Times(2)
845 .WillRepeatedly(
846 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
847 ValidatePacket(TestConnectionId(1), packet);
848 })));
849 ProcessFirstFlight(client_address, TestConnectionId(1));
850 // Packet number 256 with packet number length 1 would be considered as 0 in
851 // dispatcher.
852 ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
853 CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
854 }
855
TEST_P(QuicDispatcherTestOneVersion,StatelessVersionNegotiation)856 TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
857 CreateTimeWaitListManager();
858 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
859
860 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
861 EXPECT_CALL(
862 *time_wait_list_manager_,
863 SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
864 .Times(1);
865 expect_generator_is_called_ = false;
866 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
867 TestConnectionId(1));
868 }
869
TEST_P(QuicDispatcherTestOneVersion,StatelessVersionNegotiationWithVeryLongConnectionId)870 TEST_P(QuicDispatcherTestOneVersion,
871 StatelessVersionNegotiationWithVeryLongConnectionId) {
872 QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
873 CreateTimeWaitListManager();
874 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
875
876 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
877 EXPECT_CALL(*time_wait_list_manager_,
878 SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
879 .Times(1);
880 expect_generator_is_called_ = false;
881 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
882 connection_id);
883 }
884
TEST_P(QuicDispatcherTestOneVersion,StatelessVersionNegotiationWithClientConnectionId)885 TEST_P(QuicDispatcherTestOneVersion,
886 StatelessVersionNegotiationWithClientConnectionId) {
887 CreateTimeWaitListManager();
888 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
889
890 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
891 EXPECT_CALL(*time_wait_list_manager_,
892 SendVersionNegotiationPacket(
893 TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
894 .Times(1);
895 expect_generator_is_called_ = false;
896 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
897 TestConnectionId(1), TestConnectionId(2));
898 }
899
TEST_P(QuicDispatcherTestOneVersion,NoVersionNegotiationWithSmallPacket)900 TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
901 CreateTimeWaitListManager();
902 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
903
904 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
905 EXPECT_CALL(*time_wait_list_manager_,
906 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
907 .Times(0);
908 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
909 // Truncate to 1100 bytes of payload which results in a packet just
910 // under 1200 bytes after framing, packet, and encryption overhead.
911 QUICHE_DCHECK_LE(1200u, chlo.length());
912 std::string truncated_chlo = chlo.substr(0, 1100);
913 QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
914 ProcessPacket(client_address, TestConnectionId(1), true,
915 QuicVersionReservedForNegotiation(), truncated_chlo, false,
916 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
917 }
918
919 // Disabling CHLO size validation allows the dispatcher to send version
920 // negotiation packets in response to a CHLO that is otherwise too small.
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationWithoutChloSizeValidation)921 TEST_P(QuicDispatcherTestOneVersion,
922 VersionNegotiationWithoutChloSizeValidation) {
923 crypto_config_.set_validate_chlo_size(false);
924
925 CreateTimeWaitListManager();
926 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
927
928 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
929 EXPECT_CALL(*time_wait_list_manager_,
930 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
931 .Times(1);
932 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
933 // Truncate to 1100 bytes of payload which results in a packet just
934 // under 1200 bytes after framing, packet, and encryption overhead.
935 QUICHE_DCHECK_LE(1200u, chlo.length());
936 std::string truncated_chlo = chlo.substr(0, 1100);
937 QUICHE_DCHECK_EQ(1100u, truncated_chlo.length());
938 ProcessPacket(client_address, TestConnectionId(1), true,
939 QuicVersionReservedForNegotiation(), truncated_chlo, true,
940 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
941 }
942
TEST_P(QuicDispatcherTestAllVersions,Shutdown)943 TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
944 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
945
946 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
947 Eq(ExpectedAlpn()), _, _, _))
948 .WillOnce(Return(ByMove(CreateSession(
949 dispatcher_.get(), config_, TestConnectionId(1), client_address,
950 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
951 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
952 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
953 ProcessUdpPacket(_, _, _))
954 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
955 ValidatePacket(TestConnectionId(1), packet);
956 })));
957
958 ProcessFirstFlight(client_address, TestConnectionId(1));
959
960 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
961 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
962
963 dispatcher_->Shutdown();
964 }
965
TEST_P(QuicDispatcherTestAllVersions,TimeWaitListManager)966 TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
967 CreateTimeWaitListManager();
968
969 // Create a new session.
970 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
971 QuicConnectionId connection_id = TestConnectionId(1);
972 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
973 Eq(ExpectedAlpn()), _, _, _))
974 .WillOnce(Return(ByMove(CreateSession(
975 dispatcher_.get(), config_, connection_id, client_address,
976 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
977 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
978 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
979 ProcessUdpPacket(_, _, _))
980 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
981 ValidatePacket(TestConnectionId(1), packet);
982 })));
983
984 ProcessFirstFlight(client_address, connection_id);
985
986 // Now close the connection, which should add it to the time wait list.
987 session1_->connection()->CloseConnection(
988 QUIC_INVALID_VERSION,
989 "Server: Packet 2 without version flag before version negotiated.",
990 ConnectionCloseBehavior::SILENT_CLOSE);
991 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
992
993 // Dispatcher forwards subsequent packets for this connection_id to the time
994 // wait list manager.
995 EXPECT_CALL(*time_wait_list_manager_,
996 ProcessPacket(_, _, connection_id, _, _, _))
997 .Times(1);
998 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
999 .Times(0);
1000 ProcessPacket(client_address, connection_id, true, "data");
1001 }
1002
TEST_P(QuicDispatcherTestAllVersions,NoVersionPacketToTimeWaitListManager)1003 TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
1004 CreateTimeWaitListManager();
1005
1006 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1007 QuicConnectionId connection_id = TestConnectionId(1);
1008 // Dispatcher forwards all packets for this connection_id to the time wait
1009 // list manager.
1010 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1011 EXPECT_CALL(*time_wait_list_manager_,
1012 ProcessPacket(_, _, connection_id, _, _, _))
1013 .Times(0);
1014 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1015 .Times(0);
1016 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1017 .Times(1);
1018 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1019 "data");
1020 }
1021
TEST_P(QuicDispatcherTestAllVersions,DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion)1022 TEST_P(QuicDispatcherTestAllVersions,
1023 DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
1024 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1025 CreateTimeWaitListManager();
1026
1027 uint8_t short_packet[22] = {0x70, 0xa7, 0x02, 0x6b};
1028 uint8_t valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
1029 size_t short_packet_len = 21;
1030 QuicReceivedPacket packet(reinterpret_cast<char*>(short_packet),
1031 short_packet_len, QuicTime::Zero());
1032 QuicReceivedPacket packet2(reinterpret_cast<char*>(valid_size_packet),
1033 short_packet_len + 1, QuicTime::Zero());
1034 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1035 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1036 .Times(0);
1037 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1038 .Times(0);
1039 // Verify small packet is silently dropped.
1040 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(0xa7))
1041 .WillOnce(Return(kQuicDefaultConnectionIdLength));
1042 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1043 .Times(0);
1044 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1045 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(0xa7))
1046 .WillOnce(Return(kQuicDefaultConnectionIdLength));
1047 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1048 .Times(1);
1049 dispatcher_->ProcessPacket(server_address_, client_address, packet2);
1050 }
1051
TEST_P(QuicDispatcherTestOneVersion,DropPacketWithInvalidFlags)1052 TEST_P(QuicDispatcherTestOneVersion, DropPacketWithInvalidFlags) {
1053 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1054 CreateTimeWaitListManager();
1055 uint8_t all_zero_packet[1200] = {};
1056 QuicReceivedPacket packet(reinterpret_cast<char*>(all_zero_packet),
1057 sizeof(all_zero_packet), QuicTime::Zero());
1058 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1059 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1060 .Times(0);
1061 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1062 .Times(0);
1063 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1064 .Times(0);
1065 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(_))
1066 .WillOnce(Return(kQuicDefaultConnectionIdLength));
1067 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1068 }
1069
TEST_P(QuicDispatcherTestAllVersions,LimitResetsToSameClientAddress)1070 TEST_P(QuicDispatcherTestAllVersions, LimitResetsToSameClientAddress) {
1071 CreateTimeWaitListManager();
1072
1073 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1074 QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
1075 QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
1076 QuicConnectionId connection_id = TestConnectionId(1);
1077
1078 // Verify only one reset is sent to the address, although multiple packets
1079 // are received.
1080 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1081 .Times(1);
1082 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1083 "data");
1084 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1085 "data2");
1086 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1087 "data3");
1088
1089 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1090 .Times(2);
1091 ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
1092 "data");
1093 ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
1094 "data");
1095 }
1096
TEST_P(QuicDispatcherTestAllVersions,StopSendingResetOnTooManyRecentAddresses)1097 TEST_P(QuicDispatcherTestAllVersions,
1098 StopSendingResetOnTooManyRecentAddresses) {
1099 SetQuicFlag(quic_max_recent_stateless_reset_addresses, 2);
1100 const size_t kTestLifeTimeMs = 10;
1101 SetQuicFlag(quic_recent_stateless_reset_addresses_lifetime_ms,
1102 kTestLifeTimeMs);
1103 CreateTimeWaitListManager();
1104
1105 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1106 QuicSocketAddress client_address2(QuicIpAddress::Loopback4(), 2);
1107 QuicSocketAddress client_address3(QuicIpAddress::Loopback6(), 1);
1108 QuicConnectionId connection_id = TestConnectionId(1);
1109
1110 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1111 .Times(2);
1112 EXPECT_FALSE(GetClearResetAddressesAlarm()->IsSet());
1113 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1114 "data");
1115 const QuicTime expected_deadline =
1116 mock_helper_.GetClock()->Now() +
1117 QuicTime::Delta::FromMilliseconds(kTestLifeTimeMs);
1118 ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
1119 EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
1120 // Received no version packet 2 after 5ms.
1121 mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
1122 ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
1123 "data");
1124 ASSERT_TRUE(GetClearResetAddressesAlarm()->IsSet());
1125 // Verify deadline does not change.
1126 EXPECT_EQ(expected_deadline, GetClearResetAddressesAlarm()->deadline());
1127 // Verify reset gets throttled since there are too many recent addresses.
1128 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1129 .Times(0);
1130 ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
1131 "data");
1132
1133 mock_helper_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
1134 GetClearResetAddressesAlarm()->Fire();
1135 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _, _))
1136 .Times(2);
1137 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
1138 "data");
1139 ProcessPacket(client_address2, connection_id, /*has_version_flag=*/false,
1140 "data");
1141 ProcessPacket(client_address3, connection_id, /*has_version_flag=*/false,
1142 "data");
1143 }
1144
1145 // Makes sure nine-byte connection IDs are replaced by 8-byte ones.
TEST_P(QuicDispatcherTestAllVersions,LongConnectionIdLengthReplaced)1146 TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
1147 if (!version_.AllowsVariableLengthConnectionIds()) {
1148 // When variable length connection IDs are not supported, the connection
1149 // fails. See StrayPacketTruncatedConnectionId.
1150 return;
1151 }
1152 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1153
1154 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
1155 generated_connection_id_ = kReturnConnectionId;
1156
1157 EXPECT_CALL(*dispatcher_,
1158 CreateQuicSession(*generated_connection_id_, _, client_address,
1159 Eq(ExpectedAlpn()), _, _, _))
1160 .WillOnce(Return(ByMove(CreateSession(
1161 dispatcher_.get(), config_, *generated_connection_id_, client_address,
1162 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1163 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1164 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1165 ProcessUdpPacket(_, _, _))
1166 .WillOnce(WithArg<2>(
1167 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
1168 ValidatePacket(bad_connection_id, packet);
1169 })));
1170 ProcessFirstFlight(client_address, bad_connection_id);
1171 }
1172
1173 // Makes sure zero-byte connection IDs are replaced by 8-byte ones.
TEST_P(QuicDispatcherTestAllVersions,InvalidShortConnectionIdLengthReplaced)1174 TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
1175 if (!version_.AllowsVariableLengthConnectionIds()) {
1176 // When variable length connection IDs are not supported, the connection
1177 // fails. See StrayPacketTruncatedConnectionId.
1178 return;
1179 }
1180 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1181
1182 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
1183 generated_connection_id_ = kReturnConnectionId;
1184
1185 // Disable validation of invalid short connection IDs.
1186 dispatcher_->SetAllowShortInitialServerConnectionIds(true);
1187 // Note that StrayPacketTruncatedConnectionId covers the case where the
1188 // validation is still enabled.
1189 EXPECT_CALL(*dispatcher_,
1190 CreateQuicSession(*generated_connection_id_, _, client_address,
1191 Eq(ExpectedAlpn()), _, _, _))
1192 .WillOnce(Return(ByMove(CreateSession(
1193 dispatcher_.get(), config_, *generated_connection_id_, client_address,
1194 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1195 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1196 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1197 ProcessUdpPacket(_, _, _))
1198 .WillOnce(WithArg<2>(
1199 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
1200 ValidatePacket(bad_connection_id, packet);
1201 })));
1202 ProcessFirstFlight(client_address, bad_connection_id);
1203 }
1204
1205 // Makes sure TestConnectionId(1) creates a new connection and
1206 // TestConnectionIdNineBytesLong(2) gets replaced.
TEST_P(QuicDispatcherTestAllVersions,MixGoodAndBadConnectionIdLengthPackets)1207 TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
1208 if (!version_.AllowsVariableLengthConnectionIds()) {
1209 return;
1210 }
1211
1212 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1213 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
1214
1215 EXPECT_CALL(*dispatcher_,
1216 CreateQuicSession(TestConnectionId(1), _, client_address,
1217 Eq(ExpectedAlpn()), _, _, _))
1218 .WillOnce(Return(ByMove(CreateSession(
1219 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1220 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1221 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1222 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1223 ProcessUdpPacket(_, _, _))
1224 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1225 ValidatePacket(TestConnectionId(1), packet);
1226 })));
1227 ProcessFirstFlight(client_address, TestConnectionId(1));
1228
1229 generated_connection_id_ = kReturnConnectionId;
1230 EXPECT_CALL(*dispatcher_,
1231 CreateQuicSession(*generated_connection_id_, _, client_address,
1232 Eq(ExpectedAlpn()), _, _, _))
1233 .WillOnce(Return(ByMove(CreateSession(
1234 dispatcher_.get(), config_, *generated_connection_id_, client_address,
1235 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1236 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
1237 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1238 ProcessUdpPacket(_, _, _))
1239 .WillOnce(WithArg<2>(
1240 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
1241 ValidatePacket(bad_connection_id, packet);
1242 })));
1243 ProcessFirstFlight(client_address, bad_connection_id);
1244
1245 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1246 ProcessUdpPacket(_, _, _))
1247 .Times(1)
1248 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1249 ValidatePacket(TestConnectionId(1), packet);
1250 })));
1251 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1252 }
1253
TEST_P(QuicDispatcherTestAllVersions,ProcessPacketWithZeroPort)1254 TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
1255 CreateTimeWaitListManager();
1256
1257 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
1258
1259 // dispatcher_ should drop this packet.
1260 EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
1261 client_address, _, _, _, _))
1262 .Times(0);
1263 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1264 .Times(0);
1265 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1266 .Times(0);
1267 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1268 "data");
1269 }
1270
TEST_P(QuicDispatcherTestAllVersions,ProcessPacketWithBlockedPort)1271 TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithBlockedPort) {
1272 CreateTimeWaitListManager();
1273
1274 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 17);
1275
1276 // dispatcher_ should drop this packet.
1277 EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(1), _,
1278 client_address, _, _, _, _))
1279 .Times(0);
1280 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1281 .Times(0);
1282 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1283 .Times(0);
1284 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1285 "data");
1286 }
1287
TEST_P(QuicDispatcherTestAllVersions,ProcessPacketWithNonBlockedPort)1288 TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithNonBlockedPort) {
1289 CreateTimeWaitListManager();
1290
1291 // Port 443 must not be blocked because it might be useful for proxies to send
1292 // proxied traffic with source port 443 as that allows building a full QUIC
1293 // proxy using a single UDP socket.
1294 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 443);
1295
1296 // dispatcher_ should not drop this packet.
1297 EXPECT_CALL(*dispatcher_,
1298 CreateQuicSession(TestConnectionId(1), _, client_address,
1299 Eq(ExpectedAlpn()), _, _, _))
1300 .WillOnce(Return(ByMove(CreateSession(
1301 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1302 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1303 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1304 ProcessFirstFlight(client_address, TestConnectionId(1));
1305 }
1306
TEST_P(QuicDispatcherTestAllVersions,DropPacketWithKnownVersionAndInvalidShortInitialConnectionId)1307 TEST_P(QuicDispatcherTestAllVersions,
1308 DropPacketWithKnownVersionAndInvalidShortInitialConnectionId) {
1309 if (!version_.AllowsVariableLengthConnectionIds()) {
1310 return;
1311 }
1312 CreateTimeWaitListManager();
1313
1314 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1315
1316 // dispatcher_ should drop this packet.
1317 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(0x00))
1318 .WillOnce(Return(10));
1319 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1320 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1321 .Times(0);
1322 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1323 .Times(0);
1324 expect_generator_is_called_ = false;
1325 ProcessFirstFlight(client_address, EmptyQuicConnectionId());
1326 }
1327
TEST_P(QuicDispatcherTestAllVersions,DropPacketWithKnownVersionAndInvalidInitialConnectionId)1328 TEST_P(QuicDispatcherTestAllVersions,
1329 DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
1330 CreateTimeWaitListManager();
1331
1332 QuicSocketAddress server_address;
1333 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1334
1335 // dispatcher_ should drop this packet with invalid connection ID.
1336 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1337 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1338 .Times(0);
1339 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1340 .Times(0);
1341 absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
1342 QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
1343 QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
1344 ReceivedPacketInfo packet_info(server_address, client_address, packet);
1345 packet_info.version_flag = true;
1346 packet_info.version = version_;
1347 packet_info.destination_connection_id = invalid_connection_id;
1348
1349 ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
1350 }
1351
1352 void QuicDispatcherTestBase::
TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(const QuicConnectionId & server_connection_id,const QuicConnectionId & client_connection_id)1353 TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
1354 const QuicConnectionId& server_connection_id,
1355 const QuicConnectionId& client_connection_id) {
1356 CreateTimeWaitListManager();
1357
1358 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1359
1360 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1361 EXPECT_CALL(*time_wait_list_manager_,
1362 SendVersionNegotiationPacket(
1363 server_connection_id, client_connection_id,
1364 /*ietf_quic=*/true,
1365 /*use_length_prefix=*/true, _, _, client_address, _))
1366 .Times(1);
1367 expect_generator_is_called_ = false;
1368 EXPECT_CALL(connection_id_generator_, ConnectionIdLength(_)).Times(0);
1369 ProcessFirstFlight(ParsedQuicVersion::ReservedForNegotiation(),
1370 client_address, server_connection_id,
1371 client_connection_id);
1372 }
1373
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId)1374 TEST_P(QuicDispatcherTestOneVersion,
1375 VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId) {
1376 TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
1377 EmptyQuicConnectionId(), EmptyQuicConnectionId());
1378 }
1379
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2)1380 TEST_P(QuicDispatcherTestOneVersion,
1381 VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId2) {
1382 char server_connection_id_bytes[3] = {1, 2, 3};
1383 QuicConnectionId server_connection_id(server_connection_id_bytes,
1384 sizeof(server_connection_id_bytes));
1385 TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
1386 server_connection_id, EmptyQuicConnectionId());
1387 }
1388
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3)1389 TEST_P(QuicDispatcherTestOneVersion,
1390 VersionNegotiationForUnknownVersionInvalidShortInitialConnectionId3) {
1391 char client_connection_id_bytes[8] = {1, 2, 3, 4, 5, 6, 7, 8};
1392 QuicConnectionId client_connection_id(client_connection_id_bytes,
1393 sizeof(client_connection_id_bytes));
1394 TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
1395 EmptyQuicConnectionId(), client_connection_id);
1396 }
1397
TEST_P(QuicDispatcherTestOneVersion,VersionsChangeInFlight)1398 TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
1399 VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
1400 for (ParsedQuicVersion version : CurrentSupportedVersions()) {
1401 VerifyVersionSupported(version);
1402 QuicDisableVersion(version);
1403 VerifyVersionNotSupported(version);
1404 QuicEnableVersion(version);
1405 VerifyVersionSupported(version);
1406 }
1407 }
1408
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionDraft28WithVersionNegotiation)1409 TEST_P(QuicDispatcherTestOneVersion,
1410 RejectDeprecatedVersionDraft28WithVersionNegotiation) {
1411 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1412 CreateTimeWaitListManager();
1413 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1414 0xC0, 0xFF, 0x00, 0x00, 28, /*destination connection ID length*/ 0x08};
1415 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1416 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1417 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1418 EXPECT_CALL(
1419 *time_wait_list_manager_,
1420 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1421 /*use_length_prefix=*/true, _, _, _, _))
1422 .Times(1);
1423 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1424 }
1425
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionDraft27WithVersionNegotiation)1426 TEST_P(QuicDispatcherTestOneVersion,
1427 RejectDeprecatedVersionDraft27WithVersionNegotiation) {
1428 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1429 CreateTimeWaitListManager();
1430 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1431 0xC0, 0xFF, 0x00, 0x00, 27, /*destination connection ID length*/ 0x08};
1432 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1433 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1434 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1435 EXPECT_CALL(
1436 *time_wait_list_manager_,
1437 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1438 /*use_length_prefix=*/true, _, _, _, _))
1439 .Times(1);
1440 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1441 }
1442
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionDraft25WithVersionNegotiation)1443 TEST_P(QuicDispatcherTestOneVersion,
1444 RejectDeprecatedVersionDraft25WithVersionNegotiation) {
1445 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1446 CreateTimeWaitListManager();
1447 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1448 0xC0, 0xFF, 0x00, 0x00, 25, /*destination connection ID length*/ 0x08};
1449 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1450 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1451 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1452 EXPECT_CALL(
1453 *time_wait_list_manager_,
1454 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1455 /*use_length_prefix=*/true, _, _, _, _))
1456 .Times(1);
1457 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1458 }
1459
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionT050WithVersionNegotiation)1460 TEST_P(QuicDispatcherTestOneVersion,
1461 RejectDeprecatedVersionT050WithVersionNegotiation) {
1462 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1463 CreateTimeWaitListManager();
1464 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1465 0xC0, 'T', '0', '5', '0', /*destination connection ID length*/ 0x08};
1466 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1467 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1468 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1469 EXPECT_CALL(
1470 *time_wait_list_manager_,
1471 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1472 /*use_length_prefix=*/true, _, _, _, _))
1473 .Times(1);
1474 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1475 }
1476
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ049WithVersionNegotiation)1477 TEST_P(QuicDispatcherTestOneVersion,
1478 RejectDeprecatedVersionQ049WithVersionNegotiation) {
1479 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1480 CreateTimeWaitListManager();
1481 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1482 0xC0, 'Q', '0', '4', '9', /*destination connection ID length*/ 0x08};
1483 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1484 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1485 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1486 EXPECT_CALL(
1487 *time_wait_list_manager_,
1488 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1489 /*use_length_prefix=*/true, _, _, _, _))
1490 .Times(1);
1491 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1492 }
1493
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ048WithVersionNegotiation)1494 TEST_P(QuicDispatcherTestOneVersion,
1495 RejectDeprecatedVersionQ048WithVersionNegotiation) {
1496 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1497 CreateTimeWaitListManager();
1498 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1499 0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
1500 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1501 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1502 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1503 EXPECT_CALL(
1504 *time_wait_list_manager_,
1505 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1506 /*use_length_prefix=*/false, _, _, _, _))
1507 .Times(1);
1508 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1509 }
1510
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ047WithVersionNegotiation)1511 TEST_P(QuicDispatcherTestOneVersion,
1512 RejectDeprecatedVersionQ047WithVersionNegotiation) {
1513 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1514 CreateTimeWaitListManager();
1515 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1516 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
1517 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1518 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1519 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1520 EXPECT_CALL(
1521 *time_wait_list_manager_,
1522 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1523 /*use_length_prefix=*/false, _, _, _, _))
1524 .Times(1);
1525 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1526 }
1527
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ045WithVersionNegotiation)1528 TEST_P(QuicDispatcherTestOneVersion,
1529 RejectDeprecatedVersionQ045WithVersionNegotiation) {
1530 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1531 CreateTimeWaitListManager();
1532 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1533 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
1534 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1535 ABSL_ARRAYSIZE(packet), QuicTime::Zero());
1536 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1537 EXPECT_CALL(
1538 *time_wait_list_manager_,
1539 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1540 /*use_length_prefix=*/false, _, _, _, _))
1541 .Times(1);
1542 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1543 }
1544
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ044WithVersionNegotiation)1545 TEST_P(QuicDispatcherTestOneVersion,
1546 RejectDeprecatedVersionQ044WithVersionNegotiation) {
1547 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1548 CreateTimeWaitListManager();
1549 uint8_t packet44[kMinPacketSizeForVersionNegotiation] = {
1550 0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
1551 QuicReceivedPacket received_packet44(reinterpret_cast<char*>(packet44),
1552 kMinPacketSizeForVersionNegotiation,
1553 QuicTime::Zero());
1554 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1555 EXPECT_CALL(
1556 *time_wait_list_manager_,
1557 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1558 /*use_length_prefix=*/false, _, _, _, _))
1559 .Times(1);
1560 dispatcher_->ProcessPacket(server_address_, client_address,
1561 received_packet44);
1562 }
1563
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionQ050WithVersionNegotiation)1564 TEST_P(QuicDispatcherTestOneVersion,
1565 RejectDeprecatedVersionQ050WithVersionNegotiation) {
1566 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1567 CreateTimeWaitListManager();
1568 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1569 0xFF, 'Q', '0', '5', '0', /*connection ID length byte*/ 0x50};
1570 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1571 kMinPacketSizeForVersionNegotiation,
1572 QuicTime::Zero());
1573 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1574 EXPECT_CALL(
1575 *time_wait_list_manager_,
1576 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1577 /*use_length_prefix=*/true, _, _, _, _))
1578 .Times(1);
1579 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1580 }
1581
TEST_P(QuicDispatcherTestOneVersion,RejectDeprecatedVersionT051WithVersionNegotiation)1582 TEST_P(QuicDispatcherTestOneVersion,
1583 RejectDeprecatedVersionT051WithVersionNegotiation) {
1584 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1585 CreateTimeWaitListManager();
1586 uint8_t packet[kMinPacketSizeForVersionNegotiation] = {
1587 0xFF, 'T', '0', '5', '1', /*destination connection ID length*/ 0x08};
1588 QuicReceivedPacket received_packet(reinterpret_cast<char*>(packet),
1589 kMinPacketSizeForVersionNegotiation,
1590 QuicTime::Zero());
1591 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1592 EXPECT_CALL(
1593 *time_wait_list_manager_,
1594 SendVersionNegotiationPacket(_, _, /*ietf_quic=*/true,
1595 /*use_length_prefix=*/true, _, _, _, _))
1596 .Times(1);
1597 dispatcher_->ProcessPacket(server_address_, client_address, received_packet);
1598 }
1599
1600 static_assert(quic::SupportedVersions().size() == 4u,
1601 "Please add new RejectDeprecatedVersion tests above this assert "
1602 "when deprecating versions");
1603
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationProbe)1604 TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
1605 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1606 CreateTimeWaitListManager();
1607 char packet[1200];
1608 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1609 0x6c, 0x7a, 0x20, 0x21};
1610 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1611 packet, sizeof(packet), destination_connection_id_bytes,
1612 sizeof(destination_connection_id_bytes)));
1613 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1614 std::unique_ptr<QuicReceivedPacket> received_packet(
1615 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1616 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1617 QuicConnectionId server_connection_id(
1618 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1619 EXPECT_CALL(*time_wait_list_manager_,
1620 SendVersionNegotiationPacket(
1621 server_connection_id, client_connection_id,
1622 /*ietf_quic=*/true, /*use_length_prefix=*/true, _, _, _, _))
1623 .Times(1);
1624 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1625
1626 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1627 }
1628
1629 // Testing packet writer that saves all packets instead of sending them.
1630 // Useful for tests that need access to sent packets.
1631 class SavingWriter : public QuicPacketWriterWrapper {
1632 public:
IsWriteBlocked() const1633 bool IsWriteBlocked() const override { return false; }
1634
WritePacket(const char * buffer,size_t buf_len,const QuicIpAddress &,const QuicSocketAddress &,PerPacketOptions *,const QuicPacketWriterParams &)1635 WriteResult WritePacket(const char* buffer, size_t buf_len,
1636 const QuicIpAddress& /*self_client_address*/,
1637 const QuicSocketAddress& /*peer_client_address*/,
1638 PerPacketOptions* /*options*/,
1639 const QuicPacketWriterParams& /*params*/) override {
1640 packets_.push_back(
1641 QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
1642 return WriteResult(WRITE_STATUS_OK, buf_len);
1643 }
1644
packets()1645 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
1646 return &packets_;
1647 }
1648
1649 private:
1650 std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
1651 };
1652
TEST_P(QuicDispatcherTestOneVersion,VersionNegotiationProbeEndToEnd)1653 TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
1654 SavingWriter* saving_writer = new SavingWriter();
1655 // dispatcher_ takes ownership of saving_writer.
1656 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1657
1658 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1659 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1660 &mock_alarm_factory_);
1661 // dispatcher_ takes ownership of time_wait_list_manager.
1662 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1663 time_wait_list_manager);
1664 char packet[1200] = {};
1665 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1666 0x6c, 0x7a, 0x20, 0x21};
1667 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1668 packet, sizeof(packet), destination_connection_id_bytes,
1669 sizeof(destination_connection_id_bytes)));
1670 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1671 std::unique_ptr<QuicReceivedPacket> received_packet(
1672 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1673 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1674
1675 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1676 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1677 ASSERT_EQ(1u, saving_writer->packets()->size());
1678
1679 char source_connection_id_bytes[255] = {};
1680 uint8_t source_connection_id_length = sizeof(source_connection_id_bytes);
1681 std::string detailed_error = "foobar";
1682 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1683 (*(saving_writer->packets()))[0]->data(),
1684 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1685 &source_connection_id_length, &detailed_error));
1686 EXPECT_EQ("", detailed_error);
1687
1688 // The source connection ID of the probe response should match the
1689 // destination connection ID of the probe request.
1690 quiche::test::CompareCharArraysWithHexError(
1691 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1692 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1693 }
1694
TEST_P(QuicDispatcherTestOneVersion,AndroidConformanceTest)1695 TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
1696 // WARNING: do not remove or modify this test without making sure that we
1697 // still have adequate coverage for the Android conformance test.
1698 SavingWriter* saving_writer = new SavingWriter();
1699 // dispatcher_ takes ownership of saving_writer.
1700 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1701
1702 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1703 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1704 &mock_alarm_factory_);
1705 // dispatcher_ takes ownership of time_wait_list_manager.
1706 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1707 time_wait_list_manager);
1708 // clang-format off
1709 static const unsigned char packet[1200] = {
1710 // Android UDP network conformance test packet as it was after this change:
1711 // https://android-review.googlesource.com/c/platform/cts/+/1454515
1712 0xc0, // long header
1713 0xaa, 0xda, 0xca, 0xca, // reserved-space version number
1714 0x08, // destination connection ID length
1715 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
1716 0x00, // source connection ID length
1717 };
1718 // clang-format on
1719
1720 QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
1721 sizeof(packet), false);
1722 std::unique_ptr<QuicReceivedPacket> received_packet(
1723 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1724 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1725
1726 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1727 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1728 ASSERT_EQ(1u, saving_writer->packets()->size());
1729
1730 // The Android UDP network conformance test directly checks that these bytes
1731 // of the response match the connection ID that was sent.
1732 ASSERT_GE((*(saving_writer->packets()))[0]->length(), 15u);
1733 quiche::test::CompareCharArraysWithHexError(
1734 "response connection ID", &(*(saving_writer->packets()))[0]->data()[7], 8,
1735 reinterpret_cast<const char*>(&packet[6]), 8);
1736 }
1737
TEST_P(QuicDispatcherTestOneVersion,AndroidConformanceTestOld)1738 TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTestOld) {
1739 // WARNING: this test covers an old Android Conformance Test that has now been
1740 // changed, but it'll take time for the change to propagate through the
1741 // Android ecosystem. The Android team has asked us to keep this test
1742 // supported until at least 2021-03-31. After that date, and when we drop
1743 // support for sending QUIC version negotiation packets using the legacy
1744 // Google QUIC format (Q001-Q043), then we can delete this test.
1745 // TODO(dschinazi) delete this test after 2021-03-31
1746 SavingWriter* saving_writer = new SavingWriter();
1747 // dispatcher_ takes ownership of saving_writer.
1748 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1749
1750 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1751 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1752 &mock_alarm_factory_);
1753 // dispatcher_ takes ownership of time_wait_list_manager.
1754 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1755 time_wait_list_manager);
1756 // clang-format off
1757 static const unsigned char packet[1200] = {
1758 // Android UDP network conformance test packet as it was after this change:
1759 // https://android-review.googlesource.com/c/platform/cts/+/1104285
1760 // but before this change:
1761 // https://android-review.googlesource.com/c/platform/cts/+/1454515
1762 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number
1763 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
1764 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number
1765 0x01, // 1-byte packet number
1766 0x00, // private flags
1767 0x07, // PING frame
1768 };
1769 // clang-format on
1770
1771 QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
1772 sizeof(packet), false);
1773 std::unique_ptr<QuicReceivedPacket> received_packet(
1774 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1775 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1776
1777 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1778 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1779 ASSERT_EQ(1u, saving_writer->packets()->size());
1780
1781 // The Android UDP network conformance test directly checks that bytes 1-9
1782 // of the response match the connection ID that was sent.
1783 static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
1784 0x75, 0x76, 0x77, 0x78};
1785 ASSERT_GE((*(saving_writer->packets()))[0]->length(),
1786 1u + sizeof(connection_id_bytes));
1787 quiche::test::CompareCharArraysWithHexError(
1788 "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
1789 sizeof(connection_id_bytes), connection_id_bytes,
1790 sizeof(connection_id_bytes));
1791 }
1792
TEST_P(QuicDispatcherTestAllVersions,DoNotProcessSmallPacket)1793 TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
1794 CreateTimeWaitListManager();
1795 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1796
1797 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1798 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
1799 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1800 .Times(0);
1801 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1802 version_, SerializeCHLO(), /*full_padding=*/false,
1803 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
1804 }
1805
TEST_P(QuicDispatcherTestAllVersions,ProcessSmallCoalescedPacket)1806 TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
1807 CreateTimeWaitListManager();
1808 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1809
1810 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
1811
1812 // clang-format off
1813 uint8_t coalesced_packet[1200] = {
1814 // first coalesced packet
1815 // public flags (long header with packet type INITIAL and
1816 // 4-byte packet number)
1817 0xC3,
1818 // version
1819 'Q', '0', '9', '9',
1820 // destination connection ID length
1821 0x08,
1822 // destination connection ID
1823 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1824 // source connection ID length
1825 0x00,
1826 // long header packet length
1827 0x05,
1828 // packet number
1829 0x12, 0x34, 0x56, 0x78,
1830 // Padding
1831 0x00,
1832 // second coalesced packet
1833 // public flags (long header with packet type ZERO_RTT_PROTECTED and
1834 // 4-byte packet number)
1835 0xC3,
1836 // version
1837 'Q', '0', '9', '9',
1838 // destination connection ID length
1839 0x08,
1840 // destination connection ID
1841 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1842 // source connection ID length
1843 0x00,
1844 // long header packet length
1845 0x1E,
1846 // packet number
1847 0x12, 0x34, 0x56, 0x79,
1848 };
1849 // clang-format on
1850 QuicReceivedPacket packet(reinterpret_cast<char*>(coalesced_packet), 1200,
1851 QuicTime::Zero());
1852 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1853 }
1854
TEST_P(QuicDispatcherTestAllVersions,StopAcceptingNewConnections)1855 TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
1856 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1857
1858 EXPECT_CALL(*dispatcher_,
1859 CreateQuicSession(TestConnectionId(1), _, client_address,
1860 Eq(ExpectedAlpn()), _, _, _))
1861 .WillOnce(Return(ByMove(CreateSession(
1862 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1863 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1864 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1865 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1866 ProcessUdpPacket(_, _, _))
1867 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1868 ValidatePacket(TestConnectionId(1), packet);
1869 })));
1870 ProcessFirstFlight(client_address, TestConnectionId(1));
1871
1872 dispatcher_->StopAcceptingNewConnections();
1873 EXPECT_FALSE(dispatcher_->accept_new_connections());
1874
1875 // No more new connections afterwards.
1876 EXPECT_CALL(*dispatcher_,
1877 CreateQuicSession(TestConnectionId(2), _, client_address,
1878 Eq(ExpectedAlpn()), _, _, _))
1879 .Times(0u);
1880 expect_generator_is_called_ = false;
1881 ProcessFirstFlight(client_address, TestConnectionId(2));
1882
1883 // Existing connections should be able to continue.
1884 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1885 ProcessUdpPacket(_, _, _))
1886 .Times(1u)
1887 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1888 ValidatePacket(TestConnectionId(1), packet);
1889 })));
1890 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1891 }
1892
TEST_P(QuicDispatcherTestAllVersions,StartAcceptingNewConnections)1893 TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
1894 dispatcher_->StopAcceptingNewConnections();
1895 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1896
1897 // No more new connections afterwards.
1898 EXPECT_CALL(*dispatcher_,
1899 CreateQuicSession(TestConnectionId(2), _, client_address,
1900 Eq(ExpectedAlpn()), _, _, _))
1901 .Times(0u);
1902 expect_generator_is_called_ = false;
1903 ProcessFirstFlight(client_address, TestConnectionId(2));
1904
1905 dispatcher_->StartAcceptingNewConnections();
1906 EXPECT_TRUE(dispatcher_->accept_new_connections());
1907
1908 expect_generator_is_called_ = true;
1909 EXPECT_CALL(*dispatcher_,
1910 CreateQuicSession(TestConnectionId(1), _, client_address,
1911 Eq(ExpectedAlpn()), _, _, _))
1912 .WillOnce(Return(ByMove(CreateSession(
1913 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1914 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1915 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1916 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1917 ProcessUdpPacket(_, _, _))
1918 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1919 ValidatePacket(TestConnectionId(1), packet);
1920 })));
1921 ProcessFirstFlight(client_address, TestConnectionId(1));
1922 }
1923
TEST_P(QuicDispatcherTestOneVersion,SelectAlpn)1924 TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
1925 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
1926 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
1927 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
1928 // Q033 is no longer supported but Q046 is.
1929 QuicEnableVersion(ParsedQuicVersion::Q046());
1930 EXPECT_EQ(
1931 QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q046"}),
1932 "h3-Q046");
1933 }
1934
1935 // Verify the stopgap test: Packets with truncated connection IDs should be
1936 // dropped.
1937 class QuicDispatcherTestStrayPacketConnectionId
1938 : public QuicDispatcherTestBase {};
1939
1940 INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
1941 QuicDispatcherTestStrayPacketConnectionId,
1942 ::testing::ValuesIn(CurrentSupportedVersions()),
1943 ::testing::PrintToStringParamName());
1944
1945 // Packets with truncated connection IDs should be dropped.
TEST_P(QuicDispatcherTestStrayPacketConnectionId,StrayPacketTruncatedConnectionId)1946 TEST_P(QuicDispatcherTestStrayPacketConnectionId,
1947 StrayPacketTruncatedConnectionId) {
1948 CreateTimeWaitListManager();
1949
1950 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1951 QuicConnectionId connection_id = TestConnectionId(1);
1952 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _, _)).Times(0);
1953 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
1954 .Times(0);
1955 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _))
1956 .Times(0);
1957
1958 ProcessPacket(client_address, connection_id, true, "data",
1959 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1960 }
1961
1962 class BlockingWriter : public QuicPacketWriterWrapper {
1963 public:
BlockingWriter()1964 BlockingWriter() : write_blocked_(false) {}
1965
IsWriteBlocked() const1966 bool IsWriteBlocked() const override { return write_blocked_; }
SetWritable()1967 void SetWritable() override { write_blocked_ = false; }
1968
WritePacket(const char *,size_t,const QuicIpAddress &,const QuicSocketAddress &,PerPacketOptions *,const QuicPacketWriterParams &)1969 WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
1970 const QuicIpAddress& /*self_client_address*/,
1971 const QuicSocketAddress& /*peer_client_address*/,
1972 PerPacketOptions* /*options*/,
1973 const QuicPacketWriterParams& /*params*/) override {
1974 // It would be quite possible to actually implement this method here with
1975 // the fake blocked status, but it would be significantly more work in
1976 // Chromium, and since it's not called anyway, don't bother.
1977 QUIC_LOG(DFATAL) << "Not supported";
1978 return WriteResult();
1979 }
1980
1981 bool write_blocked_;
1982 };
1983
1984 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
1985 public:
SetUp()1986 void SetUp() override {
1987 QuicDispatcherTestBase::SetUp();
1988 writer_ = new BlockingWriter;
1989 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1990
1991 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1992
1993 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
1994 Eq(ExpectedAlpn()), _, _, _))
1995 .WillOnce(Return(ByMove(CreateSession(
1996 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1997 &helper_, &alarm_factory_, &crypto_config_,
1998 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1999 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2000 ProcessUdpPacket(_, _, _))
2001 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
2002 ValidatePacket(TestConnectionId(1), packet);
2003 })));
2004 ProcessFirstFlight(client_address, TestConnectionId(1));
2005
2006 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
2007 Eq(ExpectedAlpn()), _, _, _))
2008 .WillOnce(Return(ByMove(CreateSession(
2009 dispatcher_.get(), config_, TestConnectionId(2), client_address,
2010 &helper_, &alarm_factory_, &crypto_config_,
2011 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
2012 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
2013 ProcessUdpPacket(_, _, _))
2014 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
2015 ValidatePacket(TestConnectionId(2), packet);
2016 })));
2017 ProcessFirstFlight(client_address, TestConnectionId(2));
2018
2019 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
2020 }
2021
TearDown()2022 void TearDown() override {
2023 if (connection1() != nullptr) {
2024 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2025 }
2026
2027 if (connection2() != nullptr) {
2028 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2029 }
2030 dispatcher_->Shutdown();
2031 }
2032
2033 // Set the dispatcher's writer to be blocked. By default, all connections use
2034 // the same writer as the dispatcher in this test.
SetBlocked()2035 void SetBlocked() {
2036 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
2037 writer_->write_blocked_ = true;
2038 }
2039
2040 // Simulate what happens when connection1 gets blocked when writing.
BlockConnection1()2041 void BlockConnection1() {
2042 Connection1Writer()->write_blocked_ = true;
2043 dispatcher_->OnWriteBlocked(connection1());
2044 }
2045
Connection1Writer()2046 BlockingWriter* Connection1Writer() {
2047 return static_cast<BlockingWriter*>(connection1()->writer());
2048 }
2049
2050 // Simulate what happens when connection2 gets blocked when writing.
BlockConnection2()2051 void BlockConnection2() {
2052 Connection2Writer()->write_blocked_ = true;
2053 dispatcher_->OnWriteBlocked(connection2());
2054 }
2055
Connection2Writer()2056 BlockingWriter* Connection2Writer() {
2057 return static_cast<BlockingWriter*>(connection2()->writer());
2058 }
2059
2060 protected:
2061 MockQuicConnectionHelper helper_;
2062 MockAlarmFactory alarm_factory_;
2063 BlockingWriter* writer_;
2064 QuicDispatcher::WriteBlockedList* blocked_list_;
2065 };
2066
2067 INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
2068 QuicDispatcherWriteBlockedListTest,
2069 ::testing::Values(CurrentSupportedVersions().front()),
2070 ::testing::PrintToStringParamName());
2071
TEST_P(QuicDispatcherWriteBlockedListTest,BasicOnCanWrite)2072 TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
2073 // No OnCanWrite calls because no connections are blocked.
2074 dispatcher_->OnCanWrite();
2075
2076 // Register connection 1 for events, and make sure it's notified.
2077 SetBlocked();
2078 dispatcher_->OnWriteBlocked(connection1());
2079 EXPECT_CALL(*connection1(), OnCanWrite());
2080 dispatcher_->OnCanWrite();
2081
2082 // It should get only one notification.
2083 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
2084 dispatcher_->OnCanWrite();
2085 EXPECT_FALSE(dispatcher_->HasPendingWrites());
2086 }
2087
TEST_P(QuicDispatcherWriteBlockedListTest,OnCanWriteOrder)2088 TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
2089 // Make sure we handle events in order.
2090 InSequence s;
2091 SetBlocked();
2092 dispatcher_->OnWriteBlocked(connection1());
2093 dispatcher_->OnWriteBlocked(connection2());
2094 EXPECT_CALL(*connection1(), OnCanWrite());
2095 EXPECT_CALL(*connection2(), OnCanWrite());
2096 dispatcher_->OnCanWrite();
2097
2098 // Check the other ordering.
2099 SetBlocked();
2100 dispatcher_->OnWriteBlocked(connection2());
2101 dispatcher_->OnWriteBlocked(connection1());
2102 EXPECT_CALL(*connection2(), OnCanWrite());
2103 EXPECT_CALL(*connection1(), OnCanWrite());
2104 dispatcher_->OnCanWrite();
2105 }
2106
TEST_P(QuicDispatcherWriteBlockedListTest,OnCanWriteRemove)2107 TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
2108 // Add and remove one connction.
2109 SetBlocked();
2110 dispatcher_->OnWriteBlocked(connection1());
2111 blocked_list_->erase(connection1());
2112 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
2113 dispatcher_->OnCanWrite();
2114
2115 // Add and remove one connction and make sure it doesn't affect others.
2116 SetBlocked();
2117 dispatcher_->OnWriteBlocked(connection1());
2118 dispatcher_->OnWriteBlocked(connection2());
2119 blocked_list_->erase(connection1());
2120 EXPECT_CALL(*connection2(), OnCanWrite());
2121 dispatcher_->OnCanWrite();
2122
2123 // Add it, remove it, and add it back and make sure things are OK.
2124 SetBlocked();
2125 dispatcher_->OnWriteBlocked(connection1());
2126 blocked_list_->erase(connection1());
2127 dispatcher_->OnWriteBlocked(connection1());
2128 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
2129 dispatcher_->OnCanWrite();
2130 }
2131
TEST_P(QuicDispatcherWriteBlockedListTest,DoubleAdd)2132 TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
2133 // Make sure a double add does not necessitate a double remove.
2134 SetBlocked();
2135 dispatcher_->OnWriteBlocked(connection1());
2136 dispatcher_->OnWriteBlocked(connection1());
2137 blocked_list_->erase(connection1());
2138 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
2139 dispatcher_->OnCanWrite();
2140
2141 // Make sure a double add does not result in two OnCanWrite calls.
2142 SetBlocked();
2143 dispatcher_->OnWriteBlocked(connection1());
2144 dispatcher_->OnWriteBlocked(connection1());
2145 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
2146 dispatcher_->OnCanWrite();
2147 }
2148
TEST_P(QuicDispatcherWriteBlockedListTest,OnCanWriteHandleBlockConnection1)2149 TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
2150 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
2151 // into the write blocked list.
2152 InSequence s;
2153 SetBlocked();
2154 dispatcher_->OnWriteBlocked(connection1());
2155 dispatcher_->OnWriteBlocked(connection2());
2156 EXPECT_CALL(*connection1(), OnCanWrite())
2157 .WillOnce(
2158 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
2159 EXPECT_CALL(*connection2(), OnCanWrite());
2160 dispatcher_->OnCanWrite();
2161
2162 // connection1 should be still in the write blocked list.
2163 EXPECT_TRUE(dispatcher_->HasPendingWrites());
2164
2165 // Now call OnCanWrite again, connection1 should get its second chance.
2166 EXPECT_CALL(*connection1(), OnCanWrite());
2167 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
2168 dispatcher_->OnCanWrite();
2169 EXPECT_FALSE(dispatcher_->HasPendingWrites());
2170 }
2171
TEST_P(QuicDispatcherWriteBlockedListTest,OnCanWriteHandleBlockConnection2)2172 TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
2173 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
2174 // into the write blocked list.
2175 InSequence s;
2176 SetBlocked();
2177 dispatcher_->OnWriteBlocked(connection1());
2178 dispatcher_->OnWriteBlocked(connection2());
2179 EXPECT_CALL(*connection1(), OnCanWrite());
2180 EXPECT_CALL(*connection2(), OnCanWrite())
2181 .WillOnce(
2182 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
2183 dispatcher_->OnCanWrite();
2184
2185 // connection2 should be still in the write blocked list.
2186 EXPECT_TRUE(dispatcher_->HasPendingWrites());
2187
2188 // Now call OnCanWrite again, connection2 should get its second chance.
2189 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
2190 EXPECT_CALL(*connection2(), OnCanWrite());
2191 dispatcher_->OnCanWrite();
2192 EXPECT_FALSE(dispatcher_->HasPendingWrites());
2193 }
2194
TEST_P(QuicDispatcherWriteBlockedListTest,OnCanWriteHandleBlockBothConnections)2195 TEST_P(QuicDispatcherWriteBlockedListTest,
2196 OnCanWriteHandleBlockBothConnections) {
2197 // Both connections get blocked in OnCanWrite, and added back into the write
2198 // blocked list.
2199 InSequence s;
2200 SetBlocked();
2201 dispatcher_->OnWriteBlocked(connection1());
2202 dispatcher_->OnWriteBlocked(connection2());
2203 EXPECT_CALL(*connection1(), OnCanWrite())
2204 .WillOnce(
2205 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
2206 EXPECT_CALL(*connection2(), OnCanWrite())
2207 .WillOnce(
2208 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
2209 dispatcher_->OnCanWrite();
2210
2211 // Both connections should be still in the write blocked list.
2212 EXPECT_TRUE(dispatcher_->HasPendingWrites());
2213
2214 // Now call OnCanWrite again, both connections should get its second chance.
2215 EXPECT_CALL(*connection1(), OnCanWrite());
2216 EXPECT_CALL(*connection2(), OnCanWrite());
2217 dispatcher_->OnCanWrite();
2218 EXPECT_FALSE(dispatcher_->HasPendingWrites());
2219 }
2220
TEST_P(QuicDispatcherWriteBlockedListTest,PerConnectionWriterBlocked)2221 TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
2222 // By default, all connections share the same packet writer with the
2223 // dispatcher.
2224 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
2225 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
2226
2227 // Test the case where connection1 shares the same packet writer as the
2228 // dispatcher, whereas connection2 owns it's packet writer.
2229 // Change connection2's writer.
2230 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
2231 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
2232
2233 BlockConnection2();
2234 EXPECT_TRUE(dispatcher_->HasPendingWrites());
2235
2236 EXPECT_CALL(*connection2(), OnCanWrite());
2237 dispatcher_->OnCanWrite();
2238 EXPECT_FALSE(dispatcher_->HasPendingWrites());
2239 }
2240
TEST_P(QuicDispatcherWriteBlockedListTest,RemoveConnectionFromWriteBlockedListWhenDeletingSessions)2241 TEST_P(QuicDispatcherWriteBlockedListTest,
2242 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
2243 EXPECT_QUIC_BUG(
2244 {
2245 dispatcher_->OnConnectionClosed(
2246 connection1()->connection_id(), QUIC_PACKET_WRITE_ERROR,
2247 "Closed by test.", ConnectionCloseSource::FROM_SELF);
2248
2249 SetBlocked();
2250
2251 ASSERT_FALSE(dispatcher_->HasPendingWrites());
2252 SetBlocked();
2253 dispatcher_->OnWriteBlocked(connection1());
2254 ASSERT_TRUE(dispatcher_->HasPendingWrites());
2255
2256 dispatcher_->DeleteSessions();
2257 MarkSession1Deleted();
2258 },
2259 "QuicConnection was in WriteBlockedList before destruction");
2260 }
2261
2262 class QuicDispatcherSupportMultipleConnectionIdPerConnectionTest
2263 : public QuicDispatcherTestBase {
2264 public:
QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()2265 QuicDispatcherSupportMultipleConnectionIdPerConnectionTest()
2266 : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {
2267 dispatcher_ = std::make_unique<NiceMock<TestDispatcher>>(
2268 &config_, &crypto_config_, &version_manager_,
2269 mock_helper_.GetRandomGenerator(), connection_id_generator_);
2270 }
AddConnection1()2271 void AddConnection1() {
2272 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
2273 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
2274 Eq(ExpectedAlpn()), _, _, _))
2275 .WillOnce(Return(ByMove(CreateSession(
2276 dispatcher_.get(), config_, TestConnectionId(1), client_address,
2277 &helper_, &alarm_factory_, &crypto_config_,
2278 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2279 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2280 ProcessUdpPacket(_, _, _))
2281 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
2282 ValidatePacket(TestConnectionId(1), packet);
2283 })));
2284 ProcessFirstFlight(client_address, TestConnectionId(1));
2285 }
2286
AddConnection2()2287 void AddConnection2() {
2288 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 2);
2289 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address,
2290 Eq(ExpectedAlpn()), _, _, _))
2291 .WillOnce(Return(ByMove(CreateSession(
2292 dispatcher_.get(), config_, TestConnectionId(2), client_address,
2293 &helper_, &alarm_factory_, &crypto_config_,
2294 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
2295 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
2296 ProcessUdpPacket(_, _, _))
2297 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
2298 ValidatePacket(TestConnectionId(2), packet);
2299 })));
2300 ProcessFirstFlight(client_address, TestConnectionId(2));
2301 }
2302
2303 protected:
2304 MockQuicConnectionHelper helper_;
2305 MockAlarmFactory alarm_factory_;
2306 };
2307
2308 INSTANTIATE_TEST_SUITE_P(
2309 QuicDispatcherSupportMultipleConnectionIdPerConnectionTests,
2310 QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2311 ::testing::Values(CurrentSupportedVersions().front()),
2312 ::testing::PrintToStringParamName());
2313
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,FailToAddExistingConnectionId)2314 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2315 FailToAddExistingConnectionId) {
2316 AddConnection1();
2317 EXPECT_FALSE(dispatcher_->TryAddNewConnectionId(TestConnectionId(1),
2318 TestConnectionId(1)));
2319 }
2320
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,TryAddNewConnectionId)2321 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2322 TryAddNewConnectionId) {
2323 AddConnection1();
2324 ASSERT_EQ(dispatcher_->NumSessions(), 1u);
2325 ASSERT_THAT(session1_, testing::NotNull());
2326 MockServerConnection* mock_server_connection1 =
2327 reinterpret_cast<MockServerConnection*>(connection1());
2328
2329 {
2330 mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
2331 EXPECT_EQ(dispatcher_->NumSessions(), 1u);
2332 auto* session =
2333 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
2334 ASSERT_EQ(session, session1_);
2335 }
2336
2337 {
2338 mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
2339 EXPECT_EQ(dispatcher_->NumSessions(), 1u);
2340 auto* session =
2341 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(4));
2342 ASSERT_EQ(session, session1_);
2343 }
2344
2345 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2346 // Would timed out unless all sessions have been removed from the session map.
2347 dispatcher_->Shutdown();
2348 }
2349
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,TryAddNewConnectionIdWithCollision)2350 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2351 TryAddNewConnectionIdWithCollision) {
2352 AddConnection1();
2353 AddConnection2();
2354 ASSERT_EQ(dispatcher_->NumSessions(), 2u);
2355 ASSERT_THAT(session1_, testing::NotNull());
2356 ASSERT_THAT(session2_, testing::NotNull());
2357 MockServerConnection* mock_server_connection1 =
2358 reinterpret_cast<MockServerConnection*>(connection1());
2359 MockServerConnection* mock_server_connection2 =
2360 reinterpret_cast<MockServerConnection*>(connection2());
2361
2362 {
2363 // TestConnectionId(2) is already claimed by connection2 but connection1
2364 // still thinks it owns it.
2365 mock_server_connection1->UnconditionallyAddNewConnectionIdForTest(
2366 TestConnectionId(2));
2367 EXPECT_EQ(dispatcher_->NumSessions(), 2u);
2368 auto* session =
2369 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(2));
2370 ASSERT_EQ(session, session2_);
2371 EXPECT_THAT(mock_server_connection1->GetActiveServerConnectionIds(),
2372 testing::ElementsAre(TestConnectionId(1), TestConnectionId(2)));
2373 }
2374
2375 {
2376 mock_server_connection2->AddNewConnectionId(TestConnectionId(3));
2377 EXPECT_EQ(dispatcher_->NumSessions(), 2u);
2378 auto* session =
2379 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(3));
2380 ASSERT_EQ(session, session2_);
2381 EXPECT_THAT(mock_server_connection2->GetActiveServerConnectionIds(),
2382 testing::ElementsAre(TestConnectionId(2), TestConnectionId(3)));
2383 }
2384
2385 // Connection2 removes both TestConnectionId(2) & TestConnectionId(3) from the
2386 // session map.
2387 dispatcher_->OnConnectionClosed(TestConnectionId(2),
2388 QuicErrorCode::QUIC_NO_ERROR, "detail",
2389 quic::ConnectionCloseSource::FROM_SELF);
2390 // QUICHE_BUG fires when connection1 tries to remove TestConnectionId(2)
2391 // again from the session_map.
2392 EXPECT_QUICHE_BUG(dispatcher_->OnConnectionClosed(
2393 TestConnectionId(1), QuicErrorCode::QUIC_NO_ERROR,
2394 "detail", quic::ConnectionCloseSource::FROM_SELF),
2395 "Missing session for cid");
2396 }
2397
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,MismatchedSessionAfterAddingCollidedConnectionId)2398 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2399 MismatchedSessionAfterAddingCollidedConnectionId) {
2400 AddConnection1();
2401 AddConnection2();
2402 MockServerConnection* mock_server_connection1 =
2403 reinterpret_cast<MockServerConnection*>(connection1());
2404
2405 {
2406 // TestConnectionId(2) is already claimed by connection2 but connection1
2407 // still thinks it owns it.
2408 mock_server_connection1->UnconditionallyAddNewConnectionIdForTest(
2409 TestConnectionId(2));
2410 EXPECT_EQ(dispatcher_->NumSessions(), 2u);
2411 auto* session =
2412 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(2));
2413 ASSERT_EQ(session, session2_);
2414 EXPECT_THAT(mock_server_connection1->GetActiveServerConnectionIds(),
2415 testing::ElementsAre(TestConnectionId(1), TestConnectionId(2)));
2416 }
2417
2418 // Connection1 tries to remove both Cid1 & Cid2, but they point to different
2419 // sessions.
2420 EXPECT_QUIC_BUG(dispatcher_->OnConnectionClosed(
2421 TestConnectionId(1), QuicErrorCode::QUIC_NO_ERROR,
2422 "detail", quic::ConnectionCloseSource::FROM_SELF),
2423 "Session is mismatched in the map");
2424 }
2425
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,RetireConnectionIdFromSingleConnection)2426 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2427 RetireConnectionIdFromSingleConnection) {
2428 AddConnection1();
2429 ASSERT_EQ(dispatcher_->NumSessions(), 1u);
2430 ASSERT_THAT(session1_, testing::NotNull());
2431 MockServerConnection* mock_server_connection1 =
2432 reinterpret_cast<MockServerConnection*>(connection1());
2433
2434 // Adds 1 new connection id every turn and retires 2 connection ids every
2435 // other turn.
2436 for (int i = 2; i < 10; ++i) {
2437 mock_server_connection1->AddNewConnectionId(TestConnectionId(i));
2438 ASSERT_EQ(
2439 QuicDispatcherPeer::FindSession(dispatcher_.get(), TestConnectionId(i)),
2440 session1_);
2441 ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
2442 TestConnectionId(i - 1)),
2443 session1_);
2444 EXPECT_EQ(dispatcher_->NumSessions(), 1u);
2445 if (i % 2 == 1) {
2446 mock_server_connection1->RetireConnectionId(TestConnectionId(i - 2));
2447 mock_server_connection1->RetireConnectionId(TestConnectionId(i - 1));
2448 }
2449 }
2450
2451 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2452 // Would timed out unless all sessions have been removed from the session map.
2453 dispatcher_->Shutdown();
2454 }
2455
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,RetireConnectionIdFromMultipleConnections)2456 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2457 RetireConnectionIdFromMultipleConnections) {
2458 AddConnection1();
2459 AddConnection2();
2460 ASSERT_EQ(dispatcher_->NumSessions(), 2u);
2461 MockServerConnection* mock_server_connection1 =
2462 reinterpret_cast<MockServerConnection*>(connection1());
2463 MockServerConnection* mock_server_connection2 =
2464 reinterpret_cast<MockServerConnection*>(connection2());
2465
2466 for (int i = 2; i < 10; ++i) {
2467 mock_server_connection1->AddNewConnectionId(TestConnectionId(2 * i - 1));
2468 mock_server_connection2->AddNewConnectionId(TestConnectionId(2 * i));
2469 ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
2470 TestConnectionId(2 * i - 1)),
2471 session1_);
2472 ASSERT_EQ(QuicDispatcherPeer::FindSession(dispatcher_.get(),
2473 TestConnectionId(2 * i)),
2474 session2_);
2475 EXPECT_EQ(dispatcher_->NumSessions(), 2u);
2476 mock_server_connection1->RetireConnectionId(TestConnectionId(2 * i - 3));
2477 mock_server_connection2->RetireConnectionId(TestConnectionId(2 * i - 2));
2478 }
2479
2480 mock_server_connection1->AddNewConnectionId(TestConnectionId(19));
2481 mock_server_connection2->AddNewConnectionId(TestConnectionId(20));
2482 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2483 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2484 // Would timed out unless all sessions have been removed from the session map.
2485 dispatcher_->Shutdown();
2486 }
2487
TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,TimeWaitListPoplulateCorrectly)2488 TEST_P(QuicDispatcherSupportMultipleConnectionIdPerConnectionTest,
2489 TimeWaitListPoplulateCorrectly) {
2490 QuicTimeWaitListManager* time_wait_list_manager =
2491 QuicDispatcherPeer::GetTimeWaitListManager(dispatcher_.get());
2492 AddConnection1();
2493 MockServerConnection* mock_server_connection1 =
2494 reinterpret_cast<MockServerConnection*>(connection1());
2495
2496 mock_server_connection1->AddNewConnectionId(TestConnectionId(2));
2497 mock_server_connection1->AddNewConnectionId(TestConnectionId(3));
2498 mock_server_connection1->AddNewConnectionId(TestConnectionId(4));
2499 mock_server_connection1->RetireConnectionId(TestConnectionId(1));
2500 mock_server_connection1->RetireConnectionId(TestConnectionId(2));
2501
2502 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
2503 connection1()->CloseConnection(
2504 QUIC_PEER_GOING_AWAY, "Close for testing",
2505 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2506
2507 EXPECT_FALSE(
2508 time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(1)));
2509 EXPECT_FALSE(
2510 time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(2)));
2511 EXPECT_TRUE(
2512 time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(3)));
2513 EXPECT_TRUE(
2514 time_wait_list_manager->IsConnectionIdInTimeWait(TestConnectionId(4)));
2515
2516 dispatcher_->Shutdown();
2517 }
2518
2519 class BufferedPacketStoreTest : public QuicDispatcherTestBase {
2520 public:
BufferedPacketStoreTest()2521 BufferedPacketStoreTest()
2522 : QuicDispatcherTestBase(),
2523 client_addr_(QuicIpAddress::Loopback4(), 1234) {}
2524
ProcessFirstFlight(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)2525 void ProcessFirstFlight(const ParsedQuicVersion& version,
2526 const QuicSocketAddress& peer_address,
2527 const QuicConnectionId& server_connection_id) {
2528 QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
2529 server_connection_id);
2530 }
2531
ProcessFirstFlight(const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)2532 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
2533 const QuicConnectionId& server_connection_id) {
2534 ProcessFirstFlight(version_, peer_address, server_connection_id);
2535 }
2536
ProcessFirstFlight(const QuicConnectionId & server_connection_id)2537 void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
2538 ProcessFirstFlight(client_addr_, server_connection_id);
2539 }
2540
ProcessFirstFlight(const ParsedQuicVersion & version,const QuicConnectionId & server_connection_id)2541 void ProcessFirstFlight(const ParsedQuicVersion& version,
2542 const QuicConnectionId& server_connection_id) {
2543 ProcessFirstFlight(version, client_addr_, server_connection_id);
2544 }
2545
ProcessUndecryptableEarlyPacket(const ParsedQuicVersion & version,const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)2546 void ProcessUndecryptableEarlyPacket(
2547 const ParsedQuicVersion& version, const QuicSocketAddress& peer_address,
2548 const QuicConnectionId& server_connection_id) {
2549 QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
2550 version, peer_address, server_connection_id);
2551 }
2552
ProcessUndecryptableEarlyPacket(const QuicSocketAddress & peer_address,const QuicConnectionId & server_connection_id)2553 void ProcessUndecryptableEarlyPacket(
2554 const QuicSocketAddress& peer_address,
2555 const QuicConnectionId& server_connection_id) {
2556 ProcessUndecryptableEarlyPacket(version_, peer_address,
2557 server_connection_id);
2558 }
2559
ProcessUndecryptableEarlyPacket(const QuicConnectionId & server_connection_id)2560 void ProcessUndecryptableEarlyPacket(
2561 const QuicConnectionId& server_connection_id) {
2562 ProcessUndecryptableEarlyPacket(version_, client_addr_,
2563 server_connection_id);
2564 }
2565
2566 protected:
2567 QuicSocketAddress client_addr_;
2568 };
2569
2570 INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests, BufferedPacketStoreTest,
2571 ::testing::ValuesIn(CurrentSupportedVersions()),
2572 ::testing::PrintToStringParamName());
2573
TEST_P(BufferedPacketStoreTest,ProcessNonChloPacketBeforeChlo)2574 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
2575 InSequence s;
2576 QuicConnectionId conn_id = TestConnectionId(1);
2577 // Process non-CHLO packet.
2578 ProcessUndecryptableEarlyPacket(conn_id);
2579 EXPECT_EQ(0u, dispatcher_->NumSessions())
2580 << "No session should be created before CHLO arrives.";
2581
2582 // When CHLO arrives, a new session should be created, and all packets
2583 // buffered should be delivered to the session.
2584 EXPECT_CALL(connection_id_generator_,
2585 MaybeReplaceConnectionId(conn_id, version_))
2586 .WillOnce(Return(std::nullopt));
2587 EXPECT_CALL(*dispatcher_,
2588 CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
2589 MatchParsedClientHello(), _))
2590 .WillOnce(Return(ByMove(CreateSession(
2591 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
2592 &mock_alarm_factory_, &crypto_config_,
2593 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2594 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2595 ProcessUdpPacket(_, _, _))
2596 .Times(2) // non-CHLO + CHLO.
2597 .WillRepeatedly(
2598 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2599 if (version_.UsesQuicCrypto()) {
2600 ValidatePacket(conn_id, packet);
2601 }
2602 })));
2603 expect_generator_is_called_ = false;
2604 ProcessFirstFlight(conn_id);
2605 }
2606
TEST_P(BufferedPacketStoreTest,ProcessNonChloPacketsUptoLimitAndProcessChlo)2607 TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
2608 InSequence s;
2609 QuicConnectionId conn_id = TestConnectionId(1);
2610 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
2611 ProcessUndecryptableEarlyPacket(conn_id);
2612 }
2613 EXPECT_EQ(0u, dispatcher_->NumSessions())
2614 << "No session should be created before CHLO arrives.";
2615
2616 // Pop out the last packet as it is also be dropped by the store.
2617 data_connection_map_[conn_id].pop_back();
2618 // When CHLO arrives, a new session should be created, and all packets
2619 // buffered should be delivered to the session.
2620 EXPECT_CALL(connection_id_generator_,
2621 MaybeReplaceConnectionId(conn_id, version_))
2622 .WillOnce(Return(std::nullopt));
2623 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
2624 Eq(ExpectedAlpn()), _, _, _))
2625 .WillOnce(Return(ByMove(CreateSession(
2626 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
2627 &mock_alarm_factory_, &crypto_config_,
2628 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2629
2630 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
2631 // should be delivered in arrival order.
2632 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2633 ProcessUdpPacket(_, _, _))
2634 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
2635 .WillRepeatedly(
2636 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2637 if (version_.UsesQuicCrypto()) {
2638 ValidatePacket(conn_id, packet);
2639 }
2640 })));
2641 expect_generator_is_called_ = false;
2642 ProcessFirstFlight(conn_id);
2643 }
2644
TEST_P(BufferedPacketStoreTest,ProcessNonChloPacketsForDifferentConnectionsUptoLimit)2645 TEST_P(BufferedPacketStoreTest,
2646 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
2647 InSequence s;
2648 // A bunch of non-CHLO should be buffered upon arrival.
2649 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
2650 for (size_t i = 1; i <= kNumConnections; ++i) {
2651 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
2652 QuicConnectionId conn_id = TestConnectionId(i);
2653 ProcessUndecryptableEarlyPacket(client_address, conn_id);
2654 }
2655
2656 // Pop out the packet on last connection as it shouldn't be enqueued in store
2657 // as well.
2658 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
2659
2660 // Reset session creation counter to ensure processing CHLO can always
2661 // create session.
2662 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
2663 kNumConnections);
2664 // Deactivate the EXPECT_CALL in ProcessFirstFlight() because we have to be
2665 // in sequence, so the EXPECT_CALL has to explicitly be in order here.
2666 expect_generator_is_called_ = false;
2667 // Process CHLOs to create session for these connections.
2668 for (size_t i = 1; i <= kNumConnections; ++i) {
2669 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 20000 + i);
2670 QuicConnectionId conn_id = TestConnectionId(i);
2671 EXPECT_CALL(connection_id_generator_,
2672 MaybeReplaceConnectionId(conn_id, version_))
2673 .WillOnce(Return(std::nullopt));
2674 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
2675 Eq(ExpectedAlpn()), _, _, _))
2676 .WillOnce(Return(ByMove(CreateSession(
2677 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
2678 &mock_alarm_factory_, &crypto_config_,
2679 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2680 // First |kNumConnections| - 1 connections should have buffered
2681 // a packet in store. The rest should have been dropped.
2682 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
2683 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2684 ProcessUdpPacket(_, client_address, _))
2685 .Times(num_packet_to_process)
2686 .WillRepeatedly(WithArg<2>(
2687 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2688 if (version_.UsesQuicCrypto()) {
2689 ValidatePacket(conn_id, packet);
2690 }
2691 })));
2692 ProcessFirstFlight(client_address, conn_id);
2693 }
2694 }
2695
2696 // Tests that store delivers empty packet list if CHLO arrives firstly.
TEST_P(BufferedPacketStoreTest,DeliverEmptyPackets)2697 TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
2698 QuicConnectionId conn_id = TestConnectionId(1);
2699 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
2700 Eq(ExpectedAlpn()), _, _, _))
2701 .WillOnce(Return(ByMove(CreateSession(
2702 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
2703 &mock_alarm_factory_, &crypto_config_,
2704 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2705 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2706 ProcessUdpPacket(_, client_addr_, _));
2707 ProcessFirstFlight(conn_id);
2708 }
2709
2710 // Tests that a retransmitted CHLO arrives after a connection for the
2711 // CHLO has been created.
TEST_P(BufferedPacketStoreTest,ReceiveRetransmittedCHLO)2712 TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
2713 InSequence s;
2714 QuicConnectionId conn_id = TestConnectionId(1);
2715 ProcessUndecryptableEarlyPacket(conn_id);
2716
2717 // When CHLO arrives, a new session should be created, and all packets
2718 // buffered should be delivered to the session.
2719 EXPECT_CALL(connection_id_generator_,
2720 MaybeReplaceConnectionId(conn_id, version_))
2721 .WillOnce(Return(std::nullopt));
2722 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
2723 Eq(ExpectedAlpn()), _, _, _))
2724 .Times(1) // Only triggered by 1st CHLO.
2725 .WillOnce(Return(ByMove(CreateSession(
2726 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
2727 &mock_alarm_factory_, &crypto_config_,
2728 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2729 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2730 ProcessUdpPacket(_, _, _))
2731 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
2732 .WillRepeatedly(
2733 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2734 if (version_.UsesQuicCrypto()) {
2735 ValidatePacket(conn_id, packet);
2736 }
2737 })));
2738
2739 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
2740 GetFirstFlightOfPackets(version_, conn_id);
2741 ASSERT_EQ(packets.size(), 1u);
2742 // Receive the CHLO once.
2743 ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
2744 // Receive the CHLO a second time to simulate retransmission.
2745 ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
2746 }
2747
2748 // Tests that expiration of a connection add connection id to time wait list.
TEST_P(BufferedPacketStoreTest,ReceiveCHLOAfterExpiration)2749 TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
2750 InSequence s;
2751 CreateTimeWaitListManager();
2752 QuicBufferedPacketStore* store =
2753 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2754 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2755
2756 QuicConnectionId conn_id = TestConnectionId(1);
2757 ProcessPacket(client_addr_, conn_id, true, absl::StrCat("data packet ", 2),
2758 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
2759 /*packet_number=*/2);
2760
2761 mock_helper_.AdvanceTime(
2762 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2763 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
2764 // Cancel alarm as if it had been fired.
2765 alarm->Cancel();
2766 store->OnExpirationTimeout();
2767 // New arrived CHLO will be dropped because this connection is in time wait
2768 // list.
2769 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2770 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _, _));
2771 expect_generator_is_called_ = false;
2772 ProcessFirstFlight(conn_id);
2773 }
2774
TEST_P(BufferedPacketStoreTest,ProcessCHLOsUptoLimitAndBufferTheRest)2775 TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
2776 // Process more than (|kMaxNumSessionsToCreate| +
2777 // |kDefaultMaxConnectionsInStore|) CHLOs,
2778 // the first |kMaxNumSessionsToCreate| should create connections immediately,
2779 // the next |kDefaultMaxConnectionsInStore| should be buffered,
2780 // the rest should be dropped.
2781 QuicBufferedPacketStore* store =
2782 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2783 const size_t kNumCHLOs =
2784 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
2785 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
2786 if (conn_id <= kMaxNumSessionsToCreate) {
2787 EXPECT_CALL(connection_id_generator_,
2788 MaybeReplaceConnectionId(TestConnectionId(conn_id), version_))
2789 .WillOnce(Return(std::nullopt));
2790 EXPECT_CALL(
2791 *dispatcher_,
2792 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
2793 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
2794 .WillOnce(Return(ByMove(CreateSession(
2795 dispatcher_.get(), config_, TestConnectionId(conn_id),
2796 client_addr_, &mock_helper_, &mock_alarm_factory_,
2797 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2798 &session1_))));
2799 EXPECT_CALL(
2800 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2801 ProcessUdpPacket(_, _, _))
2802 .WillOnce(WithArg<2>(
2803 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2804 if (version_.UsesQuicCrypto()) {
2805 ValidatePacket(TestConnectionId(conn_id), packet);
2806 }
2807 })));
2808 }
2809 expect_generator_is_called_ = false;
2810 ProcessFirstFlight(TestConnectionId(conn_id));
2811 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
2812 conn_id > kMaxNumSessionsToCreate) {
2813 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
2814 } else {
2815 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
2816 // connections immediately, and the last CHLO should be dropped as the
2817 // store is full.
2818 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
2819 }
2820 }
2821
2822 // Gradually consume buffered CHLOs. The buffered connections should be
2823 // created but the dropped one shouldn't.
2824 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2825 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
2826 ++conn_id) {
2827 EXPECT_CALL(connection_id_generator_,
2828 MaybeReplaceConnectionId(TestConnectionId(conn_id), version_))
2829 .WillOnce(Return(std::nullopt));
2830 EXPECT_CALL(
2831 *dispatcher_,
2832 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
2833 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
2834 .WillOnce(Return(ByMove(CreateSession(
2835 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2836 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2837 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2838 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2839 ProcessUdpPacket(_, _, _))
2840 .WillOnce(WithArg<2>(
2841 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2842 if (version_.UsesQuicCrypto()) {
2843 ValidatePacket(TestConnectionId(conn_id), packet);
2844 }
2845 })));
2846 }
2847 EXPECT_CALL(connection_id_generator_,
2848 MaybeReplaceConnectionId(TestConnectionId(kNumCHLOs), version_))
2849 .Times(0);
2850 EXPECT_CALL(*dispatcher_,
2851 CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
2852 Eq(ExpectedAlpn()), _, _, _))
2853 .Times(0);
2854
2855 while (store->HasChlosBuffered()) {
2856 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2857 }
2858
2859 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
2860 kDefaultMaxConnectionsInStore),
2861 session1_->connection_id());
2862 }
2863
TEST_P(BufferedPacketStoreTest,ProcessCHLOsUptoLimitAndBufferWithDifferentConnectionIdGenerator)2864 TEST_P(BufferedPacketStoreTest,
2865 ProcessCHLOsUptoLimitAndBufferWithDifferentConnectionIdGenerator) {
2866 // Process (|kMaxNumSessionsToCreate| + 1) CHLOs,
2867 // the first |kMaxNumSessionsToCreate| should create connections immediately,
2868 // the last should be buffered.
2869 QuicBufferedPacketStore* store =
2870 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2871 const size_t kNumCHLOs = kMaxNumSessionsToCreate + 1;
2872 MockConnectionIdGenerator generator2;
2873 for (uint64_t conn_id = 1; conn_id < kNumCHLOs; ++conn_id) {
2874 EXPECT_CALL(
2875 *dispatcher_,
2876 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
2877 Eq(ExpectedAlpn()), _, MatchParsedClientHello(), _))
2878 .WillOnce(Return(ByMove(CreateSession(
2879 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2880 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2881 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2882 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2883 ProcessUdpPacket(_, _, _))
2884 .WillOnce(WithArg<2>(
2885 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2886 if (version_.UsesQuicCrypto()) {
2887 ValidatePacket(TestConnectionId(conn_id), packet);
2888 }
2889 })));
2890 ProcessFirstFlight(TestConnectionId(conn_id));
2891 }
2892 uint64_t conn_id = kNumCHLOs;
2893 expect_generator_is_called_ = false;
2894 EXPECT_CALL(*dispatcher_, ConnectionIdGenerator())
2895 .WillRepeatedly(ReturnRef(generator2));
2896 ProcessFirstFlight(TestConnectionId(conn_id));
2897 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
2898 // Change the generator back so that the session can only access generator2
2899 // by using the buffer entry.
2900 EXPECT_CALL(*dispatcher_, ConnectionIdGenerator())
2901 .WillRepeatedly(ReturnRef(connection_id_generator_));
2902
2903 // Consume the buffered CHLO. The buffered connection should be
2904 // created using generator2.
2905 EXPECT_CALL(generator2,
2906 MaybeReplaceConnectionId(TestConnectionId(conn_id), version_))
2907 .WillOnce(Return(std::nullopt));
2908 EXPECT_CALL(*dispatcher_, CreateQuicSession(TestConnectionId(conn_id), _,
2909 client_addr_, Eq(ExpectedAlpn()),
2910 _, MatchParsedClientHello(), _))
2911 .WillOnce(Return(ByMove(CreateSession(
2912 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2913 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2914 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2915 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2916 ProcessUdpPacket(_, _, _))
2917 .WillOnce(
2918 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2919 if (version_.UsesQuicCrypto()) {
2920 ValidatePacket(TestConnectionId(conn_id), packet);
2921 }
2922 })));
2923 while (store->HasChlosBuffered()) {
2924 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2925 }
2926 }
2927
2928 // Duplicated CHLO shouldn't be buffered.
TEST_P(BufferedPacketStoreTest,BufferDuplicatedCHLO)2929 TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
2930 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
2931 ++conn_id) {
2932 // Last CHLO will be buffered. Others will create connection right away.
2933 if (conn_id <= kMaxNumSessionsToCreate) {
2934 EXPECT_CALL(*dispatcher_,
2935 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
2936 Eq(ExpectedAlpn()), _, _, _))
2937 .WillOnce(Return(ByMove(CreateSession(
2938 dispatcher_.get(), config_, TestConnectionId(conn_id),
2939 client_addr_, &mock_helper_, &mock_alarm_factory_,
2940 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2941 &session1_))));
2942 EXPECT_CALL(
2943 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2944 ProcessUdpPacket(_, _, _))
2945 .WillOnce(WithArg<2>(
2946 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
2947 if (version_.UsesQuicCrypto()) {
2948 ValidatePacket(TestConnectionId(conn_id), packet);
2949 }
2950 })));
2951 }
2952 ProcessFirstFlight(TestConnectionId(conn_id));
2953 }
2954 // Retransmit CHLO on last connection should be dropped.
2955 QuicConnectionId last_connection =
2956 TestConnectionId(kMaxNumSessionsToCreate + 1);
2957 expect_generator_is_called_ = false;
2958 ProcessFirstFlight(last_connection);
2959
2960 size_t packets_buffered = 2;
2961
2962 // Reset counter and process buffered CHLO.
2963 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
2964 Eq(ExpectedAlpn()), _, _, _))
2965 .WillOnce(Return(ByMove(CreateSession(
2966 dispatcher_.get(), config_, last_connection, client_addr_,
2967 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
2968 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
2969 // Only one packet(CHLO) should be process.
2970 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2971 ProcessUdpPacket(_, _, _))
2972 .Times(packets_buffered)
2973 .WillRepeatedly(WithArg<2>(
2974 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
2975 if (version_.UsesQuicCrypto()) {
2976 ValidatePacket(last_connection, packet);
2977 }
2978 })));
2979 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2980 }
2981
TEST_P(BufferedPacketStoreTest,BufferNonChloPacketsUptoLimitWithChloBuffered)2982 TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
2983 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2984 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2985 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2986 // Last CHLO will be buffered. Others will create connection right away.
2987 if (conn_id <= kMaxNumSessionsToCreate) {
2988 EXPECT_CALL(*dispatcher_,
2989 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
2990 Eq(ExpectedAlpn()), _, _, _))
2991 .WillOnce(Return(ByMove(CreateSession(
2992 dispatcher_.get(), config_, TestConnectionId(conn_id),
2993 client_addr_, &mock_helper_, &mock_alarm_factory_,
2994 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
2995 &session1_))));
2996 EXPECT_CALL(
2997 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2998 ProcessUdpPacket(_, _, _))
2999 .WillRepeatedly(WithArg<2>(
3000 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
3001 if (version_.UsesQuicCrypto()) {
3002 ValidatePacket(TestConnectionId(conn_id), packet);
3003 }
3004 })));
3005 }
3006 ProcessFirstFlight(TestConnectionId(conn_id));
3007 }
3008
3009 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
3010 // last one should be dropped.
3011 for (uint64_t packet_number = 2;
3012 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
3013 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
3014 }
3015
3016 // Reset counter and process buffered CHLO.
3017 EXPECT_CALL(*dispatcher_,
3018 CreateQuicSession(last_connection_id, _, client_addr_,
3019 Eq(ExpectedAlpn()), _, _, _))
3020 .WillOnce(Return(ByMove(CreateSession(
3021 dispatcher_.get(), config_, last_connection_id, client_addr_,
3022 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
3023 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
3024 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
3025 // should be process.
3026 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
3027 ProcessUdpPacket(_, _, _))
3028 .Times(kDefaultMaxUndecryptablePackets + 1)
3029 .WillRepeatedly(WithArg<2>(
3030 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
3031 if (version_.UsesQuicCrypto()) {
3032 ValidatePacket(last_connection_id, packet);
3033 }
3034 })));
3035 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
3036 }
3037
3038 // Tests that when dispatcher's packet buffer is full, a CHLO on connection
3039 // which doesn't have buffered CHLO should be buffered.
TEST_P(BufferedPacketStoreTest,ReceiveCHLOForBufferedConnection)3040 TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
3041 QuicBufferedPacketStore* store =
3042 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
3043
3044 uint64_t conn_id = 1;
3045 ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
3046 // Fill packet buffer to full with CHLOs on other connections. Need to feed
3047 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
3048 // session directly.
3049 for (conn_id = 2;
3050 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
3051 ++conn_id) {
3052 if (conn_id <= kMaxNumSessionsToCreate + 1) {
3053 EXPECT_CALL(*dispatcher_,
3054 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
3055 Eq(ExpectedAlpn()), _, _, _))
3056 .WillOnce(Return(ByMove(CreateSession(
3057 dispatcher_.get(), config_, TestConnectionId(conn_id),
3058 client_addr_, &mock_helper_, &mock_alarm_factory_,
3059 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
3060 &session1_))));
3061 EXPECT_CALL(
3062 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
3063 ProcessUdpPacket(_, _, _))
3064 .WillOnce(WithArg<2>(
3065 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
3066 if (version_.UsesQuicCrypto()) {
3067 ValidatePacket(TestConnectionId(conn_id), packet);
3068 }
3069 })));
3070 } else {
3071 expect_generator_is_called_ = false;
3072 }
3073 ProcessFirstFlight(TestConnectionId(conn_id));
3074 }
3075 EXPECT_FALSE(store->HasChloForConnection(
3076 /*connection_id=*/TestConnectionId(1)));
3077
3078 // CHLO on connection 1 should still be buffered.
3079 ProcessFirstFlight(TestConnectionId(1));
3080 EXPECT_TRUE(store->HasChloForConnection(
3081 /*connection_id=*/TestConnectionId(1)));
3082 }
3083
3084 // Regression test for b/117874922.
TEST_P(BufferedPacketStoreTest,ProcessBufferedChloWithDifferentVersion)3085 TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
3086 // Ensure the preferred version is not supported by the server.
3087 QuicDisableVersion(AllSupportedVersions().front());
3088
3089 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
3090 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
3091 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
3092 // Last 5 CHLOs will be buffered. Others will create connection right away.
3093 ParsedQuicVersion version =
3094 supported_versions[(conn_id - 1) % supported_versions.size()];
3095 if (conn_id <= kMaxNumSessionsToCreate) {
3096 EXPECT_CALL(
3097 *dispatcher_,
3098 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
3099 Eq(ExpectedAlpnForVersion(version)), version, _, _))
3100 .WillOnce(Return(ByMove(CreateSession(
3101 dispatcher_.get(), config_, TestConnectionId(conn_id),
3102 client_addr_, &mock_helper_, &mock_alarm_factory_,
3103 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
3104 &session1_))));
3105 EXPECT_CALL(
3106 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
3107 ProcessUdpPacket(_, _, _))
3108 .WillRepeatedly(WithArg<2>(
3109 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
3110 if (version_.UsesQuicCrypto()) {
3111 ValidatePacket(TestConnectionId(conn_id), packet);
3112 }
3113 })));
3114 }
3115 ProcessFirstFlight(version, TestConnectionId(conn_id));
3116 }
3117
3118 // Process buffered CHLOs. Verify the version is correct.
3119 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
3120 conn_id <= last_connection_id; ++conn_id) {
3121 ParsedQuicVersion version =
3122 supported_versions[(conn_id - 1) % supported_versions.size()];
3123 EXPECT_CALL(
3124 *dispatcher_,
3125 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
3126 Eq(ExpectedAlpnForVersion(version)), version, _, _))
3127 .WillOnce(Return(ByMove(CreateSession(
3128 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
3129 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
3130 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
3131 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
3132 ProcessUdpPacket(_, _, _))
3133 .WillRepeatedly(WithArg<2>(
3134 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
3135 if (version_.UsesQuicCrypto()) {
3136 ValidatePacket(TestConnectionId(conn_id), packet);
3137 }
3138 })));
3139 }
3140 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
3141 }
3142
TEST_P(BufferedPacketStoreTest,BufferedChloWithEcn)3143 TEST_P(BufferedPacketStoreTest, BufferedChloWithEcn) {
3144 if (!version_.HasIetfQuicFrames()) {
3145 return;
3146 }
3147 SetQuicRestartFlag(quic_support_ect1, true);
3148 InSequence s;
3149 QuicConnectionId conn_id = TestConnectionId(1);
3150 // Process non-CHLO packet. This ProcessUndecryptableEarlyPacket() but with
3151 // an injected step to set the ECN bits.
3152 std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
3153 GetUndecryptableEarlyPacket(version_, conn_id);
3154 std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
3155 *encrypted_packet, mock_helper_.GetClock()->Now(), ECN_ECT1));
3156 ProcessReceivedPacket(std::move(received_packet), client_addr_, version_,
3157 conn_id);
3158 EXPECT_EQ(0u, dispatcher_->NumSessions())
3159 << "No session should be created before CHLO arrives.";
3160
3161 // When CHLO arrives, a new session should be created, and all packets
3162 // buffered should be delivered to the session.
3163 EXPECT_CALL(connection_id_generator_,
3164 MaybeReplaceConnectionId(conn_id, version_))
3165 .WillOnce(Return(std::nullopt));
3166 EXPECT_CALL(*dispatcher_,
3167 CreateQuicSession(conn_id, _, client_addr_, Eq(ExpectedAlpn()), _,
3168 MatchParsedClientHello(), _))
3169 .WillOnce(Return(ByMove(CreateSession(
3170 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
3171 &mock_alarm_factory_, &crypto_config_,
3172 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
3173 bool got_ect1 = false;
3174 bool got_ce = false;
3175 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
3176 ProcessUdpPacket(_, _, _))
3177 .Times(2) // non-CHLO + CHLO.
3178 .WillRepeatedly(WithArg<2>(Invoke([&](const QuicReceivedPacket& packet) {
3179 switch (packet.ecn_codepoint()) {
3180 case ECN_ECT1:
3181 got_ect1 = true;
3182 break;
3183 case ECN_CE:
3184 got_ce = true;
3185 break;
3186 default:
3187 break;
3188 }
3189 })));
3190 QuicConnectionId client_connection_id = TestConnectionId(2);
3191 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
3192 GetFirstFlightOfPackets(version_, DefaultQuicConfig(), conn_id,
3193 client_connection_id, TestClientCryptoConfig(),
3194 ECN_CE);
3195 for (auto&& packet : packets) {
3196 ProcessReceivedPacket(std::move(packet), client_addr_, version_, conn_id);
3197 }
3198 EXPECT_TRUE(got_ect1);
3199 EXPECT_TRUE(got_ce);
3200 }
3201
3202 } // namespace
3203 } // namespace test
3204 } // namespace quic
3205