blob: bd9bb7acad5303a6e7d282338fe252a6d704a8fc [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
6
7#include <memory>
8#include <ostream>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
bnc463f2352019-10-10 04:49:34 -070010#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/chlo_extractor.h"
13#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
14#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
15#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
16#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
dschinazi0e3c3482020-04-24 11:37:20 -070017#include "net/third_party/quiche/src/quic/core/quic_config.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
19#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
20#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
21#include "net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h"
22#include "net/third_party/quiche/src/quic/core/quic_types.h"
23#include "net/third_party/quiche/src/quic/core/quic_utils.h"
dschinazi41616842020-01-21 15:46:11 -080024#include "net/third_party/quiche/src/quic/core/quic_versions.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050025#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050028#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
29#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
30#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
dschinazi6b40b1d2020-04-22 06:15:46 -070031#include "net/third_party/quiche/src/quic/test_tools/first_flight.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050032#include "net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h"
33#include "net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h"
34#include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
35#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
36#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
37#include "net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h"
38#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
bnc4e9283d2019-12-17 07:08:57 -080039#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080040#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
dmcardle8f7df532020-01-07 13:28:57 -080041#include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050042
43using testing::_;
wub89490e02019-12-12 12:45:58 -080044using testing::ByMove;
dschinazi8d1c9d42020-02-18 13:12:20 -080045using testing::Eq;
QUICHE teama6ef0a62019-03-07 20:34:33 -050046using testing::InSequence;
47using testing::Invoke;
48using testing::NiceMock;
49using testing::Return;
50using testing::WithArg;
51using testing::WithoutArgs;
52
53static const size_t kDefaultMaxConnectionsInStore = 100;
54static const size_t kMaxConnectionsWithoutCHLO =
55 kDefaultMaxConnectionsInStore / 2;
56static const int16_t kMaxNumSessionsToCreate = 16;
57
58namespace quic {
59namespace test {
60namespace {
61
62class TestQuicSpdyServerSession : public QuicServerSessionBase {
63 public:
64 TestQuicSpdyServerSession(const QuicConfig& config,
65 QuicConnection* connection,
66 const QuicCryptoServerConfig* crypto_config,
67 QuicCompressedCertsCache* compressed_certs_cache)
68 : QuicServerSessionBase(config,
69 CurrentSupportedVersions(),
70 connection,
71 nullptr,
72 nullptr,
73 crypto_config,
fayang63a19842020-01-23 02:51:28 -080074 compressed_certs_cache) {
75 Initialize();
76 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
78 TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
79 delete;
80
ianswett6aefa0b2019-12-10 07:26:15 -080081 ~TestQuicSpdyServerSession() override { DeleteConnection(); }
QUICHE teama6ef0a62019-03-07 20:34:33 -050082
wub713afae2020-04-27 07:48:31 -070083 MOCK_METHOD(void,
84 OnConnectionClosed,
85 (const QuicConnectionCloseFrame& frame,
86 ConnectionCloseSource source),
87 (override));
88 MOCK_METHOD(QuicSpdyStream*,
89 CreateIncomingStream,
90 (QuicStreamId id),
91 (override));
92 MOCK_METHOD(QuicSpdyStream*,
93 CreateIncomingStream,
94 (PendingStream*),
95 (override));
96 MOCK_METHOD(QuicSpdyStream*,
97 CreateOutgoingBidirectionalStream,
98 (),
99 (override));
100 MOCK_METHOD(QuicSpdyStream*,
101 CreateOutgoingUnidirectionalStream,
102 (),
103 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104
nharpere5e28f92020-01-03 14:10:07 -0800105 std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 const QuicCryptoServerConfig* crypto_config,
107 QuicCompressedCertsCache* compressed_certs_cache) override {
nharpere5e28f92020-01-03 14:10:07 -0800108 return CreateCryptoServerStream(crypto_config, compressed_certs_cache, this,
109 stream_helper());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 }
111
nharper5f23a2d2020-02-20 10:44:09 -0800112 QuicCryptoServerStreamBase::Helper* stream_helper() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500113 return QuicServerSessionBase::stream_helper();
114 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115};
116
117class TestDispatcher : public QuicDispatcher {
118 public:
119 TestDispatcher(const QuicConfig* config,
120 const QuicCryptoServerConfig* crypto_config,
QUICHE teamc65d1d12019-03-19 20:58:04 -0700121 QuicVersionManager* version_manager,
122 QuicRandom* random)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500123 : QuicDispatcher(config,
124 crypto_config,
125 version_manager,
vasilvv0fc587f2019-09-06 13:33:08 -0700126 std::make_unique<MockQuicConnectionHelper>(),
nharper5f23a2d2020-02-20 10:44:09 -0800127 std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
wub662a3d62019-08-16 14:10:50 -0700128 new QuicSimpleCryptoServerStreamHelper()),
vasilvv0fc587f2019-09-06 13:33:08 -0700129 std::make_unique<MockAlarmFactory>(),
wub662a3d62019-08-16 14:10:50 -0700130 kQuicDefaultConnectionIdLength),
131 random_(random) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132
wub713afae2020-04-27 07:48:31 -0700133 MOCK_METHOD(std::unique_ptr<QuicSession>,
134 CreateQuicSession,
135 (QuicConnectionId connection_id,
wub4e3fb902020-07-15 13:37:29 -0700136 const QuicSocketAddress& self_address,
wub713afae2020-04-27 07:48:31 -0700137 const QuicSocketAddress& peer_address,
138 quiche::QuicheStringPiece alpn,
139 const quic::ParsedQuicVersion& version),
140 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141
wub713afae2020-04-27 07:48:31 -0700142 MOCK_METHOD(bool,
143 ShouldCreateOrBufferPacketForConnection,
144 (const ReceivedPacketInfo& packet_info),
145 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146
147 struct TestQuicPerPacketContext : public QuicPerPacketContext {
vasilvvc48c8712019-03-11 13:38:16 -0700148 std::string custom_packet_context;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149 };
150
151 std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
vasilvv0fc587f2019-09-06 13:33:08 -0700152 auto test_context = std::make_unique<TestQuicPerPacketContext>();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153 test_context->custom_packet_context = custom_packet_context_;
154 return std::move(test_context);
155 }
156
157 void RestorePerPacketContext(
158 std::unique_ptr<QuicPerPacketContext> context) override {
159 TestQuicPerPacketContext* test_context =
160 static_cast<TestQuicPerPacketContext*>(context.get());
161 custom_packet_context_ = test_context->custom_packet_context;
162 }
163
vasilvvc48c8712019-03-11 13:38:16 -0700164 std::string custom_packet_context_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165
dschinazi7b9278c2019-05-20 07:36:21 -0700166 using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167 using QuicDispatcher::writer;
wub662a3d62019-08-16 14:10:50 -0700168
169 QuicRandom* random_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170};
171
172// A Connection class which unregisters the session from the dispatcher when
173// sending connection close.
174// It'd be slightly more realistic to do this from the Session but it would
175// involve a lot more mocking.
176class MockServerConnection : public MockQuicConnection {
177 public:
178 MockServerConnection(QuicConnectionId connection_id,
179 MockQuicConnectionHelper* helper,
180 MockAlarmFactory* alarm_factory,
181 QuicDispatcher* dispatcher)
182 : MockQuicConnection(connection_id,
183 helper,
184 alarm_factory,
185 Perspective::IS_SERVER),
186 dispatcher_(dispatcher) {}
187
188 void UnregisterOnConnectionClosed() {
189 QUIC_LOG(ERROR) << "Unregistering " << connection_id();
190 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
191 "Unregistering.",
192 ConnectionCloseSource::FROM_SELF);
193 }
194
195 private:
196 QuicDispatcher* dispatcher_;
197};
198
dschinazi8d1c9d42020-02-18 13:12:20 -0800199class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200 public:
dschinazi8d1c9d42020-02-18 13:12:20 -0800201 QuicDispatcherTestBase()
202 : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203
dschinazi8d1c9d42020-02-18 13:12:20 -0800204 explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
205 : version_(GetParam()),
206 version_manager_(AllSupportedVersions()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 crypto_config_(QuicCryptoServerConfig::TESTING,
208 QuicRandom::GetInstance(),
209 std::move(proof_source),
nharper6ebe83b2019-06-13 17:43:52 -0700210 KeyExchangeSource::Default()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 server_address_(QuicIpAddress::Any4(), 5),
QUICHE teamc65d1d12019-03-19 20:58:04 -0700212 dispatcher_(
213 new NiceMock<TestDispatcher>(&config_,
214 &crypto_config_,
215 &version_manager_,
216 mock_helper_.GetRandomGenerator())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217 time_wait_list_manager_(nullptr),
218 session1_(nullptr),
219 session2_(nullptr),
fayangb880b4c2019-06-14 12:26:35 -0700220 store_(nullptr),
221 connection_id_(1) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222
223 void SetUp() override {
dschinazi42fc2da2020-04-24 16:19:17 -0700224 dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500225 // Set the counter to some value to start with.
226 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
227 dispatcher_.get(), kMaxNumSessionsToCreate);
fayang1ed1f762019-06-24 11:40:04 -0700228 ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500229 .WillByDefault(Return(true));
230 }
231
232 MockQuicConnection* connection1() {
233 if (session1_ == nullptr) {
234 return nullptr;
235 }
236 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
237 }
238
239 MockQuicConnection* connection2() {
240 if (session2_ == nullptr) {
241 return nullptr;
242 }
243 return reinterpret_cast<MockQuicConnection*>(session2_->connection());
244 }
245
246 // Process a packet with an 8 byte connection id,
247 // 6 byte packet number, default path id, and packet number 1,
dschinazi8d1c9d42020-02-18 13:12:20 -0800248 // using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500249 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700250 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700252 const std::string& data) {
dschinazi346b7ce2019-06-05 01:38:18 -0700253 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500254 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
255 }
256
257 // Process a packet with a default path id, and packet number 1,
dschinazi8d1c9d42020-02-18 13:12:20 -0800258 // using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700260 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700262 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700263 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 QuicPacketNumberLength packet_number_length) {
dschinazi346b7ce2019-06-05 01:38:18 -0700265 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
266 server_connection_id_included, packet_number_length, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 }
268
dschinazi8d1c9d42020-02-18 13:12:20 -0800269 // Process a packet using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700271 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700273 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700274 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500275 QuicPacketNumberLength packet_number_length,
276 uint64_t packet_number) {
dschinazi346b7ce2019-06-05 01:38:18 -0700277 ProcessPacket(peer_address, server_connection_id, has_version_flag,
dschinazi8d1c9d42020-02-18 13:12:20 -0800278 version_, data, true, server_connection_id_included,
279 packet_number_length, packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500280 }
281
282 // Processes a packet.
283 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700284 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285 bool has_version_flag,
286 ParsedQuicVersion version,
vasilvvc48c8712019-03-11 13:38:16 -0700287 const std::string& data,
fayange3f2f7b2019-09-19 17:01:57 -0700288 bool full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700289 QuicConnectionIdIncluded server_connection_id_included,
290 QuicPacketNumberLength packet_number_length,
291 uint64_t packet_number) {
292 ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
fayange3f2f7b2019-09-19 17:01:57 -0700293 has_version_flag, version, data, full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700294 server_connection_id_included, CONNECTION_ID_ABSENT,
295 packet_number_length, packet_number);
296 }
297
298 // Processes a packet.
299 void ProcessPacket(QuicSocketAddress peer_address,
300 QuicConnectionId server_connection_id,
301 QuicConnectionId client_connection_id,
302 bool has_version_flag,
303 ParsedQuicVersion version,
304 const std::string& data,
fayange3f2f7b2019-09-19 17:01:57 -0700305 bool full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700306 QuicConnectionIdIncluded server_connection_id_included,
307 QuicConnectionIdIncluded client_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500308 QuicPacketNumberLength packet_number_length,
309 uint64_t packet_number) {
310 ParsedQuicVersionVector versions(SupportedVersions(version));
311 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
dschinazi346b7ce2019-06-05 01:38:18 -0700312 server_connection_id, client_connection_id, has_version_flag, false,
fayange3f2f7b2019-09-19 17:01:57 -0700313 packet_number, data, full_padding, server_connection_id_included,
dschinazi346b7ce2019-06-05 01:38:18 -0700314 client_connection_id_included, packet_number_length, &versions));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500315 std::unique_ptr<QuicReceivedPacket> received_packet(
316 ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
dschinazi6b40b1d2020-04-22 06:15:46 -0700317 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
318 server_connection_id);
319 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500320
dschinazi6b40b1d2020-04-22 06:15:46 -0700321 void ProcessReceivedPacket(
322 std::unique_ptr<QuicReceivedPacket> received_packet,
323 const QuicSocketAddress& peer_address,
324 const ParsedQuicVersion& version,
325 const QuicConnectionId& server_connection_id) {
dschinazi42fc2da2020-04-24 16:19:17 -0700326 if (version.UsesQuicCrypto() &&
dschinazi0e3c3482020-04-24 11:37:20 -0700327 ChloExtractor::Extract(*received_packet, version, {}, nullptr,
dschinazi346b7ce2019-06-05 01:38:18 -0700328 server_connection_id.length())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 // Add CHLO packet to the beginning to be verified first, because it is
330 // also processed first by new session.
dschinazi346b7ce2019-06-05 01:38:18 -0700331 data_connection_map_[server_connection_id].push_front(
dschinazi6b40b1d2020-04-22 06:15:46 -0700332 std::string(received_packet->data(), received_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500333 } else {
334 // For non-CHLO, always append to last.
dschinazi346b7ce2019-06-05 01:38:18 -0700335 data_connection_map_[server_connection_id].push_back(
dschinazi6b40b1d2020-04-22 06:15:46 -0700336 std::string(received_packet->data(), received_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500337 }
338 dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
339 }
340
341 void ValidatePacket(QuicConnectionId conn_id,
342 const QuicEncryptedPacket& packet) {
343 EXPECT_EQ(data_connection_map_[conn_id].front().length(),
344 packet.AsStringPiece().length());
345 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
346 data_connection_map_[conn_id].pop_front();
347 }
348
wub89490e02019-12-12 12:45:58 -0800349 std::unique_ptr<QuicSession> CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 TestDispatcher* dispatcher,
351 const QuicConfig& config,
352 QuicConnectionId connection_id,
dschinazi17d42422019-06-18 16:35:07 -0700353 const QuicSocketAddress& /*peer_address*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500354 MockQuicConnectionHelper* helper,
355 MockAlarmFactory* alarm_factory,
356 const QuicCryptoServerConfig* crypto_config,
357 QuicCompressedCertsCache* compressed_certs_cache,
wub89490e02019-12-12 12:45:58 -0800358 TestQuicSpdyServerSession** session_ptr) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500359 MockServerConnection* connection = new MockServerConnection(
360 connection_id, helper, alarm_factory, dispatcher);
361 connection->SetQuicPacketWriter(dispatcher->writer(),
362 /*owns_writer=*/false);
wub89490e02019-12-12 12:45:58 -0800363 auto session = std::make_unique<TestQuicSpdyServerSession>(
364 config, connection, crypto_config, compressed_certs_cache);
365 *session_ptr = session.get();
366 connection->set_visitor(session.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500367 ON_CALL(*connection, CloseConnection(_, _, _))
368 .WillByDefault(WithoutArgs(Invoke(
369 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
wub89490e02019-12-12 12:45:58 -0800370 return session;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500371 }
372
373 void CreateTimeWaitListManager() {
374 time_wait_list_manager_ = new MockTimeWaitListManager(
375 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
376 mock_helper_.GetClock(), &mock_alarm_factory_);
377 // dispatcher_ takes the ownership of time_wait_list_manager_.
378 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
379 time_wait_list_manager_);
380 }
381
vasilvvc48c8712019-03-11 13:38:16 -0700382 std::string SerializeCHLO() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383 CryptoHandshakeMessage client_hello;
384 client_hello.set_tag(kCHLO);
dschinazi6b40b1d2020-04-22 06:15:46 -0700385 client_hello.SetStringPiece(kALPN, ExpectedAlpn());
vasilvvc48c8712019-03-11 13:38:16 -0700386 return std::string(client_hello.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387 }
388
dschinazi42fc2da2020-04-24 16:19:17 -0700389 void ProcessUndecryptableEarlyPacket(
390 const QuicSocketAddress& peer_address,
391 const QuicConnectionId& server_connection_id) {
392 ProcessUndecryptableEarlyPacket(version_, peer_address,
393 server_connection_id);
394 }
395
396 void ProcessUndecryptableEarlyPacket(
397 const ParsedQuicVersion& version,
398 const QuicSocketAddress& peer_address,
399 const QuicConnectionId& server_connection_id) {
400 std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
401 GetUndecryptableEarlyPacket(version, server_connection_id);
402 std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
403 *encrypted_packet, mock_helper_.GetClock()->Now()));
404 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
405 server_connection_id);
406 }
407
dschinazi6b40b1d2020-04-22 06:15:46 -0700408 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
409 const QuicConnectionId& server_connection_id) {
410 ProcessFirstFlight(version_, peer_address, server_connection_id);
411 }
412
413 void ProcessFirstFlight(const ParsedQuicVersion& version,
414 const QuicSocketAddress& peer_address,
415 const QuicConnectionId& server_connection_id) {
416 ProcessFirstFlight(version, peer_address, server_connection_id,
417 EmptyQuicConnectionId());
418 }
419
420 void ProcessFirstFlight(const ParsedQuicVersion& version,
421 const QuicSocketAddress& peer_address,
422 const QuicConnectionId& server_connection_id,
423 const QuicConnectionId& client_connection_id) {
424 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
425 GetFirstFlightOfPackets(version, server_connection_id,
426 client_connection_id);
427 for (auto&& packet : packets) {
428 ProcessReceivedPacket(std::move(packet), peer_address, version,
429 server_connection_id);
430 }
431 }
432
dschinazi8d1c9d42020-02-18 13:12:20 -0800433 std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
dschinazi6b40b1d2020-04-22 06:15:46 -0700434 return AlpnForVersion(version);
dschinazi8d1c9d42020-02-18 13:12:20 -0800435 }
436
437 std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
438
QUICHE teama6ef0a62019-03-07 20:34:33 -0500439 void MarkSession1Deleted() { session1_ = nullptr; }
440
fayangb880b4c2019-06-14 12:26:35 -0700441 void VerifyVersionSupported(ParsedQuicVersion version) {
442 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
443 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
dmcardlecf0bfcf2019-12-13 08:08:21 -0800444 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700445 CreateQuicSession(connection_id, _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800446 Eq(ExpectedAlpnForVersion(version)), _))
wub89490e02019-12-12 12:45:58 -0800447 .WillOnce(Return(ByMove(CreateSession(
fayangb880b4c2019-06-14 12:26:35 -0700448 dispatcher_.get(), config_, connection_id, client_address,
449 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800450 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
fayangb880b4c2019-06-14 12:26:35 -0700451 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
452 ProcessUdpPacket(_, _, _))
453 .WillOnce(WithArg<2>(
454 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
455 ValidatePacket(connection_id, packet);
456 })));
457 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700458 ShouldCreateOrBufferPacketForConnection(
459 ReceivedPacketInfoConnectionIdEquals(connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700460 ProcessFirstFlight(version, client_address, connection_id);
fayangb880b4c2019-06-14 12:26:35 -0700461 }
462
463 void VerifyVersionNotSupported(ParsedQuicVersion version) {
464 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
465 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
dmcardlecf0bfcf2019-12-13 08:08:21 -0800466 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700467 CreateQuicSession(connection_id, _, client_address, _, _))
fayangb880b4c2019-06-14 12:26:35 -0700468 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -0700469 ProcessFirstFlight(version, client_address, connection_id);
fayangb880b4c2019-06-14 12:26:35 -0700470 }
471
dschinazi0e3c3482020-04-24 11:37:20 -0700472 void TestTlsMultiPacketClientHello(bool add_reordering);
473
dschinazi8d1c9d42020-02-18 13:12:20 -0800474 ParsedQuicVersion version_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500475 MockQuicConnectionHelper mock_helper_;
476 MockAlarmFactory mock_alarm_factory_;
477 QuicConfig config_;
478 QuicVersionManager version_manager_;
479 QuicCryptoServerConfig crypto_config_;
480 QuicSocketAddress server_address_;
481 std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
482 MockTimeWaitListManager* time_wait_list_manager_;
483 TestQuicSpdyServerSession* session1_;
484 TestQuicSpdyServerSession* session2_;
vasilvvc48c8712019-03-11 13:38:16 -0700485 std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500486 QuicBufferedPacketStore* store_;
fayangb880b4c2019-06-14 12:26:35 -0700487 uint64_t connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500488};
489
dschinazi8d1c9d42020-02-18 13:12:20 -0800490class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
491class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
492
493INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
494 QuicDispatcherTestAllVersions,
495 ::testing::ValuesIn(CurrentSupportedVersions()),
496 ::testing::PrintToStringParamName());
497
498INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
499 QuicDispatcherTestOneVersion,
500 ::testing::Values(CurrentSupportedVersions().front()),
501 ::testing::PrintToStringParamName());
502
503TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
dschinazi42fc2da2020-04-24 16:19:17 -0700504 if (version_.UsesQuicCrypto()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 return;
506 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500507 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
508
509 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700510 CreateQuicSession(TestConnectionId(1), _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800511 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800512 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500513 dispatcher_.get(), config_, TestConnectionId(1), client_address,
514 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800515 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500516 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
517 ProcessUdpPacket(_, _, _))
518 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
519 ValidatePacket(TestConnectionId(1), packet);
520 })));
521 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700522 ShouldCreateOrBufferPacketForConnection(
523 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700524
525 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526}
527
dschinazi0e3c3482020-04-24 11:37:20 -0700528void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
529 bool add_reordering) {
dschinazi42fc2da2020-04-24 16:19:17 -0700530 if (!version_.UsesTls()) {
dschinazi0e3c3482020-04-24 11:37:20 -0700531 return;
532 }
533 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
534 QuicConnectionId server_connection_id = TestConnectionId();
535 QuicConfig client_config = DefaultQuicConfig();
536 // Add a 2000-byte custom parameter to increase the length of the CHLO.
537 constexpr auto kCustomParameterId =
538 static_cast<TransportParameters::TransportParameterId>(0xff33);
539 std::string kCustomParameterValue(2000, '-');
540 client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
541 kCustomParameterValue;
542 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
543 GetFirstFlightOfPackets(version_, client_config, server_connection_id);
544 ASSERT_EQ(packets.size(), 2u);
545 if (add_reordering) {
546 std::swap(packets[0], packets[1]);
547 }
548
549 // Processing the first packet should not create a new session.
550 EXPECT_CALL(*dispatcher_,
551 ShouldCreateOrBufferPacketForConnection(
552 ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
553 ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
554 server_connection_id);
555
556 EXPECT_EQ(dispatcher_->session_map().size(), 0u)
557 << "No session should be created before the rest of the CHLO arrives.";
558
559 // Processing the second packet should create the new session.
560 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700561 CreateQuicSession(server_connection_id, _, client_address,
dschinazi0e3c3482020-04-24 11:37:20 -0700562 Eq(ExpectedAlpn()), _))
563 .WillOnce(Return(ByMove(CreateSession(
564 dispatcher_.get(), config_, server_connection_id, client_address,
565 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
566 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
567 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
568 ProcessUdpPacket(_, _, _))
569 .Times(2);
570
571 ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
572 server_connection_id);
573 EXPECT_EQ(dispatcher_->session_map().size(), 1u);
574}
575
576TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
577 TestTlsMultiPacketClientHello(/*add_reordering=*/false);
578}
579
580TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
581 TestTlsMultiPacketClientHello(/*add_reordering=*/true);
582}
583
dschinazi6458eb32020-06-23 12:38:41 -0700584TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
585 if (!version_.HasLongHeaderLengths()) {
586 // Decapsulating Legacy Version Encapsulation packets from these versions
587 // is not currently supported in QuicDispatcher.
588 return;
589 }
590 SetQuicReloadableFlag(quic_dont_pad_chlo, true);
591 SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
592 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
593 QuicConnectionId server_connection_id = TestConnectionId();
594 QuicConfig client_config = DefaultQuicConfig();
595 client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
596 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
597 GetFirstFlightOfPackets(version_, client_config, server_connection_id);
598 ASSERT_EQ(packets.size(), 1u);
599
600 // Validate that Legacy Version Encapsulation is actually being used by
601 // checking the version of the packet before processing it.
602 PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
603 QuicLongHeaderType long_packet_type;
604 bool version_present;
605 bool has_length_prefix;
606 QuicVersionLabel version_label;
607 ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
608 QuicConnectionId destination_connection_id, source_connection_id;
609 bool retry_token_present;
610 quiche::QuicheStringPiece retry_token;
611 std::string detailed_error;
612 const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
613 QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
614 kQuicDefaultConnectionIdLength, &format, &long_packet_type,
615 &version_present, &has_length_prefix, &version_label, &parsed_version,
616 &destination_connection_id, &source_connection_id, &retry_token_present,
617 &retry_token, &detailed_error);
618 ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
619 EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
620 EXPECT_TRUE(version_present);
621 EXPECT_FALSE(has_length_prefix);
622 EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
623 EXPECT_EQ(destination_connection_id, server_connection_id);
624 EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
625 EXPECT_FALSE(retry_token_present);
626 EXPECT_TRUE(detailed_error.empty());
627
628 // Processing the packet should create a new session.
629 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700630 CreateQuicSession(server_connection_id, _, client_address,
dschinazi6458eb32020-06-23 12:38:41 -0700631 Eq(ExpectedAlpn()), _))
632 .WillOnce(Return(ByMove(CreateSession(
633 dispatcher_.get(), config_, server_connection_id, client_address,
634 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
635 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
636 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
637 ProcessUdpPacket(_, _, _))
638 .Times(2);
639
640 ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
641 server_connection_id);
642 EXPECT_EQ(dispatcher_->session_map().size(), 1u);
643
644 // Processing the same packet a second time should also be routed by the
645 // dispatcher to the right connection (we expect ProcessUdpPacket to be
646 // called twice, see the EXPECT_CALL above).
647 ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
648 server_connection_id);
649}
650
dschinazi8d1c9d42020-02-18 13:12:20 -0800651TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500652 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
653
654 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700655 CreateQuicSession(TestConnectionId(1), _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800656 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800657 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500658 dispatcher_.get(), config_, TestConnectionId(1), client_address,
659 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800660 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500661 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
662 ProcessUdpPacket(_, _, _))
663 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
664 ValidatePacket(TestConnectionId(1), packet);
665 })));
666 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700667 ShouldCreateOrBufferPacketForConnection(
668 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700669 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500670
671 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700672 CreateQuicSession(TestConnectionId(2), _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800673 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800674 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500675 dispatcher_.get(), config_, TestConnectionId(2), client_address,
676 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800677 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500678 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
679 ProcessUdpPacket(_, _, _))
680 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
681 ValidatePacket(TestConnectionId(2), packet);
682 })));
683 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700684 ShouldCreateOrBufferPacketForConnection(
685 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700686 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500687
688 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
689 ProcessUdpPacket(_, _, _))
690 .Times(1)
691 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
692 ValidatePacket(TestConnectionId(1), packet);
693 })));
694 ProcessPacket(client_address, TestConnectionId(1), false, "data");
695}
696
697// Regression test of b/93325907.
dschinazi8d1c9d42020-02-18 13:12:20 -0800698TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500699 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
700
701 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700702 CreateQuicSession(TestConnectionId(1), _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800703 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800704 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500705 dispatcher_.get(), config_, TestConnectionId(1), client_address,
706 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800707 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500708 // Verify both packets 1 and 2 are processed by connection 1.
709 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
710 ProcessUdpPacket(_, _, _))
711 .Times(2)
712 .WillRepeatedly(
713 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
714 ValidatePacket(TestConnectionId(1), packet);
715 })));
716 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700717 ShouldCreateOrBufferPacketForConnection(
718 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700719 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500720 // Packet number 256 with packet number length 1 would be considered as 0 in
721 // dispatcher.
dschinazi8d1c9d42020-02-18 13:12:20 -0800722 ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
723 CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500724}
725
dschinazi8d1c9d42020-02-18 13:12:20 -0800726TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727 CreateTimeWaitListManager();
728 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
729
wub4e3fb902020-07-15 13:37:29 -0700730 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi346b7ce2019-06-05 01:38:18 -0700731 EXPECT_CALL(
732 *time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700733 SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500734 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700735 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
736 TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500737}
738
dschinazi8d1c9d42020-02-18 13:12:20 -0800739TEST_P(QuicDispatcherTestOneVersion,
dschinaziffa83552019-12-17 11:00:23 -0800740 StatelessVersionNegotiationWithVeryLongConnectionId) {
dschinaziffa83552019-12-17 11:00:23 -0800741 QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
742 CreateTimeWaitListManager();
743 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
744
wub4e3fb902020-07-15 13:37:29 -0700745 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinaziffa83552019-12-17 11:00:23 -0800746 EXPECT_CALL(*time_wait_list_manager_,
747 SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
748 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700749 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
750 connection_id);
dschinaziffa83552019-12-17 11:00:23 -0800751}
752
dschinazi8d1c9d42020-02-18 13:12:20 -0800753TEST_P(QuicDispatcherTestOneVersion,
754 StatelessVersionNegotiationWithClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700755 CreateTimeWaitListManager();
756 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
757
wub4e3fb902020-07-15 13:37:29 -0700758 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi346b7ce2019-06-05 01:38:18 -0700759 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700760 SendVersionNegotiationPacket(
761 TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
dschinazi346b7ce2019-06-05 01:38:18 -0700762 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700763 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
764 TestConnectionId(1), TestConnectionId(2));
dschinazi346b7ce2019-06-05 01:38:18 -0700765}
766
dschinazi8d1c9d42020-02-18 13:12:20 -0800767TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500768 CreateTimeWaitListManager();
769 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
770
wub4e3fb902020-07-15 13:37:29 -0700771 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500772 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700773 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500774 .Times(0);
vasilvvc48c8712019-03-11 13:38:16 -0700775 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500776 // Truncate to 1100 bytes of payload which results in a packet just
777 // under 1200 bytes after framing, packet, and encryption overhead.
778 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700779 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500780 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700781 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700782 QuicVersionReservedForNegotiation(), truncated_chlo, false,
nharper4fd11052019-06-04 14:23:22 -0700783 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500784}
785
786// Disabling CHLO size validation allows the dispatcher to send version
787// negotiation packets in response to a CHLO that is otherwise too small.
dschinazi8d1c9d42020-02-18 13:12:20 -0800788TEST_P(QuicDispatcherTestOneVersion,
789 VersionNegotiationWithoutChloSizeValidation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500790 crypto_config_.set_validate_chlo_size(false);
791
792 CreateTimeWaitListManager();
793 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
794
wub4e3fb902020-07-15 13:37:29 -0700795 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500796 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700797 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500798 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -0700799 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500800 // Truncate to 1100 bytes of payload which results in a packet just
801 // under 1200 bytes after framing, packet, and encryption overhead.
802 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700803 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500804 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700805 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700806 QuicVersionReservedForNegotiation(), truncated_chlo, true,
nharper4fd11052019-06-04 14:23:22 -0700807 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500808}
809
dschinazi8d1c9d42020-02-18 13:12:20 -0800810TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500811 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
812
dschinazi8d1c9d42020-02-18 13:12:20 -0800813 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700814 CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800815 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500816 dispatcher_.get(), config_, TestConnectionId(1), client_address,
817 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800818 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500819 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
820 ProcessUdpPacket(_, _, _))
821 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
822 ValidatePacket(TestConnectionId(1), packet);
823 })));
824
825 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700826 ShouldCreateOrBufferPacketForConnection(
827 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700828 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500829
830 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
831 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
832
833 dispatcher_->Shutdown();
834}
835
dschinazi8d1c9d42020-02-18 13:12:20 -0800836TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500837 CreateTimeWaitListManager();
838
839 // Create a new session.
840 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
841 QuicConnectionId connection_id = TestConnectionId(1);
wub4e3fb902020-07-15 13:37:29 -0700842 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800843 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800844 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500845 dispatcher_.get(), config_, connection_id, client_address,
846 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800847 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500848 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
849 ProcessUdpPacket(_, _, _))
850 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
851 ValidatePacket(TestConnectionId(1), packet);
852 })));
853
854 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700855 ShouldCreateOrBufferPacketForConnection(
856 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700857 ProcessFirstFlight(client_address, connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858
859 // Now close the connection, which should add it to the time wait list.
860 session1_->connection()->CloseConnection(
861 QUIC_INVALID_VERSION,
862 "Server: Packet 2 without version flag before version negotiated.",
863 ConnectionCloseBehavior::SILENT_CLOSE);
864 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
865
866 // Dispatcher forwards subsequent packets for this connection_id to the time
867 // wait list manager.
868 EXPECT_CALL(*time_wait_list_manager_,
869 ProcessPacket(_, _, connection_id, _, _))
870 .Times(1);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700871 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500872 .Times(0);
873 ProcessPacket(client_address, connection_id, true, "data");
874}
875
dschinazi8d1c9d42020-02-18 13:12:20 -0800876TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500877 CreateTimeWaitListManager();
878
879 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
880 QuicConnectionId connection_id = TestConnectionId(1);
881 // Dispatcher forwards all packets for this connection_id to the time wait
882 // list manager.
wub4e3fb902020-07-15 13:37:29 -0700883 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800884 EXPECT_CALL(*time_wait_list_manager_,
885 ProcessPacket(_, _, connection_id, _, _))
886 .Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700887 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
fayang9d6231c2019-12-04 07:10:13 -0800888 .Times(0);
889 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
890 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700891 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
892 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500893}
894
dschinazi8d1c9d42020-02-18 13:12:20 -0800895TEST_P(QuicDispatcherTestAllVersions,
fayangd057e662019-07-10 13:29:41 -0700896 DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
897 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
898 CreateTimeWaitListManager();
899
900 char short_packet[22] = {0x70, 0xa7, 0x02, 0x6b};
901 QuicReceivedPacket packet(short_packet, 22, QuicTime::Zero());
902 char valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
903 QuicReceivedPacket packet2(valid_size_packet, 23, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -0700904 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800905 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700906 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
fayang9d6231c2019-12-04 07:10:13 -0800907 .Times(0);
908 // Verify small packet is silently dropped.
909 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
910 .Times(0);
fayangd057e662019-07-10 13:29:41 -0700911 dispatcher_->ProcessPacket(server_address_, client_address, packet);
fayang9d6231c2019-12-04 07:10:13 -0800912 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
913 .Times(1);
fayangd057e662019-07-10 13:29:41 -0700914 dispatcher_->ProcessPacket(server_address_, client_address, packet2);
915}
916
QUICHE teamc65d1d12019-03-19 20:58:04 -0700917// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800918TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
919 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700920 // When variable length connection IDs are not supported, the connection
921 // fails. See StrayPacketTruncatedConnectionId.
QUICHE team8e2e4532019-03-14 14:37:56 -0700922 return;
923 }
QUICHE team8e2e4532019-03-14 14:37:56 -0700924 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
925
QUICHE teamc65d1d12019-03-19 20:58:04 -0700926 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700927 QuicConnectionId fixed_connection_id =
928 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700929
930 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700931 CreateQuicSession(fixed_connection_id, _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800932 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800933 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700934 dispatcher_.get(), config_, fixed_connection_id, client_address,
935 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800936 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -0700937 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
938 ProcessUdpPacket(_, _, _))
939 .WillOnce(WithArg<2>(
940 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
941 ValidatePacket(bad_connection_id, packet);
942 })));
943 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700944 ShouldCreateOrBufferPacketForConnection(
945 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700946 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700947}
948
QUICHE team963d57e2019-03-21 10:58:47 -0700949// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800950TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
951 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team963d57e2019-03-21 10:58:47 -0700952 // When variable length connection IDs are not supported, the connection
953 // fails. See StrayPacketTruncatedConnectionId.
954 return;
955 }
956 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
957
958 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
dschinazi28c1bf32019-08-19 11:54:46 -0700959 QuicConnectionId fixed_connection_id =
960 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700961
962 // Disable validation of invalid short connection IDs.
dschinazi7b9278c2019-05-20 07:36:21 -0700963 dispatcher_->SetAllowShortInitialServerConnectionIds(true);
QUICHE team963d57e2019-03-21 10:58:47 -0700964 // Note that StrayPacketTruncatedConnectionId covers the case where the
965 // validation is still enabled.
966
967 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700968 CreateQuicSession(fixed_connection_id, _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800969 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800970 .WillOnce(Return(ByMove(CreateSession(
QUICHE team963d57e2019-03-21 10:58:47 -0700971 dispatcher_.get(), config_, fixed_connection_id, client_address,
972 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800973 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team963d57e2019-03-21 10:58:47 -0700974 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
975 ProcessUdpPacket(_, _, _))
976 .WillOnce(WithArg<2>(
977 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
978 ValidatePacket(bad_connection_id, packet);
979 })));
980 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700981 ShouldCreateOrBufferPacketForConnection(
982 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700983 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700984}
985
QUICHE teamc65d1d12019-03-19 20:58:04 -0700986// Makes sure TestConnectionId(1) creates a new connection and
987// TestConnectionIdNineBytesLong(2) gets replaced.
dschinazi8d1c9d42020-02-18 13:12:20 -0800988TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
989 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700990 return;
991 }
QUICHE teamc65d1d12019-03-19 20:58:04 -0700992
QUICHE team8e2e4532019-03-14 14:37:56 -0700993 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700994 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700995 QuicConnectionId fixed_connection_id =
996 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700997
998 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -0700999 CreateQuicSession(TestConnectionId(1), _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -08001000 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001001 .WillOnce(Return(ByMove(CreateSession(
QUICHE team8e2e4532019-03-14 14:37:56 -07001002 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1003 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001004 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team8e2e4532019-03-14 14:37:56 -07001005 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1006 ProcessUdpPacket(_, _, _))
1007 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1008 ValidatePacket(TestConnectionId(1), packet);
1009 })));
1010 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001011 ShouldCreateOrBufferPacketForConnection(
1012 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001013 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE team8e2e4532019-03-14 14:37:56 -07001014
QUICHE teamc65d1d12019-03-19 20:58:04 -07001015 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001016 CreateQuicSession(fixed_connection_id, _, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -08001017 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001018 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -07001019 dispatcher_.get(), config_, fixed_connection_id, client_address,
1020 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001021 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -07001022 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1023 ProcessUdpPacket(_, _, _))
1024 .WillOnce(WithArg<2>(
1025 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
1026 ValidatePacket(bad_connection_id, packet);
1027 })));
1028 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001029 ShouldCreateOrBufferPacketForConnection(
1030 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -07001031 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -07001032
1033 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1034 ProcessUdpPacket(_, _, _))
1035 .Times(1)
1036 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1037 ValidatePacket(TestConnectionId(1), packet);
1038 })));
1039 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1040}
1041
dschinazi8d1c9d42020-02-18 13:12:20 -08001042TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001043 CreateTimeWaitListManager();
1044
1045 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
1046
1047 // dispatcher_ should drop this packet.
1048 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001049 CreateQuicSession(TestConnectionId(1), _, client_address, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001050 .Times(0);
1051 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001052 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001053 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -07001054 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1055 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -05001056}
1057
dschinazi8d1c9d42020-02-18 13:12:20 -08001058TEST_P(QuicDispatcherTestAllVersions,
1059 ProcessPacketWithInvalidShortInitialConnectionId) {
1060 if (!version_.AllowsVariableLengthConnectionIds()) {
1061 return;
1062 }
dschinaziee07e472019-06-19 09:56:56 -07001063 CreateTimeWaitListManager();
1064
1065 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1066
1067 // dispatcher_ should drop this packet.
wub4e3fb902020-07-15 13:37:29 -07001068 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, client_address, _, _))
dschinaziee07e472019-06-19 09:56:56 -07001069 .Times(0);
1070 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001071 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
dschinaziee07e472019-06-19 09:56:56 -07001072 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -07001073 ProcessFirstFlight(client_address, EmptyQuicConnectionId());
dschinaziee07e472019-06-19 09:56:56 -07001074}
1075
dschinazi8d1c9d42020-02-18 13:12:20 -08001076TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
fayangb880b4c2019-06-14 12:26:35 -07001077 VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
dschinazi8d1c9d42020-02-18 13:12:20 -08001078 for (ParsedQuicVersion version : CurrentSupportedVersions()) {
1079 VerifyVersionSupported(version);
dschinazi5a50d932020-06-17 12:43:36 -07001080 QuicDisableVersion(version);
1081 VerifyVersionNotSupported(version);
1082 QuicEnableVersion(version);
1083 VerifyVersionSupported(version);
dschinazi8d1c9d42020-02-18 13:12:20 -08001084 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001085}
1086
dschinazi8d1c9d42020-02-18 13:12:20 -08001087TEST_P(QuicDispatcherTestOneVersion,
1088 RejectDeprecatedVersionsWithVersionNegotiation) {
dschinaziceed8662020-07-14 09:37:05 -07001089 static_assert(quic::SupportedVersions().size() == 7u,
fayangb54ac5b2019-07-01 10:30:37 -07001090 "Please add deprecated versions to this test");
1091 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1092 CreateTimeWaitListManager();
1093
dschinazi8b1c45a2019-10-17 08:48:13 -07001094 {
dschinaziceed8662020-07-14 09:37:05 -07001095 char packet49[kMinPacketSizeForVersionNegotiation] = {
1096 0xC0, 'Q', '0', '4', '9', /*connection ID length byte*/ 0x50};
1097 QuicReceivedPacket received_packet49(
1098 packet49, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -07001099 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinaziceed8662020-07-14 09:37:05 -07001100 EXPECT_CALL(*time_wait_list_manager_,
1101 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1102 .Times(1);
1103 dispatcher_->ProcessPacket(server_address_, client_address,
1104 received_packet49);
1105 }
1106
1107 {
1108 char packet48[kMinPacketSizeForVersionNegotiation] = {
1109 0xC0, 'Q', '0', '4', '8', /*connection ID length byte*/ 0x50};
1110 QuicReceivedPacket received_packet48(
1111 packet48, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -07001112 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinaziceed8662020-07-14 09:37:05 -07001113 EXPECT_CALL(*time_wait_list_manager_,
1114 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1115 .Times(1);
1116 dispatcher_->ProcessPacket(server_address_, client_address,
1117 received_packet48);
1118 }
1119
1120 {
dschinazi8b1c45a2019-10-17 08:48:13 -07001121 char packet47[kMinPacketSizeForVersionNegotiation] = {
1122 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
1123 QuicReceivedPacket received_packet47(
1124 packet47, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -07001125 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi8b1c45a2019-10-17 08:48:13 -07001126 EXPECT_CALL(*time_wait_list_manager_,
1127 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1128 .Times(1);
1129 dispatcher_->ProcessPacket(server_address_, client_address,
1130 received_packet47);
1131 }
fayang36825da2019-08-21 14:01:27 -07001132
dschinazi8b1c45a2019-10-17 08:48:13 -07001133 {
1134 char packet45[kMinPacketSizeForVersionNegotiation] = {
1135 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
1136 QuicReceivedPacket received_packet45(
1137 packet45, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -07001138 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi8b1c45a2019-10-17 08:48:13 -07001139 EXPECT_CALL(*time_wait_list_manager_,
1140 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1141 .Times(1);
1142 dispatcher_->ProcessPacket(server_address_, client_address,
1143 received_packet45);
1144 }
1145
1146 {
1147 char packet44[kMinPacketSizeForVersionNegotiation] = {
1148 0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
1149 QuicReceivedPacket received_packet44(
1150 packet44, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
wub4e3fb902020-07-15 13:37:29 -07001151 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi8b1c45a2019-10-17 08:48:13 -07001152 EXPECT_CALL(*time_wait_list_manager_,
1153 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1154 .Times(1);
1155 dispatcher_->ProcessPacket(server_address_, client_address,
1156 received_packet44);
1157 }
fayangb54ac5b2019-07-01 10:30:37 -07001158}
1159
dschinazi8d1c9d42020-02-18 13:12:20 -08001160TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeOld) {
dschinazi30ab6db2019-08-13 14:43:32 -07001161 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi30ab6db2019-08-13 14:43:32 -07001162 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1163 CreateTimeWaitListManager();
1164 char packet[1200];
1165 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1166 0x6c, 0x7a, 0x20, 0x21};
1167 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1168 packet, sizeof(packet), destination_connection_id_bytes,
1169 sizeof(destination_connection_id_bytes)));
1170 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1171 std::unique_ptr<QuicReceivedPacket> received_packet(
1172 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1173 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1174 QuicConnectionId server_connection_id(
1175 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1176 bool ietf_quic = true;
1177 bool use_length_prefix =
1178 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1179 EXPECT_CALL(
1180 *time_wait_list_manager_,
1181 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1182 ietf_quic, use_length_prefix, _, _, _, _))
1183 .Times(1);
wub4e3fb902020-07-15 13:37:29 -07001184 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi30ab6db2019-08-13 14:43:32 -07001185
1186 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1187}
1188
dschinazi8d1c9d42020-02-18 13:12:20 -08001189TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
dschinazi30ab6db2019-08-13 14:43:32 -07001190 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi30ab6db2019-08-13 14:43:32 -07001191 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1192 CreateTimeWaitListManager();
1193 char packet[1200];
1194 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1195 0x6c, 0x7a, 0x20, 0x21};
1196 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1197 packet, sizeof(packet), destination_connection_id_bytes,
1198 sizeof(destination_connection_id_bytes)));
1199 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1200 std::unique_ptr<QuicReceivedPacket> received_packet(
1201 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1202 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1203 QuicConnectionId server_connection_id(
1204 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1205 bool ietf_quic = true;
1206 bool use_length_prefix =
1207 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1208 EXPECT_CALL(
1209 *time_wait_list_manager_,
1210 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1211 ietf_quic, use_length_prefix, _, _, _, _))
1212 .Times(1);
wub4e3fb902020-07-15 13:37:29 -07001213 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi30ab6db2019-08-13 14:43:32 -07001214
1215 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1216}
1217
dschinazi0185ebb2019-08-14 11:09:35 -07001218// Testing packet writer that saves all packets instead of sending them.
1219// Useful for tests that need access to sent packets.
1220class SavingWriter : public QuicPacketWriterWrapper {
1221 public:
1222 bool IsWriteBlocked() const override { return false; }
1223
1224 WriteResult WritePacket(const char* buffer,
1225 size_t buf_len,
1226 const QuicIpAddress& /*self_client_address*/,
1227 const QuicSocketAddress& /*peer_client_address*/,
1228 PerPacketOptions* /*options*/) override {
1229 packets_.push_back(
1230 QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
1231 return WriteResult(WRITE_STATUS_OK, buf_len);
1232 }
1233
1234 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
1235 return &packets_;
1236 }
1237
1238 private:
1239 std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
1240};
1241
dschinazi8d1c9d42020-02-18 13:12:20 -08001242TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) {
dschinazi0185ebb2019-08-14 11:09:35 -07001243 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi0185ebb2019-08-14 11:09:35 -07001244
1245 SavingWriter* saving_writer = new SavingWriter();
1246 // dispatcher_ takes ownership of saving_writer.
1247 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1248
1249 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1250 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1251 &mock_alarm_factory_);
1252 // dispatcher_ takes ownership of time_wait_list_manager.
1253 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1254 time_wait_list_manager);
1255 char packet[1200] = {};
1256 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1257 0x6c, 0x7a, 0x20, 0x21};
1258 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1259 packet, sizeof(packet), destination_connection_id_bytes,
1260 sizeof(destination_connection_id_bytes)));
1261 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1262 std::unique_ptr<QuicReceivedPacket> received_packet(
1263 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
wub4e3fb902020-07-15 13:37:29 -07001264 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi0185ebb2019-08-14 11:09:35 -07001265
1266 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1267 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1268 ASSERT_EQ(1u, saving_writer->packets()->size());
1269
1270 char source_connection_id_bytes[255] = {};
1271 uint8_t source_connection_id_length = 0;
1272 std::string detailed_error = "foobar";
1273 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1274 (*(saving_writer->packets()))[0]->data(),
1275 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1276 &source_connection_id_length, &detailed_error));
1277 EXPECT_EQ("", detailed_error);
1278
1279 // The source connection ID of the probe response should match the
1280 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001281 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001282 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1283 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1284}
1285
dschinazi8d1c9d42020-02-18 13:12:20 -08001286TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
dschinazi0185ebb2019-08-14 11:09:35 -07001287 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi0185ebb2019-08-14 11:09:35 -07001288
1289 SavingWriter* saving_writer = new SavingWriter();
1290 // dispatcher_ takes ownership of saving_writer.
1291 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1292
1293 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1294 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1295 &mock_alarm_factory_);
1296 // dispatcher_ takes ownership of time_wait_list_manager.
1297 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1298 time_wait_list_manager);
1299 char packet[1200] = {};
1300 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1301 0x6c, 0x7a, 0x20, 0x21};
1302 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1303 packet, sizeof(packet), destination_connection_id_bytes,
1304 sizeof(destination_connection_id_bytes)));
1305 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1306 std::unique_ptr<QuicReceivedPacket> received_packet(
1307 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
wub4e3fb902020-07-15 13:37:29 -07001308 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi0185ebb2019-08-14 11:09:35 -07001309
1310 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1311 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1312 ASSERT_EQ(1u, saving_writer->packets()->size());
1313
1314 char source_connection_id_bytes[255] = {};
1315 uint8_t source_connection_id_length = 0;
1316 std::string detailed_error = "foobar";
1317 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1318 (*(saving_writer->packets()))[0]->data(),
1319 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1320 &source_connection_id_length, &detailed_error));
1321 EXPECT_EQ("", detailed_error);
1322
1323 // The source connection ID of the probe response should match the
1324 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001325 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001326 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1327 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1328}
1329
dschinazi8d1c9d42020-02-18 13:12:20 -08001330TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
dschinazi5b236be2019-08-19 14:55:22 -07001331 // WARNING: do not remove or modify this test without making sure that we
1332 // still have adequate coverage for the Android conformance test.
dschinazi5b236be2019-08-19 14:55:22 -07001333 SavingWriter* saving_writer = new SavingWriter();
1334 // dispatcher_ takes ownership of saving_writer.
1335 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1336
1337 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1338 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1339 &mock_alarm_factory_);
1340 // dispatcher_ takes ownership of time_wait_list_manager.
1341 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1342 time_wait_list_manager);
1343 // clang-format off
1344 static const unsigned char packet[1200] = {
1345 // Android UDP network conformance test packet as it was after this change:
1346 // https://android-review.googlesource.com/c/platform/cts/+/1104285
1347 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number
1348 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
1349 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number
1350 0x01, // 1-byte packet number
1351 0x00, // private flags
1352 0x07, // PING frame
1353 };
1354 // clang-format on
1355
1356 QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
1357 sizeof(packet), false);
1358 std::unique_ptr<QuicReceivedPacket> received_packet(
1359 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
wub4e3fb902020-07-15 13:37:29 -07001360 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi5b236be2019-08-19 14:55:22 -07001361
1362 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1363 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1364 ASSERT_EQ(1u, saving_writer->packets()->size());
1365
1366 // The Android UDP network conformance test directly checks that bytes 1-9
1367 // of the response match the connection ID that was sent.
1368 static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
1369 0x75, 0x76, 0x77, 0x78};
1370 ASSERT_GE((*(saving_writer->packets()))[0]->length(),
1371 1u + sizeof(connection_id_bytes));
dmcardle8f7df532020-01-07 13:28:57 -08001372 quiche::test::CompareCharArraysWithHexError(
dschinazi5b236be2019-08-19 14:55:22 -07001373 "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
1374 sizeof(connection_id_bytes), connection_id_bytes,
1375 sizeof(connection_id_bytes));
1376}
1377
dschinazi8d1c9d42020-02-18 13:12:20 -08001378TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
dschinazi942a9f82020-06-19 09:23:20 -07001379 if (!version_.HasIetfInvariantHeader() &&
1380 !GetQuicReloadableFlag(quic_dont_pad_chlo)) {
1381 // When quic_dont_pad_chlo is false, we only drop small packets when using
1382 // IETF_QUIC_LONG_HEADER_PACKET. When quic_dont_pad_chlo is true, we drop
1383 // small packets for all versions.
1384 // TODO(dschinazi) remove this early return when we deprecate the flag.
dschinazi8d1c9d42020-02-18 13:12:20 -08001385 return;
1386 }
fayange3f2f7b2019-09-19 17:01:57 -07001387 CreateTimeWaitListManager();
1388 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1389
wub4e3fb902020-07-15 13:37:29 -07001390 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazicdc73612020-03-02 10:34:01 -08001391 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001392 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
rch9d76c2d2019-12-20 12:19:48 -08001393 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001394 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1395 version_, SerializeCHLO(), /*full_padding=*/false,
fayange3f2f7b2019-09-19 17:01:57 -07001396 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
1397}
1398
dschinazi8d1c9d42020-02-18 13:12:20 -08001399TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
fayange3f2f7b2019-09-19 17:01:57 -07001400 CreateTimeWaitListManager();
1401 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1402
1403 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
1404
1405 // clang-format off
1406 char coalesced_packet[1200] = {
1407 // first coalesced packet
1408 // public flags (long header with packet type INITIAL and
1409 // 4-byte packet number)
1410 0xC3,
1411 // version
1412 'Q', '0', '9', '9',
1413 // destination connection ID length
1414 0x08,
1415 // destination connection ID
1416 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1417 // source connection ID length
1418 0x00,
1419 // long header packet length
1420 0x05,
1421 // packet number
1422 0x12, 0x34, 0x56, 0x78,
1423 // Padding
1424 0x00,
1425 // second coalesced packet
1426 // public flags (long header with packet type ZERO_RTT_PROTECTED and
1427 // 4-byte packet number)
1428 0xC3,
1429 // version
1430 'Q', '0', '9', '9',
1431 // destination connection ID length
1432 0x08,
1433 // destination connection ID
1434 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1435 // source connection ID length
1436 0x00,
1437 // long header packet length
1438 0x1E,
1439 // packet number
1440 0x12, 0x34, 0x56, 0x79,
1441 };
1442 // clang-format on
1443 QuicReceivedPacket packet(coalesced_packet, 1200, QuicTime::Zero());
1444 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1445}
1446
danzh72e0dab2020-03-05 20:00:50 -08001447TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
1448 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1449
1450 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001451 CreateQuicSession(TestConnectionId(1), _, client_address,
danzh72e0dab2020-03-05 20:00:50 -08001452 Eq(ExpectedAlpn()), _))
1453 .WillOnce(Return(ByMove(CreateSession(
1454 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1455 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1456 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1457 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1458 ProcessUdpPacket(_, _, _))
1459 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1460 ValidatePacket(TestConnectionId(1), packet);
1461 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001462 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001463
1464 dispatcher_->StopAcceptingNewConnections();
1465 EXPECT_FALSE(dispatcher_->accept_new_connections());
1466
1467 // No more new connections afterwards.
1468 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001469 CreateQuicSession(TestConnectionId(2), _, client_address,
danzh72e0dab2020-03-05 20:00:50 -08001470 Eq(ExpectedAlpn()), _))
1471 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001472 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001473
1474 // Existing connections should be able to continue.
1475 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1476 ProcessUdpPacket(_, _, _))
1477 .Times(1u)
1478 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1479 ValidatePacket(TestConnectionId(1), packet);
1480 })));
1481 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1482}
1483
1484TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
1485 dispatcher_->StopAcceptingNewConnections();
1486 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1487
1488 // No more new connections afterwards.
1489 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001490 CreateQuicSession(TestConnectionId(2), _, client_address,
danzh72e0dab2020-03-05 20:00:50 -08001491 Eq(ExpectedAlpn()), _))
1492 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001493 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001494
1495 dispatcher_->StartAcceptingNewConnections();
1496 EXPECT_TRUE(dispatcher_->accept_new_connections());
1497
1498 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001499 CreateQuicSession(TestConnectionId(1), _, client_address,
danzh72e0dab2020-03-05 20:00:50 -08001500 Eq(ExpectedAlpn()), _))
1501 .WillOnce(Return(ByMove(CreateSession(
1502 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1503 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1504 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1505 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1506 ProcessUdpPacket(_, _, _))
1507 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1508 ValidatePacket(TestConnectionId(1), packet);
1509 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001510 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001511}
1512
dschinazi71116fd2020-04-22 16:07:04 -07001513TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
1514 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
1515 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
1516 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
1517 // Q033 is no longer supported but Q050 is.
1518 QuicEnableVersion(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
1519 EXPECT_EQ(
1520 QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
1521 "h3-Q050");
1522}
1523
QUICHE teama6ef0a62019-03-07 20:34:33 -05001524// Verify the stopgap test: Packets with truncated connection IDs should be
1525// dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001526class QuicDispatcherTestStrayPacketConnectionId
1527 : public QuicDispatcherTestBase {};
1528
1529INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
1530 QuicDispatcherTestStrayPacketConnectionId,
1531 ::testing::ValuesIn(CurrentSupportedVersions()),
1532 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001533
1534// Packets with truncated connection IDs should be dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001535TEST_P(QuicDispatcherTestStrayPacketConnectionId,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001536 StrayPacketTruncatedConnectionId) {
1537 CreateTimeWaitListManager();
1538
1539 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1540 QuicConnectionId connection_id = TestConnectionId(1);
wub4e3fb902020-07-15 13:37:29 -07001541 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _)).Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001542 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001543 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001544 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001545
QUICHE teama6ef0a62019-03-07 20:34:33 -05001546 ProcessPacket(client_address, connection_id, true, "data",
1547 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1548}
1549
1550class BlockingWriter : public QuicPacketWriterWrapper {
1551 public:
1552 BlockingWriter() : write_blocked_(false) {}
1553
1554 bool IsWriteBlocked() const override { return write_blocked_; }
1555 void SetWritable() override { write_blocked_ = false; }
1556
dschinazi17d42422019-06-18 16:35:07 -07001557 WriteResult WritePacket(const char* /*buffer*/,
1558 size_t /*buf_len*/,
1559 const QuicIpAddress& /*self_client_address*/,
1560 const QuicSocketAddress& /*peer_client_address*/,
1561 PerPacketOptions* /*options*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001562 // It would be quite possible to actually implement this method here with
1563 // the fake blocked status, but it would be significantly more work in
1564 // Chromium, and since it's not called anyway, don't bother.
1565 QUIC_LOG(DFATAL) << "Not supported";
1566 return WriteResult();
1567 }
1568
1569 bool write_blocked_;
1570};
1571
dschinazi8d1c9d42020-02-18 13:12:20 -08001572class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001573 public:
1574 void SetUp() override {
dschinazi8d1c9d42020-02-18 13:12:20 -08001575 QuicDispatcherTestBase::SetUp();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001576 writer_ = new BlockingWriter;
1577 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1578
1579 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1580
1581 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001582 CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001583 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001584 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1585 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001586 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001587 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1588 ProcessUdpPacket(_, _, _))
1589 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1590 ValidatePacket(TestConnectionId(1), packet);
1591 })));
fayang1ed1f762019-06-24 11:40:04 -07001592 EXPECT_CALL(*dispatcher_,
1593 ShouldCreateOrBufferPacketForConnection(
1594 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001595 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001596
1597 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07001598 CreateQuicSession(_, _, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001599 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001600 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1601 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001602 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001603 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1604 ProcessUdpPacket(_, _, _))
1605 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1606 ValidatePacket(TestConnectionId(2), packet);
1607 })));
fayang1ed1f762019-06-24 11:40:04 -07001608 EXPECT_CALL(*dispatcher_,
1609 ShouldCreateOrBufferPacketForConnection(
1610 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001611 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001612
1613 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1614 }
1615
1616 void TearDown() override {
1617 if (connection1() != nullptr) {
1618 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1619 }
1620
1621 if (connection2() != nullptr) {
1622 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1623 }
1624 dispatcher_->Shutdown();
1625 }
1626
1627 // Set the dispatcher's writer to be blocked. By default, all connections use
1628 // the same writer as the dispatcher in this test.
1629 void SetBlocked() {
1630 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1631 writer_->write_blocked_ = true;
1632 }
1633
1634 // Simulate what happens when connection1 gets blocked when writing.
1635 void BlockConnection1() {
1636 Connection1Writer()->write_blocked_ = true;
1637 dispatcher_->OnWriteBlocked(connection1());
1638 }
1639
1640 BlockingWriter* Connection1Writer() {
1641 return static_cast<BlockingWriter*>(connection1()->writer());
1642 }
1643
1644 // Simulate what happens when connection2 gets blocked when writing.
1645 void BlockConnection2() {
1646 Connection2Writer()->write_blocked_ = true;
1647 dispatcher_->OnWriteBlocked(connection2());
1648 }
1649
1650 BlockingWriter* Connection2Writer() {
1651 return static_cast<BlockingWriter*>(connection2()->writer());
1652 }
1653
1654 protected:
1655 MockQuicConnectionHelper helper_;
1656 MockAlarmFactory alarm_factory_;
1657 BlockingWriter* writer_;
1658 QuicDispatcher::WriteBlockedList* blocked_list_;
1659};
1660
dschinazi8d1c9d42020-02-18 13:12:20 -08001661INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
1662 QuicDispatcherWriteBlockedListTest,
1663 ::testing::Values(CurrentSupportedVersions().front()),
1664 ::testing::PrintToStringParamName());
1665
1666TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001667 // No OnCanWrite calls because no connections are blocked.
1668 dispatcher_->OnCanWrite();
1669
1670 // Register connection 1 for events, and make sure it's notified.
1671 SetBlocked();
1672 dispatcher_->OnWriteBlocked(connection1());
1673 EXPECT_CALL(*connection1(), OnCanWrite());
1674 dispatcher_->OnCanWrite();
1675
1676 // It should get only one notification.
1677 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1678 dispatcher_->OnCanWrite();
1679 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1680}
1681
dschinazi8d1c9d42020-02-18 13:12:20 -08001682TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001683 // Make sure we handle events in order.
1684 InSequence s;
1685 SetBlocked();
1686 dispatcher_->OnWriteBlocked(connection1());
1687 dispatcher_->OnWriteBlocked(connection2());
1688 EXPECT_CALL(*connection1(), OnCanWrite());
1689 EXPECT_CALL(*connection2(), OnCanWrite());
1690 dispatcher_->OnCanWrite();
1691
1692 // Check the other ordering.
1693 SetBlocked();
1694 dispatcher_->OnWriteBlocked(connection2());
1695 dispatcher_->OnWriteBlocked(connection1());
1696 EXPECT_CALL(*connection2(), OnCanWrite());
1697 EXPECT_CALL(*connection1(), OnCanWrite());
1698 dispatcher_->OnCanWrite();
1699}
1700
dschinazi8d1c9d42020-02-18 13:12:20 -08001701TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001702 // Add and remove one connction.
1703 SetBlocked();
1704 dispatcher_->OnWriteBlocked(connection1());
1705 blocked_list_->erase(connection1());
1706 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1707 dispatcher_->OnCanWrite();
1708
1709 // Add and remove one connction and make sure it doesn't affect others.
1710 SetBlocked();
1711 dispatcher_->OnWriteBlocked(connection1());
1712 dispatcher_->OnWriteBlocked(connection2());
1713 blocked_list_->erase(connection1());
1714 EXPECT_CALL(*connection2(), OnCanWrite());
1715 dispatcher_->OnCanWrite();
1716
1717 // Add it, remove it, and add it back and make sure things are OK.
1718 SetBlocked();
1719 dispatcher_->OnWriteBlocked(connection1());
1720 blocked_list_->erase(connection1());
1721 dispatcher_->OnWriteBlocked(connection1());
1722 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1723 dispatcher_->OnCanWrite();
1724}
1725
dschinazi8d1c9d42020-02-18 13:12:20 -08001726TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001727 // Make sure a double add does not necessitate a double remove.
1728 SetBlocked();
1729 dispatcher_->OnWriteBlocked(connection1());
1730 dispatcher_->OnWriteBlocked(connection1());
1731 blocked_list_->erase(connection1());
1732 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1733 dispatcher_->OnCanWrite();
1734
1735 // Make sure a double add does not result in two OnCanWrite calls.
1736 SetBlocked();
1737 dispatcher_->OnWriteBlocked(connection1());
1738 dispatcher_->OnWriteBlocked(connection1());
1739 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1740 dispatcher_->OnCanWrite();
1741}
1742
dschinazi8d1c9d42020-02-18 13:12:20 -08001743TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001744 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1745 // into the write blocked list.
1746 InSequence s;
1747 SetBlocked();
1748 dispatcher_->OnWriteBlocked(connection1());
1749 dispatcher_->OnWriteBlocked(connection2());
1750 EXPECT_CALL(*connection1(), OnCanWrite())
1751 .WillOnce(
1752 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1753 EXPECT_CALL(*connection2(), OnCanWrite());
1754 dispatcher_->OnCanWrite();
1755
1756 // connection1 should be still in the write blocked list.
1757 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1758
1759 // Now call OnCanWrite again, connection1 should get its second chance.
1760 EXPECT_CALL(*connection1(), OnCanWrite());
1761 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1762 dispatcher_->OnCanWrite();
1763 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1764}
1765
dschinazi8d1c9d42020-02-18 13:12:20 -08001766TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001767 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1768 // into the write blocked list.
1769 InSequence s;
1770 SetBlocked();
1771 dispatcher_->OnWriteBlocked(connection1());
1772 dispatcher_->OnWriteBlocked(connection2());
1773 EXPECT_CALL(*connection1(), OnCanWrite());
1774 EXPECT_CALL(*connection2(), OnCanWrite())
1775 .WillOnce(
1776 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1777 dispatcher_->OnCanWrite();
1778
1779 // connection2 should be still in the write blocked list.
1780 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1781
1782 // Now call OnCanWrite again, connection2 should get its second chance.
1783 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1784 EXPECT_CALL(*connection2(), OnCanWrite());
1785 dispatcher_->OnCanWrite();
1786 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1787}
1788
dschinazi8d1c9d42020-02-18 13:12:20 -08001789TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001790 OnCanWriteHandleBlockBothConnections) {
1791 // Both connections get blocked in OnCanWrite, and added back into the write
1792 // blocked list.
1793 InSequence s;
1794 SetBlocked();
1795 dispatcher_->OnWriteBlocked(connection1());
1796 dispatcher_->OnWriteBlocked(connection2());
1797 EXPECT_CALL(*connection1(), OnCanWrite())
1798 .WillOnce(
1799 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1800 EXPECT_CALL(*connection2(), OnCanWrite())
1801 .WillOnce(
1802 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1803 dispatcher_->OnCanWrite();
1804
1805 // Both connections should be still in the write blocked list.
1806 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1807
1808 // Now call OnCanWrite again, both connections should get its second chance.
1809 EXPECT_CALL(*connection1(), OnCanWrite());
1810 EXPECT_CALL(*connection2(), OnCanWrite());
1811 dispatcher_->OnCanWrite();
1812 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1813}
1814
dschinazi8d1c9d42020-02-18 13:12:20 -08001815TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001816 // By default, all connections share the same packet writer with the
1817 // dispatcher.
1818 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1819 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1820
1821 // Test the case where connection1 shares the same packet writer as the
1822 // dispatcher, whereas connection2 owns it's packet writer.
1823 // Change connection2's writer.
1824 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1825 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1826
1827 BlockConnection2();
1828 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1829
1830 EXPECT_CALL(*connection2(), OnCanWrite());
1831 dispatcher_->OnCanWrite();
1832 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1833}
1834
dschinazi8d1c9d42020-02-18 13:12:20 -08001835TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001836 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001837 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1838 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1839 ConnectionCloseSource::FROM_SELF);
1840
1841 SetBlocked();
1842
1843 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1844 SetBlocked();
1845 dispatcher_->OnWriteBlocked(connection1());
1846 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1847
1848 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1849 "QuicConnection was in WriteBlockedList before destruction");
1850 MarkSession1Deleted();
1851}
1852
dschinazi8d1c9d42020-02-18 13:12:20 -08001853class BufferedPacketStoreTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001854 public:
1855 BufferedPacketStoreTest()
dschinazi8d1c9d42020-02-18 13:12:20 -08001856 : QuicDispatcherTestBase(),
dschinazi42fc2da2020-04-24 16:19:17 -07001857 client_addr_(QuicIpAddress::Loopback4(), 1234) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -05001858
dschinazi42fc2da2020-04-24 16:19:17 -07001859 void ProcessFirstFlight(const ParsedQuicVersion& version,
1860 const QuicSocketAddress& peer_address,
1861 const QuicConnectionId& server_connection_id) {
1862 QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
1863 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001864 }
1865
dschinazi42fc2da2020-04-24 16:19:17 -07001866 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
1867 const QuicConnectionId& server_connection_id) {
1868 ProcessFirstFlight(version_, peer_address, server_connection_id);
1869 }
1870
1871 void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
1872 ProcessFirstFlight(client_addr_, server_connection_id);
1873 }
1874
1875 void ProcessFirstFlight(const ParsedQuicVersion& version,
1876 const QuicConnectionId& server_connection_id) {
1877 ProcessFirstFlight(version, client_addr_, server_connection_id);
1878 }
1879
1880 void ProcessUndecryptableEarlyPacket(
1881 const ParsedQuicVersion& version,
1882 const QuicSocketAddress& peer_address,
1883 const QuicConnectionId& server_connection_id) {
1884 QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
1885 version, peer_address, server_connection_id);
1886 }
1887
1888 void ProcessUndecryptableEarlyPacket(
1889 const QuicSocketAddress& peer_address,
1890 const QuicConnectionId& server_connection_id) {
1891 ProcessUndecryptableEarlyPacket(version_, peer_address,
1892 server_connection_id);
1893 }
1894
1895 void ProcessUndecryptableEarlyPacket(
1896 const QuicConnectionId& server_connection_id) {
1897 ProcessUndecryptableEarlyPacket(version_, client_addr_,
1898 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001899 }
1900
1901 protected:
QUICHE teama6ef0a62019-03-07 20:34:33 -05001902 QuicSocketAddress client_addr_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001903};
1904
dschinazi8d1c9d42020-02-18 13:12:20 -08001905INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests,
1906 BufferedPacketStoreTest,
dschinazi42fc2da2020-04-24 16:19:17 -07001907 ::testing::ValuesIn(CurrentSupportedVersions()),
dschinazi8d1c9d42020-02-18 13:12:20 -08001908 ::testing::PrintToStringParamName());
1909
dschinazi42fc2da2020-04-24 16:19:17 -07001910TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
1911 InSequence s;
1912 QuicConnectionId conn_id = TestConnectionId(1);
1913 // Non-CHLO should be buffered upon arrival, and should trigger
1914 // ShouldCreateOrBufferPacketForConnection().
1915 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1916 ReceivedPacketInfoConnectionIdEquals(conn_id)));
1917 // Process non-CHLO packet.
1918 ProcessUndecryptableEarlyPacket(conn_id);
1919 EXPECT_EQ(0u, dispatcher_->session_map().size())
1920 << "No session should be created before CHLO arrives.";
1921
1922 // When CHLO arrives, a new session should be created, and all packets
1923 // buffered should be delivered to the session.
wub4e3fb902020-07-15 13:37:29 -07001924 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
1925 Eq(ExpectedAlpn()), _))
dschinazi42fc2da2020-04-24 16:19:17 -07001926 .WillOnce(Return(ByMove(CreateSession(
1927 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
1928 &mock_alarm_factory_, &crypto_config_,
1929 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1930 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1931 ProcessUdpPacket(_, _, _))
1932 .Times(2) // non-CHLO + CHLO.
1933 .WillRepeatedly(
1934 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1935 if (version_.UsesQuicCrypto()) {
1936 ValidatePacket(conn_id, packet);
1937 }
1938 })));
1939 ProcessFirstFlight(conn_id);
1940}
1941
dschinazi8d1c9d42020-02-18 13:12:20 -08001942TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001943 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001944 QuicConnectionId conn_id = TestConnectionId(1);
1945 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1946 // should trigger ShouldCreateOrBufferPacketForConnection().
fayang1ed1f762019-06-24 11:40:04 -07001947 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1948 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001949 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
dschinazi42fc2da2020-04-24 16:19:17 -07001950 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001951 }
1952 EXPECT_EQ(0u, dispatcher_->session_map().size())
1953 << "No session should be created before CHLO arrives.";
1954
1955 // Pop out the last packet as it is also be dropped by the store.
1956 data_connection_map_[conn_id].pop_back();
1957 // When CHLO arrives, a new session should be created, and all packets
1958 // buffered should be delivered to the session.
wub4e3fb902020-07-15 13:37:29 -07001959 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
1960 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001961 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07001962 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001963 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001964 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001965
1966 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1967 // should be delivered in arrival order.
1968 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1969 ProcessUdpPacket(_, _, _))
1970 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1971 .WillRepeatedly(
1972 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001973 if (version_.UsesQuicCrypto()) {
1974 ValidatePacket(conn_id, packet);
1975 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001976 })));
dschinazi42fc2da2020-04-24 16:19:17 -07001977 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001978}
1979
dschinazi8d1c9d42020-02-18 13:12:20 -08001980TEST_P(BufferedPacketStoreTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001981 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1982 InSequence s;
1983 // A bunch of non-CHLO should be buffered upon arrival.
1984 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1985 for (size_t i = 1; i <= kNumConnections; ++i) {
1986 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1987 QuicConnectionId conn_id = TestConnectionId(i);
1988 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001989 ShouldCreateOrBufferPacketForConnection(
1990 ReceivedPacketInfoConnectionIdEquals(conn_id)));
dschinazi42fc2da2020-04-24 16:19:17 -07001991 ProcessUndecryptableEarlyPacket(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001992 }
1993
1994 // Pop out the packet on last connection as it shouldn't be enqueued in store
1995 // as well.
1996 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1997
1998 // Reset session creation counter to ensure processing CHLO can always
1999 // create session.
2000 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
2001 kNumConnections);
2002 // Process CHLOs to create session for these connections.
2003 for (size_t i = 1; i <= kNumConnections; ++i) {
2004 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
2005 QuicConnectionId conn_id = TestConnectionId(i);
2006 if (i == kNumConnections) {
2007 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07002008 ShouldCreateOrBufferPacketForConnection(
2009 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002010 }
wub4e3fb902020-07-15 13:37:29 -07002011 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_address,
dschinazi42fc2da2020-04-24 16:19:17 -07002012 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002013 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002014 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
2015 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002016 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002017 // First |kNumConnections| - 1 connections should have buffered
2018 // a packet in store. The rest should have been dropped.
2019 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
2020 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2021 ProcessUdpPacket(_, client_address, _))
2022 .Times(num_packet_to_process)
2023 .WillRepeatedly(WithArg<2>(
2024 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002025 if (version_.UsesQuicCrypto()) {
2026 ValidatePacket(conn_id, packet);
2027 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002028 })));
2029
dschinazi42fc2da2020-04-24 16:19:17 -07002030 ProcessFirstFlight(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002031 }
2032}
2033
2034// Tests that store delivers empty packet list if CHLO arrives firstly.
dschinazi8d1c9d42020-02-18 13:12:20 -08002035TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002036 QuicConnectionId conn_id = TestConnectionId(1);
fayang1ed1f762019-06-24 11:40:04 -07002037 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
2038 ReceivedPacketInfoConnectionIdEquals(conn_id)));
wub4e3fb902020-07-15 13:37:29 -07002039 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
2040 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002041 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07002042 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002043 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002044 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002045 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
dschinazi42fc2da2020-04-24 16:19:17 -07002046 ProcessUdpPacket(_, client_addr_, _));
2047 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002048}
2049
2050// Tests that a retransmitted CHLO arrives after a connection for the
2051// CHLO has been created.
dschinazi8d1c9d42020-02-18 13:12:20 -08002052TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002053 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002054 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07002055 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002056
2057 // When CHLO arrives, a new session should be created, and all packets
2058 // buffered should be delivered to the session.
wub4e3fb902020-07-15 13:37:29 -07002059 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, _, client_addr_,
2060 Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05002061 .Times(1) // Only triggered by 1st CHLO.
wub89490e02019-12-12 12:45:58 -08002062 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07002063 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002064 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002065 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002066 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2067 ProcessUdpPacket(_, _, _))
2068 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
2069 .WillRepeatedly(
2070 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002071 if (version_.UsesQuicCrypto()) {
2072 ValidatePacket(conn_id, packet);
2073 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002074 })));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002075
dschinazi42fc2da2020-04-24 16:19:17 -07002076 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
2077 GetFirstFlightOfPackets(version_, conn_id);
2078 ASSERT_EQ(packets.size(), 1u);
2079 // Receive the CHLO once.
2080 ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
2081 // Receive the CHLO a second time to simulate retransmission.
2082 ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002083}
2084
2085// Tests that expiration of a connection add connection id to time wait list.
dschinazi8d1c9d42020-02-18 13:12:20 -08002086TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002087 InSequence s;
2088 CreateTimeWaitListManager();
2089 QuicBufferedPacketStore* store =
2090 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2091 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2092
QUICHE teama6ef0a62019-03-07 20:34:33 -05002093 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07002094 ProcessPacket(client_addr_, conn_id, true,
dmcardlecf0bfcf2019-12-13 08:08:21 -08002095 quiche::QuicheStrCat("data packet ", 2), CONNECTION_ID_PRESENT,
2096 PACKET_4BYTE_PACKET_NUMBER,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002097 /*packet_number=*/2);
2098
2099 mock_helper_.AdvanceTime(
2100 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2101 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
2102 // Cancel alarm as if it had been fired.
2103 alarm->Cancel();
2104 store->OnExpirationTimeout();
2105 // New arrived CHLO will be dropped because this connection is in time wait
2106 // list.
2107 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2108 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
dschinazi42fc2da2020-04-24 16:19:17 -07002109 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002110}
2111
dschinazi8d1c9d42020-02-18 13:12:20 -08002112TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002113 // Process more than (|kMaxNumSessionsToCreate| +
2114 // |kDefaultMaxConnectionsInStore|) CHLOs,
2115 // the first |kMaxNumSessionsToCreate| should create connections immediately,
2116 // the next |kDefaultMaxConnectionsInStore| should be buffered,
2117 // the rest should be dropped.
2118 QuicBufferedPacketStore* store =
2119 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2120 const size_t kNumCHLOs =
2121 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
2122 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
fayang1ed1f762019-06-24 11:40:04 -07002123 EXPECT_CALL(
2124 *dispatcher_,
2125 ShouldCreateOrBufferPacketForConnection(
2126 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002127 if (conn_id <= kMaxNumSessionsToCreate) {
2128 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002129 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002130 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002131 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002132 dispatcher_.get(), config_, TestConnectionId(conn_id),
2133 client_addr_, &mock_helper_, &mock_alarm_factory_,
2134 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002135 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002136 EXPECT_CALL(
2137 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2138 ProcessUdpPacket(_, _, _))
2139 .WillOnce(WithArg<2>(
2140 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002141 if (version_.UsesQuicCrypto()) {
2142 ValidatePacket(TestConnectionId(conn_id), packet);
2143 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002144 })));
2145 }
dschinazi42fc2da2020-04-24 16:19:17 -07002146 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002147 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
2148 conn_id > kMaxNumSessionsToCreate) {
2149 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
2150 } else {
2151 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
2152 // connections immediately, and the last CHLO should be dropped as the
2153 // store is full.
2154 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
2155 }
2156 }
2157
2158 // Graduately consume buffered CHLOs. The buffered connections should be
2159 // created but the dropped one shouldn't.
2160 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2161 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
2162 ++conn_id) {
2163 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002164 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002165 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002166 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002167 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2168 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002169 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002170 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2171 ProcessUdpPacket(_, _, _))
2172 .WillOnce(WithArg<2>(
2173 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002174 if (version_.UsesQuicCrypto()) {
2175 ValidatePacket(TestConnectionId(conn_id), packet);
2176 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002177 })));
2178 }
2179 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002180 CreateQuicSession(TestConnectionId(kNumCHLOs), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002181 Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05002182 .Times(0);
2183
2184 while (store->HasChlosBuffered()) {
2185 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2186 }
2187
2188 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
2189 kDefaultMaxConnectionsInStore),
2190 session1_->connection_id());
2191}
2192
2193// Duplicated CHLO shouldn't be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002194TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002195 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
2196 ++conn_id) {
2197 // Last CHLO will be buffered. Others will create connection right away.
2198 if (conn_id <= kMaxNumSessionsToCreate) {
2199 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002200 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002201 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002202 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002203 dispatcher_.get(), config_, TestConnectionId(conn_id),
2204 client_addr_, &mock_helper_, &mock_alarm_factory_,
2205 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002206 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002207 EXPECT_CALL(
2208 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2209 ProcessUdpPacket(_, _, _))
2210 .WillOnce(WithArg<2>(
2211 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002212 if (version_.UsesQuicCrypto()) {
2213 ValidatePacket(TestConnectionId(conn_id), packet);
2214 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002215 })));
2216 }
dschinazi42fc2da2020-04-24 16:19:17 -07002217 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002218 }
2219 // Retransmit CHLO on last connection should be dropped.
2220 QuicConnectionId last_connection =
2221 TestConnectionId(kMaxNumSessionsToCreate + 1);
dschinazi42fc2da2020-04-24 16:19:17 -07002222 ProcessFirstFlight(last_connection);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002223
2224 size_t packets_buffered = 2;
2225
2226 // Reset counter and process buffered CHLO.
wub4e3fb902020-07-15 13:37:29 -07002227 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002228 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002229 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002230 dispatcher_.get(), config_, last_connection, client_addr_,
2231 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002232 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002233 // Only one packet(CHLO) should be process.
2234 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2235 ProcessUdpPacket(_, _, _))
2236 .Times(packets_buffered)
2237 .WillRepeatedly(WithArg<2>(
2238 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002239 if (version_.UsesQuicCrypto()) {
2240 ValidatePacket(last_connection, packet);
2241 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002242 })));
2243 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2244}
2245
dschinazi8d1c9d42020-02-18 13:12:20 -08002246TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002247 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2248 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2249 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2250 // Last CHLO will be buffered. Others will create connection right away.
2251 if (conn_id <= kMaxNumSessionsToCreate) {
2252 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002253 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002254 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002255 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002256 dispatcher_.get(), config_, TestConnectionId(conn_id),
2257 client_addr_, &mock_helper_, &mock_alarm_factory_,
2258 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002259 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002260 EXPECT_CALL(
2261 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2262 ProcessUdpPacket(_, _, _))
2263 .WillRepeatedly(WithArg<2>(
2264 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002265 if (version_.UsesQuicCrypto()) {
2266 ValidatePacket(TestConnectionId(conn_id), packet);
2267 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002268 })));
2269 }
dschinazi42fc2da2020-04-24 16:19:17 -07002270 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002271 }
2272
2273 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
2274 // last one should be dropped.
2275 for (uint64_t packet_number = 2;
2276 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
2277 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
2278 }
2279
2280 // Reset counter and process buffered CHLO.
wub4e3fb902020-07-15 13:37:29 -07002281 EXPECT_CALL(*dispatcher_,
2282 CreateQuicSession(last_connection_id, _, client_addr_,
2283 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002284 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002285 dispatcher_.get(), config_, last_connection_id, client_addr_,
2286 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002287 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002288 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
2289 // should be process.
2290 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2291 ProcessUdpPacket(_, _, _))
2292 .Times(kDefaultMaxUndecryptablePackets + 1)
2293 .WillRepeatedly(WithArg<2>(
2294 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002295 if (version_.UsesQuicCrypto()) {
2296 ValidatePacket(last_connection_id, packet);
2297 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002298 })));
2299 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2300}
2301
2302// Tests that when dispatcher's packet buffer is full, a CHLO on connection
2303// which doesn't have buffered CHLO should be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002304TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002305 QuicBufferedPacketStore* store =
2306 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2307
2308 uint64_t conn_id = 1;
dschinazi42fc2da2020-04-24 16:19:17 -07002309 ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002310 // Fill packet buffer to full with CHLOs on other connections. Need to feed
2311 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
2312 // session directly.
2313 for (conn_id = 2;
2314 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
2315 ++conn_id) {
2316 if (conn_id <= kMaxNumSessionsToCreate + 1) {
2317 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002318 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002319 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002320 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002321 dispatcher_.get(), config_, TestConnectionId(conn_id),
2322 client_addr_, &mock_helper_, &mock_alarm_factory_,
2323 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002324 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002325 EXPECT_CALL(
2326 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2327 ProcessUdpPacket(_, _, _))
2328 .WillOnce(WithArg<2>(
2329 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002330 if (version_.UsesQuicCrypto()) {
2331 ValidatePacket(TestConnectionId(conn_id), packet);
2332 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002333 })));
2334 }
dschinazi42fc2da2020-04-24 16:19:17 -07002335 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002336 }
2337 EXPECT_FALSE(store->HasChloForConnection(
2338 /*connection_id=*/TestConnectionId(1)));
2339
2340 // CHLO on connection 1 should still be buffered.
dschinazi42fc2da2020-04-24 16:19:17 -07002341 ProcessFirstFlight(TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002342 EXPECT_TRUE(store->HasChloForConnection(
2343 /*connection_id=*/TestConnectionId(1)));
2344}
2345
2346// Regression test for b/117874922.
dschinazi8d1c9d42020-02-18 13:12:20 -08002347TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
dschinazic3316f32020-03-05 14:34:36 -08002348 // Ensure the preferred version is not supported by the server.
dschinazi5a50d932020-06-17 12:43:36 -07002349 QuicDisableVersion(AllSupportedVersions().front());
dschinazib3fed9e2020-06-11 11:59:33 -07002350
QUICHE teama6ef0a62019-03-07 20:34:33 -05002351 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
2352 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
2353 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
2354 // Last 5 CHLOs will be buffered. Others will create connection right away.
2355 ParsedQuicVersion version =
2356 supported_versions[(conn_id - 1) % supported_versions.size()];
2357 if (conn_id <= kMaxNumSessionsToCreate) {
dschinazi42fc2da2020-04-24 16:19:17 -07002358 EXPECT_CALL(
2359 *dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002360 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002361 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002362 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002363 dispatcher_.get(), config_, TestConnectionId(conn_id),
2364 client_addr_, &mock_helper_, &mock_alarm_factory_,
2365 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002366 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002367 EXPECT_CALL(
2368 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2369 ProcessUdpPacket(_, _, _))
2370 .WillRepeatedly(WithArg<2>(
2371 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002372 if (version_.UsesQuicCrypto()) {
2373 ValidatePacket(TestConnectionId(conn_id), packet);
2374 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002375 })));
2376 }
dschinazi42fc2da2020-04-24 16:19:17 -07002377 ProcessFirstFlight(version, TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002378 }
2379
2380 // Process buffered CHLOs. Verify the version is correct.
2381 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2382 conn_id <= last_connection_id; ++conn_id) {
2383 ParsedQuicVersion version =
2384 supported_versions[(conn_id - 1) % supported_versions.size()];
2385 EXPECT_CALL(*dispatcher_,
wub4e3fb902020-07-15 13:37:29 -07002386 CreateQuicSession(TestConnectionId(conn_id), _, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002387 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002388 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002389 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2390 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002391 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002392 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2393 ProcessUdpPacket(_, _, _))
2394 .WillRepeatedly(WithArg<2>(
2395 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002396 if (version_.UsesQuicCrypto()) {
2397 ValidatePacket(TestConnectionId(conn_id), packet);
2398 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002399 })));
2400 }
2401 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2402}
2403
QUICHE teama6ef0a62019-03-07 20:34:33 -05002404} // namespace
2405} // namespace test
2406} // namespace quic