blob: ae084ecc1659175f7656fbf793affe9762b42b1c [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,
136 const QuicSocketAddress& peer_address,
137 quiche::QuicheStringPiece alpn,
138 const quic::ParsedQuicVersion& version),
139 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500140
wub713afae2020-04-27 07:48:31 -0700141 MOCK_METHOD(bool,
142 ShouldCreateOrBufferPacketForConnection,
143 (const ReceivedPacketInfo& packet_info),
144 (override));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145
146 struct TestQuicPerPacketContext : public QuicPerPacketContext {
vasilvvc48c8712019-03-11 13:38:16 -0700147 std::string custom_packet_context;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500148 };
149
150 std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
vasilvv0fc587f2019-09-06 13:33:08 -0700151 auto test_context = std::make_unique<TestQuicPerPacketContext>();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 test_context->custom_packet_context = custom_packet_context_;
153 return std::move(test_context);
154 }
155
156 void RestorePerPacketContext(
157 std::unique_ptr<QuicPerPacketContext> context) override {
158 TestQuicPerPacketContext* test_context =
159 static_cast<TestQuicPerPacketContext*>(context.get());
160 custom_packet_context_ = test_context->custom_packet_context;
161 }
162
vasilvvc48c8712019-03-11 13:38:16 -0700163 std::string custom_packet_context_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500164
dschinazi7b9278c2019-05-20 07:36:21 -0700165 using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166 using QuicDispatcher::writer;
wub662a3d62019-08-16 14:10:50 -0700167
168 QuicRandom* random_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500169};
170
171// A Connection class which unregisters the session from the dispatcher when
172// sending connection close.
173// It'd be slightly more realistic to do this from the Session but it would
174// involve a lot more mocking.
175class MockServerConnection : public MockQuicConnection {
176 public:
177 MockServerConnection(QuicConnectionId connection_id,
178 MockQuicConnectionHelper* helper,
179 MockAlarmFactory* alarm_factory,
180 QuicDispatcher* dispatcher)
181 : MockQuicConnection(connection_id,
182 helper,
183 alarm_factory,
184 Perspective::IS_SERVER),
185 dispatcher_(dispatcher) {}
186
187 void UnregisterOnConnectionClosed() {
188 QUIC_LOG(ERROR) << "Unregistering " << connection_id();
189 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
190 "Unregistering.",
191 ConnectionCloseSource::FROM_SELF);
192 }
193
194 private:
195 QuicDispatcher* dispatcher_;
196};
197
dschinazi8d1c9d42020-02-18 13:12:20 -0800198class QuicDispatcherTestBase : public QuicTestWithParam<ParsedQuicVersion> {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199 public:
dschinazi8d1c9d42020-02-18 13:12:20 -0800200 QuicDispatcherTestBase()
201 : QuicDispatcherTestBase(crypto_test_utils::ProofSourceForTesting()) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202
dschinazi8d1c9d42020-02-18 13:12:20 -0800203 explicit QuicDispatcherTestBase(std::unique_ptr<ProofSource> proof_source)
204 : version_(GetParam()),
205 version_manager_(AllSupportedVersions()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206 crypto_config_(QuicCryptoServerConfig::TESTING,
207 QuicRandom::GetInstance(),
208 std::move(proof_source),
nharper6ebe83b2019-06-13 17:43:52 -0700209 KeyExchangeSource::Default()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500210 server_address_(QuicIpAddress::Any4(), 5),
QUICHE teamc65d1d12019-03-19 20:58:04 -0700211 dispatcher_(
212 new NiceMock<TestDispatcher>(&config_,
213 &crypto_config_,
214 &version_manager_,
215 mock_helper_.GetRandomGenerator())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500216 time_wait_list_manager_(nullptr),
217 session1_(nullptr),
218 session2_(nullptr),
fayangb880b4c2019-06-14 12:26:35 -0700219 store_(nullptr),
220 connection_id_(1) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500221
222 void SetUp() override {
dschinazi42fc2da2020-04-24 16:19:17 -0700223 dispatcher_->InitializeWithWriter(new NiceMock<MockPacketWriter>());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 // Set the counter to some value to start with.
225 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
226 dispatcher_.get(), kMaxNumSessionsToCreate);
fayang1ed1f762019-06-24 11:40:04 -0700227 ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228 .WillByDefault(Return(true));
229 }
230
231 MockQuicConnection* connection1() {
232 if (session1_ == nullptr) {
233 return nullptr;
234 }
235 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
236 }
237
238 MockQuicConnection* connection2() {
239 if (session2_ == nullptr) {
240 return nullptr;
241 }
242 return reinterpret_cast<MockQuicConnection*>(session2_->connection());
243 }
244
245 // Process a packet with an 8 byte connection id,
246 // 6 byte packet number, default path id, and packet number 1,
dschinazi8d1c9d42020-02-18 13:12:20 -0800247 // using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500248 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700249 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500250 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700251 const std::string& data) {
dschinazi346b7ce2019-06-05 01:38:18 -0700252 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
254 }
255
256 // Process a packet with a default path id, and packet number 1,
dschinazi8d1c9d42020-02-18 13:12:20 -0800257 // using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700259 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500260 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700261 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700262 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500263 QuicPacketNumberLength packet_number_length) {
dschinazi346b7ce2019-06-05 01:38:18 -0700264 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
265 server_connection_id_included, packet_number_length, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500266 }
267
dschinazi8d1c9d42020-02-18 13:12:20 -0800268 // Process a packet using the version under test.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500269 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700270 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500271 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700272 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700273 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 QuicPacketNumberLength packet_number_length,
275 uint64_t packet_number) {
dschinazi346b7ce2019-06-05 01:38:18 -0700276 ProcessPacket(peer_address, server_connection_id, has_version_flag,
dschinazi8d1c9d42020-02-18 13:12:20 -0800277 version_, data, true, server_connection_id_included,
278 packet_number_length, packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279 }
280
281 // Processes a packet.
282 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700283 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 bool has_version_flag,
285 ParsedQuicVersion version,
vasilvvc48c8712019-03-11 13:38:16 -0700286 const std::string& data,
fayange3f2f7b2019-09-19 17:01:57 -0700287 bool full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700288 QuicConnectionIdIncluded server_connection_id_included,
289 QuicPacketNumberLength packet_number_length,
290 uint64_t packet_number) {
291 ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
fayange3f2f7b2019-09-19 17:01:57 -0700292 has_version_flag, version, data, full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700293 server_connection_id_included, CONNECTION_ID_ABSENT,
294 packet_number_length, packet_number);
295 }
296
297 // Processes a packet.
298 void ProcessPacket(QuicSocketAddress peer_address,
299 QuicConnectionId server_connection_id,
300 QuicConnectionId client_connection_id,
301 bool has_version_flag,
302 ParsedQuicVersion version,
303 const std::string& data,
fayange3f2f7b2019-09-19 17:01:57 -0700304 bool full_padding,
dschinazi346b7ce2019-06-05 01:38:18 -0700305 QuicConnectionIdIncluded server_connection_id_included,
306 QuicConnectionIdIncluded client_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 QuicPacketNumberLength packet_number_length,
308 uint64_t packet_number) {
309 ParsedQuicVersionVector versions(SupportedVersions(version));
310 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
dschinazi346b7ce2019-06-05 01:38:18 -0700311 server_connection_id, client_connection_id, has_version_flag, false,
fayange3f2f7b2019-09-19 17:01:57 -0700312 packet_number, data, full_padding, server_connection_id_included,
dschinazi346b7ce2019-06-05 01:38:18 -0700313 client_connection_id_included, packet_number_length, &versions));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314 std::unique_ptr<QuicReceivedPacket> received_packet(
315 ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
dschinazi6b40b1d2020-04-22 06:15:46 -0700316 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
317 server_connection_id);
318 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500319
dschinazi6b40b1d2020-04-22 06:15:46 -0700320 void ProcessReceivedPacket(
321 std::unique_ptr<QuicReceivedPacket> received_packet,
322 const QuicSocketAddress& peer_address,
323 const ParsedQuicVersion& version,
324 const QuicConnectionId& server_connection_id) {
dschinazi42fc2da2020-04-24 16:19:17 -0700325 if (version.UsesQuicCrypto() &&
dschinazi0e3c3482020-04-24 11:37:20 -0700326 ChloExtractor::Extract(*received_packet, version, {}, nullptr,
dschinazi346b7ce2019-06-05 01:38:18 -0700327 server_connection_id.length())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500328 // Add CHLO packet to the beginning to be verified first, because it is
329 // also processed first by new session.
dschinazi346b7ce2019-06-05 01:38:18 -0700330 data_connection_map_[server_connection_id].push_front(
dschinazi6b40b1d2020-04-22 06:15:46 -0700331 std::string(received_packet->data(), received_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332 } else {
333 // For non-CHLO, always append to last.
dschinazi346b7ce2019-06-05 01:38:18 -0700334 data_connection_map_[server_connection_id].push_back(
dschinazi6b40b1d2020-04-22 06:15:46 -0700335 std::string(received_packet->data(), received_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336 }
337 dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
338 }
339
340 void ValidatePacket(QuicConnectionId conn_id,
341 const QuicEncryptedPacket& packet) {
342 EXPECT_EQ(data_connection_map_[conn_id].front().length(),
343 packet.AsStringPiece().length());
344 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
345 data_connection_map_[conn_id].pop_front();
346 }
347
wub89490e02019-12-12 12:45:58 -0800348 std::unique_ptr<QuicSession> CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500349 TestDispatcher* dispatcher,
350 const QuicConfig& config,
351 QuicConnectionId connection_id,
dschinazi17d42422019-06-18 16:35:07 -0700352 const QuicSocketAddress& /*peer_address*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 MockQuicConnectionHelper* helper,
354 MockAlarmFactory* alarm_factory,
355 const QuicCryptoServerConfig* crypto_config,
356 QuicCompressedCertsCache* compressed_certs_cache,
wub89490e02019-12-12 12:45:58 -0800357 TestQuicSpdyServerSession** session_ptr) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500358 MockServerConnection* connection = new MockServerConnection(
359 connection_id, helper, alarm_factory, dispatcher);
360 connection->SetQuicPacketWriter(dispatcher->writer(),
361 /*owns_writer=*/false);
wub89490e02019-12-12 12:45:58 -0800362 auto session = std::make_unique<TestQuicSpdyServerSession>(
363 config, connection, crypto_config, compressed_certs_cache);
364 *session_ptr = session.get();
365 connection->set_visitor(session.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500366 ON_CALL(*connection, CloseConnection(_, _, _))
367 .WillByDefault(WithoutArgs(Invoke(
368 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
wub89490e02019-12-12 12:45:58 -0800369 return session;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500370 }
371
372 void CreateTimeWaitListManager() {
373 time_wait_list_manager_ = new MockTimeWaitListManager(
374 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
375 mock_helper_.GetClock(), &mock_alarm_factory_);
376 // dispatcher_ takes the ownership of time_wait_list_manager_.
377 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
378 time_wait_list_manager_);
379 }
380
vasilvvc48c8712019-03-11 13:38:16 -0700381 std::string SerializeCHLO() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500382 CryptoHandshakeMessage client_hello;
383 client_hello.set_tag(kCHLO);
dschinazi6b40b1d2020-04-22 06:15:46 -0700384 client_hello.SetStringPiece(kALPN, ExpectedAlpn());
vasilvvc48c8712019-03-11 13:38:16 -0700385 return std::string(client_hello.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500386 }
387
dschinazi42fc2da2020-04-24 16:19:17 -0700388 void ProcessUndecryptableEarlyPacket(
389 const QuicSocketAddress& peer_address,
390 const QuicConnectionId& server_connection_id) {
391 ProcessUndecryptableEarlyPacket(version_, peer_address,
392 server_connection_id);
393 }
394
395 void ProcessUndecryptableEarlyPacket(
396 const ParsedQuicVersion& version,
397 const QuicSocketAddress& peer_address,
398 const QuicConnectionId& server_connection_id) {
399 std::unique_ptr<QuicEncryptedPacket> encrypted_packet =
400 GetUndecryptableEarlyPacket(version, server_connection_id);
401 std::unique_ptr<QuicReceivedPacket> received_packet(ConstructReceivedPacket(
402 *encrypted_packet, mock_helper_.GetClock()->Now()));
403 ProcessReceivedPacket(std::move(received_packet), peer_address, version,
404 server_connection_id);
405 }
406
dschinazi6b40b1d2020-04-22 06:15:46 -0700407 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
408 const QuicConnectionId& server_connection_id) {
409 ProcessFirstFlight(version_, peer_address, server_connection_id);
410 }
411
412 void ProcessFirstFlight(const ParsedQuicVersion& version,
413 const QuicSocketAddress& peer_address,
414 const QuicConnectionId& server_connection_id) {
415 ProcessFirstFlight(version, peer_address, server_connection_id,
416 EmptyQuicConnectionId());
417 }
418
419 void ProcessFirstFlight(const ParsedQuicVersion& version,
420 const QuicSocketAddress& peer_address,
421 const QuicConnectionId& server_connection_id,
422 const QuicConnectionId& client_connection_id) {
423 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
424 GetFirstFlightOfPackets(version, server_connection_id,
425 client_connection_id);
426 for (auto&& packet : packets) {
427 ProcessReceivedPacket(std::move(packet), peer_address, version,
428 server_connection_id);
429 }
430 }
431
dschinazi8d1c9d42020-02-18 13:12:20 -0800432 std::string ExpectedAlpnForVersion(ParsedQuicVersion version) {
dschinazi6b40b1d2020-04-22 06:15:46 -0700433 return AlpnForVersion(version);
dschinazi8d1c9d42020-02-18 13:12:20 -0800434 }
435
436 std::string ExpectedAlpn() { return ExpectedAlpnForVersion(version_); }
437
QUICHE teama6ef0a62019-03-07 20:34:33 -0500438 void MarkSession1Deleted() { session1_ = nullptr; }
439
fayangb880b4c2019-06-14 12:26:35 -0700440 void VerifyVersionSupported(ParsedQuicVersion version) {
441 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
442 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
dmcardlecf0bfcf2019-12-13 08:08:21 -0800443 EXPECT_CALL(*dispatcher_,
444 CreateQuicSession(connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800445 Eq(ExpectedAlpnForVersion(version)), _))
wub89490e02019-12-12 12:45:58 -0800446 .WillOnce(Return(ByMove(CreateSession(
fayangb880b4c2019-06-14 12:26:35 -0700447 dispatcher_.get(), config_, connection_id, client_address,
448 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800449 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
fayangb880b4c2019-06-14 12:26:35 -0700450 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
451 ProcessUdpPacket(_, _, _))
452 .WillOnce(WithArg<2>(
453 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
454 ValidatePacket(connection_id, packet);
455 })));
456 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700457 ShouldCreateOrBufferPacketForConnection(
458 ReceivedPacketInfoConnectionIdEquals(connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700459 ProcessFirstFlight(version, client_address, connection_id);
fayangb880b4c2019-06-14 12:26:35 -0700460 }
461
462 void VerifyVersionNotSupported(ParsedQuicVersion version) {
463 QuicConnectionId connection_id = TestConnectionId(++connection_id_);
464 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
dmcardlecf0bfcf2019-12-13 08:08:21 -0800465 EXPECT_CALL(*dispatcher_,
dschinazi8d1c9d42020-02-18 13:12:20 -0800466 CreateQuicSession(connection_id, client_address, _, _))
fayangb880b4c2019-06-14 12:26:35 -0700467 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -0700468 ProcessFirstFlight(version, client_address, connection_id);
fayangb880b4c2019-06-14 12:26:35 -0700469 }
470
dschinazi0e3c3482020-04-24 11:37:20 -0700471 void TestTlsMultiPacketClientHello(bool add_reordering);
472
dschinazi8d1c9d42020-02-18 13:12:20 -0800473 ParsedQuicVersion version_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500474 MockQuicConnectionHelper mock_helper_;
475 MockAlarmFactory mock_alarm_factory_;
476 QuicConfig config_;
477 QuicVersionManager version_manager_;
478 QuicCryptoServerConfig crypto_config_;
479 QuicSocketAddress server_address_;
480 std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
481 MockTimeWaitListManager* time_wait_list_manager_;
482 TestQuicSpdyServerSession* session1_;
483 TestQuicSpdyServerSession* session2_;
vasilvvc48c8712019-03-11 13:38:16 -0700484 std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500485 QuicBufferedPacketStore* store_;
fayangb880b4c2019-06-14 12:26:35 -0700486 uint64_t connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500487};
488
dschinazi8d1c9d42020-02-18 13:12:20 -0800489class QuicDispatcherTestAllVersions : public QuicDispatcherTestBase {};
490class QuicDispatcherTestOneVersion : public QuicDispatcherTestBase {};
491
492INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsAllVersions,
493 QuicDispatcherTestAllVersions,
494 ::testing::ValuesIn(CurrentSupportedVersions()),
495 ::testing::PrintToStringParamName());
496
497INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsOneVersion,
498 QuicDispatcherTestOneVersion,
499 ::testing::Values(CurrentSupportedVersions().front()),
500 ::testing::PrintToStringParamName());
501
502TEST_P(QuicDispatcherTestAllVersions, TlsClientHelloCreatesSession) {
dschinazi42fc2da2020-04-24 16:19:17 -0700503 if (version_.UsesQuicCrypto()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 return;
505 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
507
508 EXPECT_CALL(*dispatcher_,
509 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800510 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800511 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512 dispatcher_.get(), config_, TestConnectionId(1), client_address,
513 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800514 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500515 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
516 ProcessUdpPacket(_, _, _))
517 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
518 ValidatePacket(TestConnectionId(1), packet);
519 })));
520 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700521 ShouldCreateOrBufferPacketForConnection(
522 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700523
524 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525}
526
dschinazi0e3c3482020-04-24 11:37:20 -0700527void QuicDispatcherTestBase::TestTlsMultiPacketClientHello(
528 bool add_reordering) {
dschinazi42fc2da2020-04-24 16:19:17 -0700529 if (!version_.UsesTls()) {
dschinazi0e3c3482020-04-24 11:37:20 -0700530 return;
531 }
532 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
533 QuicConnectionId server_connection_id = TestConnectionId();
534 QuicConfig client_config = DefaultQuicConfig();
535 // Add a 2000-byte custom parameter to increase the length of the CHLO.
536 constexpr auto kCustomParameterId =
537 static_cast<TransportParameters::TransportParameterId>(0xff33);
538 std::string kCustomParameterValue(2000, '-');
539 client_config.custom_transport_parameters_to_send()[kCustomParameterId] =
540 kCustomParameterValue;
541 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
542 GetFirstFlightOfPackets(version_, client_config, server_connection_id);
543 ASSERT_EQ(packets.size(), 2u);
544 if (add_reordering) {
545 std::swap(packets[0], packets[1]);
546 }
547
548 // Processing the first packet should not create a new session.
549 EXPECT_CALL(*dispatcher_,
550 ShouldCreateOrBufferPacketForConnection(
551 ReceivedPacketInfoConnectionIdEquals(server_connection_id)));
552 ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
553 server_connection_id);
554
555 EXPECT_EQ(dispatcher_->session_map().size(), 0u)
556 << "No session should be created before the rest of the CHLO arrives.";
557
558 // Processing the second packet should create the new session.
559 EXPECT_CALL(*dispatcher_,
560 CreateQuicSession(server_connection_id, client_address,
561 Eq(ExpectedAlpn()), _))
562 .WillOnce(Return(ByMove(CreateSession(
563 dispatcher_.get(), config_, server_connection_id, client_address,
564 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
565 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
566 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
567 ProcessUdpPacket(_, _, _))
568 .Times(2);
569
570 ProcessReceivedPacket(std::move(packets[1]), client_address, version_,
571 server_connection_id);
572 EXPECT_EQ(dispatcher_->session_map().size(), 1u);
573}
574
575TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHello) {
576 TestTlsMultiPacketClientHello(/*add_reordering=*/false);
577}
578
579TEST_P(QuicDispatcherTestAllVersions, TlsMultiPacketClientHelloWithReordering) {
580 TestTlsMultiPacketClientHello(/*add_reordering=*/true);
581}
582
dschinazi8d1c9d42020-02-18 13:12:20 -0800583TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500584 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
585
586 EXPECT_CALL(*dispatcher_,
587 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800588 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800589 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500590 dispatcher_.get(), config_, TestConnectionId(1), client_address,
591 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800592 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500593 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
594 ProcessUdpPacket(_, _, _))
595 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
596 ValidatePacket(TestConnectionId(1), packet);
597 })));
598 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700599 ShouldCreateOrBufferPacketForConnection(
600 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700601 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500602
603 EXPECT_CALL(*dispatcher_,
604 CreateQuicSession(TestConnectionId(2), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800605 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800606 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500607 dispatcher_.get(), config_, TestConnectionId(2), client_address,
608 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800609 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500610 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
611 ProcessUdpPacket(_, _, _))
612 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
613 ValidatePacket(TestConnectionId(2), packet);
614 })));
615 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700616 ShouldCreateOrBufferPacketForConnection(
617 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700618 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500619
620 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
621 ProcessUdpPacket(_, _, _))
622 .Times(1)
623 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
624 ValidatePacket(TestConnectionId(1), packet);
625 })));
626 ProcessPacket(client_address, TestConnectionId(1), false, "data");
627}
628
629// Regression test of b/93325907.
dschinazi8d1c9d42020-02-18 13:12:20 -0800630TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500631 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
632
633 EXPECT_CALL(*dispatcher_,
634 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800635 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800636 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500637 dispatcher_.get(), config_, TestConnectionId(1), client_address,
638 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800639 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500640 // Verify both packets 1 and 2 are processed by connection 1.
641 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
642 ProcessUdpPacket(_, _, _))
643 .Times(2)
644 .WillRepeatedly(
645 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
646 ValidatePacket(TestConnectionId(1), packet);
647 })));
648 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700649 ShouldCreateOrBufferPacketForConnection(
650 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700651 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500652 // Packet number 256 with packet number length 1 would be considered as 0 in
653 // dispatcher.
dschinazi8d1c9d42020-02-18 13:12:20 -0800654 ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
655 CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500656}
657
dschinazi8d1c9d42020-02-18 13:12:20 -0800658TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500659 CreateTimeWaitListManager();
660 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
661
662 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
dschinazi346b7ce2019-06-05 01:38:18 -0700663 EXPECT_CALL(
664 *time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700665 SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500666 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700667 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
668 TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500669}
670
dschinazi8d1c9d42020-02-18 13:12:20 -0800671TEST_P(QuicDispatcherTestOneVersion,
dschinaziffa83552019-12-17 11:00:23 -0800672 StatelessVersionNegotiationWithVeryLongConnectionId) {
dschinaziffa83552019-12-17 11:00:23 -0800673 QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
674 CreateTimeWaitListManager();
675 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
676
677 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
678 EXPECT_CALL(*time_wait_list_manager_,
679 SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
680 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700681 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
682 connection_id);
dschinaziffa83552019-12-17 11:00:23 -0800683}
684
dschinazi8d1c9d42020-02-18 13:12:20 -0800685TEST_P(QuicDispatcherTestOneVersion,
686 StatelessVersionNegotiationWithClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700687 CreateTimeWaitListManager();
688 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
689
690 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
691 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700692 SendVersionNegotiationPacket(
693 TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
dschinazi346b7ce2019-06-05 01:38:18 -0700694 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700695 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
696 TestConnectionId(1), TestConnectionId(2));
dschinazi346b7ce2019-06-05 01:38:18 -0700697}
698
dschinazi8d1c9d42020-02-18 13:12:20 -0800699TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500700 CreateTimeWaitListManager();
701 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
702
703 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
704 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700705 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500706 .Times(0);
vasilvvc48c8712019-03-11 13:38:16 -0700707 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500708 // Truncate to 1100 bytes of payload which results in a packet just
709 // under 1200 bytes after framing, packet, and encryption overhead.
710 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700711 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500712 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700713 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700714 QuicVersionReservedForNegotiation(), truncated_chlo, false,
nharper4fd11052019-06-04 14:23:22 -0700715 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500716}
717
718// Disabling CHLO size validation allows the dispatcher to send version
719// negotiation packets in response to a CHLO that is otherwise too small.
dschinazi8d1c9d42020-02-18 13:12:20 -0800720TEST_P(QuicDispatcherTestOneVersion,
721 VersionNegotiationWithoutChloSizeValidation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500722 crypto_config_.set_validate_chlo_size(false);
723
724 CreateTimeWaitListManager();
725 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
726
727 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
728 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700729 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500730 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -0700731 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500732 // Truncate to 1100 bytes of payload which results in a packet just
733 // under 1200 bytes after framing, packet, and encryption overhead.
734 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700735 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500736 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700737 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700738 QuicVersionReservedForNegotiation(), truncated_chlo, true,
nharper4fd11052019-06-04 14:23:22 -0700739 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740}
741
dschinazi8d1c9d42020-02-18 13:12:20 -0800742TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500743 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
744
dschinazi8d1c9d42020-02-18 13:12:20 -0800745 EXPECT_CALL(*dispatcher_,
746 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800747 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500748 dispatcher_.get(), config_, TestConnectionId(1), client_address,
749 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800750 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500751 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
752 ProcessUdpPacket(_, _, _))
753 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
754 ValidatePacket(TestConnectionId(1), packet);
755 })));
756
757 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700758 ShouldCreateOrBufferPacketForConnection(
759 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700760 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500761
762 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
763 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
764
765 dispatcher_->Shutdown();
766}
767
dschinazi8d1c9d42020-02-18 13:12:20 -0800768TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500769 CreateTimeWaitListManager();
770
771 // Create a new session.
772 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
773 QuicConnectionId connection_id = TestConnectionId(1);
dschinazi8d1c9d42020-02-18 13:12:20 -0800774 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
775 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800776 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500777 dispatcher_.get(), config_, connection_id, client_address,
778 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800779 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500780 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
781 ProcessUdpPacket(_, _, _))
782 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
783 ValidatePacket(TestConnectionId(1), packet);
784 })));
785
786 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700787 ShouldCreateOrBufferPacketForConnection(
788 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700789 ProcessFirstFlight(client_address, connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500790
791 // Now close the connection, which should add it to the time wait list.
792 session1_->connection()->CloseConnection(
793 QUIC_INVALID_VERSION,
794 "Server: Packet 2 without version flag before version negotiated.",
795 ConnectionCloseBehavior::SILENT_CLOSE);
796 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
797
798 // Dispatcher forwards subsequent packets for this connection_id to the time
799 // wait list manager.
800 EXPECT_CALL(*time_wait_list_manager_,
801 ProcessPacket(_, _, connection_id, _, _))
802 .Times(1);
803 EXPECT_CALL(*time_wait_list_manager_,
804 AddConnectionIdToTimeWait(_, _, _, _, _))
805 .Times(0);
806 ProcessPacket(client_address, connection_id, true, "data");
807}
808
dschinazi8d1c9d42020-02-18 13:12:20 -0800809TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500810 CreateTimeWaitListManager();
811
812 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
813 QuicConnectionId connection_id = TestConnectionId(1);
814 // Dispatcher forwards all packets for this connection_id to the time wait
815 // list manager.
dschinazi8d1c9d42020-02-18 13:12:20 -0800816 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800817 EXPECT_CALL(*time_wait_list_manager_,
818 ProcessPacket(_, _, connection_id, _, _))
819 .Times(0);
820 EXPECT_CALL(*time_wait_list_manager_,
821 AddConnectionIdToTimeWait(_, _, _, _, _))
822 .Times(0);
823 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
824 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700825 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
826 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500827}
828
dschinazi8d1c9d42020-02-18 13:12:20 -0800829TEST_P(QuicDispatcherTestAllVersions,
fayangd057e662019-07-10 13:29:41 -0700830 DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
831 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
832 CreateTimeWaitListManager();
833
834 char short_packet[22] = {0x70, 0xa7, 0x02, 0x6b};
835 QuicReceivedPacket packet(short_packet, 22, QuicTime::Zero());
836 char valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
837 QuicReceivedPacket packet2(valid_size_packet, 23, QuicTime::Zero());
838 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800839 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
840 EXPECT_CALL(*time_wait_list_manager_,
841 AddConnectionIdToTimeWait(_, _, _, _, _))
842 .Times(0);
843 // Verify small packet is silently dropped.
844 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
845 .Times(0);
fayangd057e662019-07-10 13:29:41 -0700846 dispatcher_->ProcessPacket(server_address_, client_address, packet);
fayang9d6231c2019-12-04 07:10:13 -0800847 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
848 .Times(1);
fayangd057e662019-07-10 13:29:41 -0700849 dispatcher_->ProcessPacket(server_address_, client_address, packet2);
850}
851
QUICHE teamc65d1d12019-03-19 20:58:04 -0700852// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800853TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
854 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700855 // When variable length connection IDs are not supported, the connection
856 // fails. See StrayPacketTruncatedConnectionId.
QUICHE team8e2e4532019-03-14 14:37:56 -0700857 return;
858 }
QUICHE team8e2e4532019-03-14 14:37:56 -0700859 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
860
QUICHE teamc65d1d12019-03-19 20:58:04 -0700861 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700862 QuicConnectionId fixed_connection_id =
863 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700864
865 EXPECT_CALL(*dispatcher_,
866 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800867 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800868 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700869 dispatcher_.get(), config_, fixed_connection_id, client_address,
870 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800871 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -0700872 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
873 ProcessUdpPacket(_, _, _))
874 .WillOnce(WithArg<2>(
875 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
876 ValidatePacket(bad_connection_id, packet);
877 })));
878 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700879 ShouldCreateOrBufferPacketForConnection(
880 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700881 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700882}
883
QUICHE team963d57e2019-03-21 10:58:47 -0700884// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800885TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
886 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team963d57e2019-03-21 10:58:47 -0700887 // When variable length connection IDs are not supported, the connection
888 // fails. See StrayPacketTruncatedConnectionId.
889 return;
890 }
891 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
892
893 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
dschinazi28c1bf32019-08-19 11:54:46 -0700894 QuicConnectionId fixed_connection_id =
895 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700896
897 // Disable validation of invalid short connection IDs.
dschinazi7b9278c2019-05-20 07:36:21 -0700898 dispatcher_->SetAllowShortInitialServerConnectionIds(true);
QUICHE team963d57e2019-03-21 10:58:47 -0700899 // Note that StrayPacketTruncatedConnectionId covers the case where the
900 // validation is still enabled.
901
902 EXPECT_CALL(*dispatcher_,
903 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800904 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800905 .WillOnce(Return(ByMove(CreateSession(
QUICHE team963d57e2019-03-21 10:58:47 -0700906 dispatcher_.get(), config_, fixed_connection_id, client_address,
907 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800908 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team963d57e2019-03-21 10:58:47 -0700909 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
910 ProcessUdpPacket(_, _, _))
911 .WillOnce(WithArg<2>(
912 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
913 ValidatePacket(bad_connection_id, packet);
914 })));
915 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700916 ShouldCreateOrBufferPacketForConnection(
917 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700918 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700919}
920
QUICHE teamc65d1d12019-03-19 20:58:04 -0700921// Makes sure TestConnectionId(1) creates a new connection and
922// TestConnectionIdNineBytesLong(2) gets replaced.
dschinazi8d1c9d42020-02-18 13:12:20 -0800923TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
924 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700925 return;
926 }
QUICHE teamc65d1d12019-03-19 20:58:04 -0700927
QUICHE team8e2e4532019-03-14 14:37:56 -0700928 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700929 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700930 QuicConnectionId fixed_connection_id =
931 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700932
933 EXPECT_CALL(*dispatcher_,
934 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800935 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800936 .WillOnce(Return(ByMove(CreateSession(
QUICHE team8e2e4532019-03-14 14:37:56 -0700937 dispatcher_.get(), config_, TestConnectionId(1), client_address,
938 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800939 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team8e2e4532019-03-14 14:37:56 -0700940 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
941 ProcessUdpPacket(_, _, _))
942 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
943 ValidatePacket(TestConnectionId(1), packet);
944 })));
945 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700946 ShouldCreateOrBufferPacketForConnection(
947 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700948 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE team8e2e4532019-03-14 14:37:56 -0700949
QUICHE teamc65d1d12019-03-19 20:58:04 -0700950 EXPECT_CALL(*dispatcher_,
951 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800952 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800953 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700954 dispatcher_.get(), config_, fixed_connection_id, client_address,
955 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800956 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -0700957 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
958 ProcessUdpPacket(_, _, _))
959 .WillOnce(WithArg<2>(
960 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
961 ValidatePacket(bad_connection_id, packet);
962 })));
963 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700964 ShouldCreateOrBufferPacketForConnection(
965 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700966 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700967
968 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
969 ProcessUdpPacket(_, _, _))
970 .Times(1)
971 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
972 ValidatePacket(TestConnectionId(1), packet);
973 })));
974 ProcessPacket(client_address, TestConnectionId(1), false, "data");
975}
976
dschinazi8d1c9d42020-02-18 13:12:20 -0800977TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500978 CreateTimeWaitListManager();
979
980 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
981
982 // dispatcher_ should drop this packet.
983 EXPECT_CALL(*dispatcher_,
dschinazi8d1c9d42020-02-18 13:12:20 -0800984 CreateQuicSession(TestConnectionId(1), client_address, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500985 .Times(0);
986 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
987 EXPECT_CALL(*time_wait_list_manager_,
988 AddConnectionIdToTimeWait(_, _, _, _, _))
989 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -0700990 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
991 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500992}
993
dschinazi8d1c9d42020-02-18 13:12:20 -0800994TEST_P(QuicDispatcherTestAllVersions,
995 ProcessPacketWithInvalidShortInitialConnectionId) {
996 if (!version_.AllowsVariableLengthConnectionIds()) {
997 return;
998 }
dschinaziee07e472019-06-19 09:56:56 -0700999 CreateTimeWaitListManager();
1000
1001 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1002
1003 // dispatcher_ should drop this packet.
dschinazi8d1c9d42020-02-18 13:12:20 -08001004 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address, _, _))
dschinaziee07e472019-06-19 09:56:56 -07001005 .Times(0);
1006 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
1007 EXPECT_CALL(*time_wait_list_manager_,
1008 AddConnectionIdToTimeWait(_, _, _, _, _))
1009 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -07001010 ProcessFirstFlight(client_address, EmptyQuicConnectionId());
dschinaziee07e472019-06-19 09:56:56 -07001011}
1012
dschinazi8d1c9d42020-02-18 13:12:20 -08001013TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
fayangb880b4c2019-06-14 12:26:35 -07001014 VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
dschinazi8d1c9d42020-02-18 13:12:20 -08001015 for (ParsedQuicVersion version : CurrentSupportedVersions()) {
1016 VerifyVersionSupported(version);
dschinazi5a50d932020-06-17 12:43:36 -07001017 QuicDisableVersion(version);
1018 VerifyVersionNotSupported(version);
1019 QuicEnableVersion(version);
1020 VerifyVersionSupported(version);
dschinazi8d1c9d42020-02-18 13:12:20 -08001021 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001022}
1023
dschinazi8d1c9d42020-02-18 13:12:20 -08001024TEST_P(QuicDispatcherTestOneVersion,
1025 RejectDeprecatedVersionsWithVersionNegotiation) {
dschinazi6ab45242020-06-23 00:20:37 -07001026 static_assert(quic::SupportedVersions().size() == 9u,
fayangb54ac5b2019-07-01 10:30:37 -07001027 "Please add deprecated versions to this test");
1028 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1029 CreateTimeWaitListManager();
1030
dschinazi8b1c45a2019-10-17 08:48:13 -07001031 {
1032 char packet47[kMinPacketSizeForVersionNegotiation] = {
1033 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
1034 QuicReceivedPacket received_packet47(
1035 packet47, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1036 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1037 EXPECT_CALL(*time_wait_list_manager_,
1038 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1039 .Times(1);
1040 dispatcher_->ProcessPacket(server_address_, client_address,
1041 received_packet47);
1042 }
fayang36825da2019-08-21 14:01:27 -07001043
dschinazi8b1c45a2019-10-17 08:48:13 -07001044 {
1045 char packet45[kMinPacketSizeForVersionNegotiation] = {
1046 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
1047 QuicReceivedPacket received_packet45(
1048 packet45, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1049 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1050 EXPECT_CALL(*time_wait_list_manager_,
1051 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1052 .Times(1);
1053 dispatcher_->ProcessPacket(server_address_, client_address,
1054 received_packet45);
1055 }
1056
1057 {
1058 char packet44[kMinPacketSizeForVersionNegotiation] = {
1059 0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
1060 QuicReceivedPacket received_packet44(
1061 packet44, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1062 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1063 EXPECT_CALL(*time_wait_list_manager_,
1064 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1065 .Times(1);
1066 dispatcher_->ProcessPacket(server_address_, client_address,
1067 received_packet44);
1068 }
fayangb54ac5b2019-07-01 10:30:37 -07001069}
1070
dschinazi8d1c9d42020-02-18 13:12:20 -08001071TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeOld) {
dschinazi30ab6db2019-08-13 14:43:32 -07001072 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi30ab6db2019-08-13 14:43:32 -07001073 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1074 CreateTimeWaitListManager();
1075 char packet[1200];
1076 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1077 0x6c, 0x7a, 0x20, 0x21};
1078 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1079 packet, sizeof(packet), destination_connection_id_bytes,
1080 sizeof(destination_connection_id_bytes)));
1081 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1082 std::unique_ptr<QuicReceivedPacket> received_packet(
1083 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1084 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1085 QuicConnectionId server_connection_id(
1086 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1087 bool ietf_quic = true;
1088 bool use_length_prefix =
1089 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1090 EXPECT_CALL(
1091 *time_wait_list_manager_,
1092 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1093 ietf_quic, use_length_prefix, _, _, _, _))
1094 .Times(1);
1095 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1096
1097 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1098}
1099
dschinazi8d1c9d42020-02-18 13:12:20 -08001100TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
dschinazi30ab6db2019-08-13 14:43:32 -07001101 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi30ab6db2019-08-13 14:43:32 -07001102 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1103 CreateTimeWaitListManager();
1104 char packet[1200];
1105 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1106 0x6c, 0x7a, 0x20, 0x21};
1107 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1108 packet, sizeof(packet), destination_connection_id_bytes,
1109 sizeof(destination_connection_id_bytes)));
1110 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1111 std::unique_ptr<QuicReceivedPacket> received_packet(
1112 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1113 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1114 QuicConnectionId server_connection_id(
1115 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1116 bool ietf_quic = true;
1117 bool use_length_prefix =
1118 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1119 EXPECT_CALL(
1120 *time_wait_list_manager_,
1121 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1122 ietf_quic, use_length_prefix, _, _, _, _))
1123 .Times(1);
1124 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1125
1126 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1127}
1128
dschinazi0185ebb2019-08-14 11:09:35 -07001129// Testing packet writer that saves all packets instead of sending them.
1130// Useful for tests that need access to sent packets.
1131class SavingWriter : public QuicPacketWriterWrapper {
1132 public:
1133 bool IsWriteBlocked() const override { return false; }
1134
1135 WriteResult WritePacket(const char* buffer,
1136 size_t buf_len,
1137 const QuicIpAddress& /*self_client_address*/,
1138 const QuicSocketAddress& /*peer_client_address*/,
1139 PerPacketOptions* /*options*/) override {
1140 packets_.push_back(
1141 QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
1142 return WriteResult(WRITE_STATUS_OK, buf_len);
1143 }
1144
1145 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
1146 return &packets_;
1147 }
1148
1149 private:
1150 std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
1151};
1152
dschinazi8d1c9d42020-02-18 13:12:20 -08001153TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) {
dschinazi0185ebb2019-08-14 11:09:35 -07001154 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi0185ebb2019-08-14 11:09:35 -07001155
1156 SavingWriter* saving_writer = new SavingWriter();
1157 // dispatcher_ takes ownership of saving_writer.
1158 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1159
1160 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1161 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1162 &mock_alarm_factory_);
1163 // dispatcher_ takes ownership of time_wait_list_manager.
1164 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1165 time_wait_list_manager);
1166 char packet[1200] = {};
1167 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1168 0x6c, 0x7a, 0x20, 0x21};
1169 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1170 packet, sizeof(packet), destination_connection_id_bytes,
1171 sizeof(destination_connection_id_bytes)));
1172 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1173 std::unique_ptr<QuicReceivedPacket> received_packet(
1174 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1175 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1176
1177 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1178 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1179 ASSERT_EQ(1u, saving_writer->packets()->size());
1180
1181 char source_connection_id_bytes[255] = {};
1182 uint8_t source_connection_id_length = 0;
1183 std::string detailed_error = "foobar";
1184 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1185 (*(saving_writer->packets()))[0]->data(),
1186 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1187 &source_connection_id_length, &detailed_error));
1188 EXPECT_EQ("", detailed_error);
1189
1190 // The source connection ID of the probe response should match the
1191 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001192 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001193 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1194 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1195}
1196
dschinazi8d1c9d42020-02-18 13:12:20 -08001197TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
dschinazi0185ebb2019-08-14 11:09:35 -07001198 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi0185ebb2019-08-14 11:09:35 -07001199
1200 SavingWriter* saving_writer = new SavingWriter();
1201 // dispatcher_ takes ownership of saving_writer.
1202 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1203
1204 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1205 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1206 &mock_alarm_factory_);
1207 // dispatcher_ takes ownership of time_wait_list_manager.
1208 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1209 time_wait_list_manager);
1210 char packet[1200] = {};
1211 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1212 0x6c, 0x7a, 0x20, 0x21};
1213 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1214 packet, sizeof(packet), destination_connection_id_bytes,
1215 sizeof(destination_connection_id_bytes)));
1216 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1217 std::unique_ptr<QuicReceivedPacket> received_packet(
1218 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1219 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1220
1221 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1222 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1223 ASSERT_EQ(1u, saving_writer->packets()->size());
1224
1225 char source_connection_id_bytes[255] = {};
1226 uint8_t source_connection_id_length = 0;
1227 std::string detailed_error = "foobar";
1228 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1229 (*(saving_writer->packets()))[0]->data(),
1230 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1231 &source_connection_id_length, &detailed_error));
1232 EXPECT_EQ("", detailed_error);
1233
1234 // The source connection ID of the probe response should match the
1235 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001236 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001237 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1238 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1239}
1240
dschinazi8d1c9d42020-02-18 13:12:20 -08001241TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
dschinazi5b236be2019-08-19 14:55:22 -07001242 // WARNING: do not remove or modify this test without making sure that we
1243 // still have adequate coverage for the Android conformance test.
dschinazi5b236be2019-08-19 14:55:22 -07001244 SavingWriter* saving_writer = new SavingWriter();
1245 // dispatcher_ takes ownership of saving_writer.
1246 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1247
1248 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1249 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1250 &mock_alarm_factory_);
1251 // dispatcher_ takes ownership of time_wait_list_manager.
1252 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1253 time_wait_list_manager);
1254 // clang-format off
1255 static const unsigned char packet[1200] = {
1256 // Android UDP network conformance test packet as it was after this change:
1257 // https://android-review.googlesource.com/c/platform/cts/+/1104285
1258 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number
1259 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
1260 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number
1261 0x01, // 1-byte packet number
1262 0x00, // private flags
1263 0x07, // PING frame
1264 };
1265 // clang-format on
1266
1267 QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
1268 sizeof(packet), false);
1269 std::unique_ptr<QuicReceivedPacket> received_packet(
1270 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1271 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1272
1273 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1274 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1275 ASSERT_EQ(1u, saving_writer->packets()->size());
1276
1277 // The Android UDP network conformance test directly checks that bytes 1-9
1278 // of the response match the connection ID that was sent.
1279 static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
1280 0x75, 0x76, 0x77, 0x78};
1281 ASSERT_GE((*(saving_writer->packets()))[0]->length(),
1282 1u + sizeof(connection_id_bytes));
dmcardle8f7df532020-01-07 13:28:57 -08001283 quiche::test::CompareCharArraysWithHexError(
dschinazi5b236be2019-08-19 14:55:22 -07001284 "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
1285 sizeof(connection_id_bytes), connection_id_bytes,
1286 sizeof(connection_id_bytes));
1287}
1288
dschinazi8d1c9d42020-02-18 13:12:20 -08001289TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
dschinazi942a9f82020-06-19 09:23:20 -07001290 if (!version_.HasIetfInvariantHeader() &&
1291 !GetQuicReloadableFlag(quic_dont_pad_chlo)) {
1292 // When quic_dont_pad_chlo is false, we only drop small packets when using
1293 // IETF_QUIC_LONG_HEADER_PACKET. When quic_dont_pad_chlo is true, we drop
1294 // small packets for all versions.
1295 // TODO(dschinazi) remove this early return when we deprecate the flag.
dschinazi8d1c9d42020-02-18 13:12:20 -08001296 return;
1297 }
fayange3f2f7b2019-09-19 17:01:57 -07001298 CreateTimeWaitListManager();
1299 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1300
1301 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
dschinazicdc73612020-03-02 10:34:01 -08001302 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
rch9d76c2d2019-12-20 12:19:48 -08001303 EXPECT_CALL(*time_wait_list_manager_,
1304 AddConnectionIdToTimeWait(_, _, _, _, _))
1305 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001306 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1307 version_, SerializeCHLO(), /*full_padding=*/false,
fayange3f2f7b2019-09-19 17:01:57 -07001308 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
1309}
1310
dschinazi8d1c9d42020-02-18 13:12:20 -08001311TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
fayange3f2f7b2019-09-19 17:01:57 -07001312 CreateTimeWaitListManager();
1313 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1314
1315 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
1316
1317 // clang-format off
1318 char coalesced_packet[1200] = {
1319 // first coalesced packet
1320 // public flags (long header with packet type INITIAL and
1321 // 4-byte packet number)
1322 0xC3,
1323 // version
1324 'Q', '0', '9', '9',
1325 // destination connection ID length
1326 0x08,
1327 // destination connection ID
1328 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1329 // source connection ID length
1330 0x00,
1331 // long header packet length
1332 0x05,
1333 // packet number
1334 0x12, 0x34, 0x56, 0x78,
1335 // Padding
1336 0x00,
1337 // second coalesced packet
1338 // public flags (long header with packet type ZERO_RTT_PROTECTED and
1339 // 4-byte packet number)
1340 0xC3,
1341 // version
1342 'Q', '0', '9', '9',
1343 // destination connection ID length
1344 0x08,
1345 // destination connection ID
1346 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1347 // source connection ID length
1348 0x00,
1349 // long header packet length
1350 0x1E,
1351 // packet number
1352 0x12, 0x34, 0x56, 0x79,
1353 };
1354 // clang-format on
1355 QuicReceivedPacket packet(coalesced_packet, 1200, QuicTime::Zero());
1356 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1357}
1358
danzh72e0dab2020-03-05 20:00:50 -08001359TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
1360 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1361
1362 EXPECT_CALL(*dispatcher_,
1363 CreateQuicSession(TestConnectionId(1), client_address,
1364 Eq(ExpectedAlpn()), _))
1365 .WillOnce(Return(ByMove(CreateSession(
1366 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1367 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1368 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1369 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1370 ProcessUdpPacket(_, _, _))
1371 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1372 ValidatePacket(TestConnectionId(1), packet);
1373 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001374 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001375
1376 dispatcher_->StopAcceptingNewConnections();
1377 EXPECT_FALSE(dispatcher_->accept_new_connections());
1378
1379 // No more new connections afterwards.
1380 EXPECT_CALL(*dispatcher_,
1381 CreateQuicSession(TestConnectionId(2), client_address,
1382 Eq(ExpectedAlpn()), _))
1383 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001384 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001385
1386 // Existing connections should be able to continue.
1387 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1388 ProcessUdpPacket(_, _, _))
1389 .Times(1u)
1390 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1391 ValidatePacket(TestConnectionId(1), packet);
1392 })));
1393 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1394}
1395
1396TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
1397 dispatcher_->StopAcceptingNewConnections();
1398 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1399
1400 // No more new connections afterwards.
1401 EXPECT_CALL(*dispatcher_,
1402 CreateQuicSession(TestConnectionId(2), client_address,
1403 Eq(ExpectedAlpn()), _))
1404 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001405 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001406
1407 dispatcher_->StartAcceptingNewConnections();
1408 EXPECT_TRUE(dispatcher_->accept_new_connections());
1409
1410 EXPECT_CALL(*dispatcher_,
1411 CreateQuicSession(TestConnectionId(1), client_address,
1412 Eq(ExpectedAlpn()), _))
1413 .WillOnce(Return(ByMove(CreateSession(
1414 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1415 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1416 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1417 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1418 ProcessUdpPacket(_, _, _))
1419 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1420 ValidatePacket(TestConnectionId(1), packet);
1421 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001422 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001423}
1424
dschinazi71116fd2020-04-22 16:07:04 -07001425TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
1426 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
1427 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
1428 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
1429 // Q033 is no longer supported but Q050 is.
1430 QuicEnableVersion(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
1431 EXPECT_EQ(
1432 QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
1433 "h3-Q050");
1434}
1435
QUICHE teama6ef0a62019-03-07 20:34:33 -05001436// Verify the stopgap test: Packets with truncated connection IDs should be
1437// dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001438class QuicDispatcherTestStrayPacketConnectionId
1439 : public QuicDispatcherTestBase {};
1440
1441INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
1442 QuicDispatcherTestStrayPacketConnectionId,
1443 ::testing::ValuesIn(CurrentSupportedVersions()),
1444 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001445
1446// Packets with truncated connection IDs should be dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001447TEST_P(QuicDispatcherTestStrayPacketConnectionId,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001448 StrayPacketTruncatedConnectionId) {
1449 CreateTimeWaitListManager();
1450
1451 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1452 QuicConnectionId connection_id = TestConnectionId(1);
dschinazi8d1c9d42020-02-18 13:12:20 -08001453 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1454 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
1455 EXPECT_CALL(*time_wait_list_manager_,
1456 AddConnectionIdToTimeWait(_, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001457 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001458
QUICHE teama6ef0a62019-03-07 20:34:33 -05001459 ProcessPacket(client_address, connection_id, true, "data",
1460 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1461}
1462
1463class BlockingWriter : public QuicPacketWriterWrapper {
1464 public:
1465 BlockingWriter() : write_blocked_(false) {}
1466
1467 bool IsWriteBlocked() const override { return write_blocked_; }
1468 void SetWritable() override { write_blocked_ = false; }
1469
dschinazi17d42422019-06-18 16:35:07 -07001470 WriteResult WritePacket(const char* /*buffer*/,
1471 size_t /*buf_len*/,
1472 const QuicIpAddress& /*self_client_address*/,
1473 const QuicSocketAddress& /*peer_client_address*/,
1474 PerPacketOptions* /*options*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001475 // It would be quite possible to actually implement this method here with
1476 // the fake blocked status, but it would be significantly more work in
1477 // Chromium, and since it's not called anyway, don't bother.
1478 QUIC_LOG(DFATAL) << "Not supported";
1479 return WriteResult();
1480 }
1481
1482 bool write_blocked_;
1483};
1484
dschinazi8d1c9d42020-02-18 13:12:20 -08001485class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001486 public:
1487 void SetUp() override {
dschinazi8d1c9d42020-02-18 13:12:20 -08001488 QuicDispatcherTestBase::SetUp();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001489 writer_ = new BlockingWriter;
1490 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1491
1492 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1493
1494 EXPECT_CALL(*dispatcher_,
bncf6e95ea2020-02-27 04:59:49 -08001495 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001496 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001497 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1498 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001499 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001500 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1501 ProcessUdpPacket(_, _, _))
1502 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1503 ValidatePacket(TestConnectionId(1), packet);
1504 })));
fayang1ed1f762019-06-24 11:40:04 -07001505 EXPECT_CALL(*dispatcher_,
1506 ShouldCreateOrBufferPacketForConnection(
1507 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001508 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001509
1510 EXPECT_CALL(*dispatcher_,
bncf6e95ea2020-02-27 04:59:49 -08001511 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001512 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001513 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1514 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001515 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001516 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1517 ProcessUdpPacket(_, _, _))
1518 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1519 ValidatePacket(TestConnectionId(2), packet);
1520 })));
fayang1ed1f762019-06-24 11:40:04 -07001521 EXPECT_CALL(*dispatcher_,
1522 ShouldCreateOrBufferPacketForConnection(
1523 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001524 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001525
1526 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1527 }
1528
1529 void TearDown() override {
1530 if (connection1() != nullptr) {
1531 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1532 }
1533
1534 if (connection2() != nullptr) {
1535 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1536 }
1537 dispatcher_->Shutdown();
1538 }
1539
1540 // Set the dispatcher's writer to be blocked. By default, all connections use
1541 // the same writer as the dispatcher in this test.
1542 void SetBlocked() {
1543 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1544 writer_->write_blocked_ = true;
1545 }
1546
1547 // Simulate what happens when connection1 gets blocked when writing.
1548 void BlockConnection1() {
1549 Connection1Writer()->write_blocked_ = true;
1550 dispatcher_->OnWriteBlocked(connection1());
1551 }
1552
1553 BlockingWriter* Connection1Writer() {
1554 return static_cast<BlockingWriter*>(connection1()->writer());
1555 }
1556
1557 // Simulate what happens when connection2 gets blocked when writing.
1558 void BlockConnection2() {
1559 Connection2Writer()->write_blocked_ = true;
1560 dispatcher_->OnWriteBlocked(connection2());
1561 }
1562
1563 BlockingWriter* Connection2Writer() {
1564 return static_cast<BlockingWriter*>(connection2()->writer());
1565 }
1566
1567 protected:
1568 MockQuicConnectionHelper helper_;
1569 MockAlarmFactory alarm_factory_;
1570 BlockingWriter* writer_;
1571 QuicDispatcher::WriteBlockedList* blocked_list_;
1572};
1573
dschinazi8d1c9d42020-02-18 13:12:20 -08001574INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
1575 QuicDispatcherWriteBlockedListTest,
1576 ::testing::Values(CurrentSupportedVersions().front()),
1577 ::testing::PrintToStringParamName());
1578
1579TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001580 // No OnCanWrite calls because no connections are blocked.
1581 dispatcher_->OnCanWrite();
1582
1583 // Register connection 1 for events, and make sure it's notified.
1584 SetBlocked();
1585 dispatcher_->OnWriteBlocked(connection1());
1586 EXPECT_CALL(*connection1(), OnCanWrite());
1587 dispatcher_->OnCanWrite();
1588
1589 // It should get only one notification.
1590 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1591 dispatcher_->OnCanWrite();
1592 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1593}
1594
dschinazi8d1c9d42020-02-18 13:12:20 -08001595TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001596 // Make sure we handle events in order.
1597 InSequence s;
1598 SetBlocked();
1599 dispatcher_->OnWriteBlocked(connection1());
1600 dispatcher_->OnWriteBlocked(connection2());
1601 EXPECT_CALL(*connection1(), OnCanWrite());
1602 EXPECT_CALL(*connection2(), OnCanWrite());
1603 dispatcher_->OnCanWrite();
1604
1605 // Check the other ordering.
1606 SetBlocked();
1607 dispatcher_->OnWriteBlocked(connection2());
1608 dispatcher_->OnWriteBlocked(connection1());
1609 EXPECT_CALL(*connection2(), OnCanWrite());
1610 EXPECT_CALL(*connection1(), OnCanWrite());
1611 dispatcher_->OnCanWrite();
1612}
1613
dschinazi8d1c9d42020-02-18 13:12:20 -08001614TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001615 // Add and remove one connction.
1616 SetBlocked();
1617 dispatcher_->OnWriteBlocked(connection1());
1618 blocked_list_->erase(connection1());
1619 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1620 dispatcher_->OnCanWrite();
1621
1622 // Add and remove one connction and make sure it doesn't affect others.
1623 SetBlocked();
1624 dispatcher_->OnWriteBlocked(connection1());
1625 dispatcher_->OnWriteBlocked(connection2());
1626 blocked_list_->erase(connection1());
1627 EXPECT_CALL(*connection2(), OnCanWrite());
1628 dispatcher_->OnCanWrite();
1629
1630 // Add it, remove it, and add it back and make sure things are OK.
1631 SetBlocked();
1632 dispatcher_->OnWriteBlocked(connection1());
1633 blocked_list_->erase(connection1());
1634 dispatcher_->OnWriteBlocked(connection1());
1635 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1636 dispatcher_->OnCanWrite();
1637}
1638
dschinazi8d1c9d42020-02-18 13:12:20 -08001639TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001640 // Make sure a double add does not necessitate a double remove.
1641 SetBlocked();
1642 dispatcher_->OnWriteBlocked(connection1());
1643 dispatcher_->OnWriteBlocked(connection1());
1644 blocked_list_->erase(connection1());
1645 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1646 dispatcher_->OnCanWrite();
1647
1648 // Make sure a double add does not result in two OnCanWrite calls.
1649 SetBlocked();
1650 dispatcher_->OnWriteBlocked(connection1());
1651 dispatcher_->OnWriteBlocked(connection1());
1652 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1653 dispatcher_->OnCanWrite();
1654}
1655
dschinazi8d1c9d42020-02-18 13:12:20 -08001656TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001657 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1658 // into the write blocked list.
1659 InSequence s;
1660 SetBlocked();
1661 dispatcher_->OnWriteBlocked(connection1());
1662 dispatcher_->OnWriteBlocked(connection2());
1663 EXPECT_CALL(*connection1(), OnCanWrite())
1664 .WillOnce(
1665 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1666 EXPECT_CALL(*connection2(), OnCanWrite());
1667 dispatcher_->OnCanWrite();
1668
1669 // connection1 should be still in the write blocked list.
1670 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1671
1672 // Now call OnCanWrite again, connection1 should get its second chance.
1673 EXPECT_CALL(*connection1(), OnCanWrite());
1674 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1675 dispatcher_->OnCanWrite();
1676 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1677}
1678
dschinazi8d1c9d42020-02-18 13:12:20 -08001679TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001680 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1681 // into the write blocked list.
1682 InSequence s;
1683 SetBlocked();
1684 dispatcher_->OnWriteBlocked(connection1());
1685 dispatcher_->OnWriteBlocked(connection2());
1686 EXPECT_CALL(*connection1(), OnCanWrite());
1687 EXPECT_CALL(*connection2(), OnCanWrite())
1688 .WillOnce(
1689 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1690 dispatcher_->OnCanWrite();
1691
1692 // connection2 should be still in the write blocked list.
1693 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1694
1695 // Now call OnCanWrite again, connection2 should get its second chance.
1696 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1697 EXPECT_CALL(*connection2(), OnCanWrite());
1698 dispatcher_->OnCanWrite();
1699 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1700}
1701
dschinazi8d1c9d42020-02-18 13:12:20 -08001702TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001703 OnCanWriteHandleBlockBothConnections) {
1704 // Both connections get blocked in OnCanWrite, and added back into the write
1705 // blocked list.
1706 InSequence s;
1707 SetBlocked();
1708 dispatcher_->OnWriteBlocked(connection1());
1709 dispatcher_->OnWriteBlocked(connection2());
1710 EXPECT_CALL(*connection1(), OnCanWrite())
1711 .WillOnce(
1712 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1713 EXPECT_CALL(*connection2(), OnCanWrite())
1714 .WillOnce(
1715 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1716 dispatcher_->OnCanWrite();
1717
1718 // Both connections should be still in the write blocked list.
1719 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1720
1721 // Now call OnCanWrite again, both connections should get its second chance.
1722 EXPECT_CALL(*connection1(), OnCanWrite());
1723 EXPECT_CALL(*connection2(), OnCanWrite());
1724 dispatcher_->OnCanWrite();
1725 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1726}
1727
dschinazi8d1c9d42020-02-18 13:12:20 -08001728TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001729 // By default, all connections share the same packet writer with the
1730 // dispatcher.
1731 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1732 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1733
1734 // Test the case where connection1 shares the same packet writer as the
1735 // dispatcher, whereas connection2 owns it's packet writer.
1736 // Change connection2's writer.
1737 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1738 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1739
1740 BlockConnection2();
1741 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1742
1743 EXPECT_CALL(*connection2(), OnCanWrite());
1744 dispatcher_->OnCanWrite();
1745 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1746}
1747
dschinazi8d1c9d42020-02-18 13:12:20 -08001748TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001749 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001750 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1751 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1752 ConnectionCloseSource::FROM_SELF);
1753
1754 SetBlocked();
1755
1756 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1757 SetBlocked();
1758 dispatcher_->OnWriteBlocked(connection1());
1759 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1760
1761 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1762 "QuicConnection was in WriteBlockedList before destruction");
1763 MarkSession1Deleted();
1764}
1765
dschinazi8d1c9d42020-02-18 13:12:20 -08001766class BufferedPacketStoreTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001767 public:
1768 BufferedPacketStoreTest()
dschinazi8d1c9d42020-02-18 13:12:20 -08001769 : QuicDispatcherTestBase(),
dschinazi42fc2da2020-04-24 16:19:17 -07001770 client_addr_(QuicIpAddress::Loopback4(), 1234) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -05001771
dschinazi42fc2da2020-04-24 16:19:17 -07001772 void ProcessFirstFlight(const ParsedQuicVersion& version,
1773 const QuicSocketAddress& peer_address,
1774 const QuicConnectionId& server_connection_id) {
1775 QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
1776 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001777 }
1778
dschinazi42fc2da2020-04-24 16:19:17 -07001779 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
1780 const QuicConnectionId& server_connection_id) {
1781 ProcessFirstFlight(version_, peer_address, server_connection_id);
1782 }
1783
1784 void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
1785 ProcessFirstFlight(client_addr_, server_connection_id);
1786 }
1787
1788 void ProcessFirstFlight(const ParsedQuicVersion& version,
1789 const QuicConnectionId& server_connection_id) {
1790 ProcessFirstFlight(version, client_addr_, server_connection_id);
1791 }
1792
1793 void ProcessUndecryptableEarlyPacket(
1794 const ParsedQuicVersion& version,
1795 const QuicSocketAddress& peer_address,
1796 const QuicConnectionId& server_connection_id) {
1797 QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
1798 version, peer_address, server_connection_id);
1799 }
1800
1801 void ProcessUndecryptableEarlyPacket(
1802 const QuicSocketAddress& peer_address,
1803 const QuicConnectionId& server_connection_id) {
1804 ProcessUndecryptableEarlyPacket(version_, peer_address,
1805 server_connection_id);
1806 }
1807
1808 void ProcessUndecryptableEarlyPacket(
1809 const QuicConnectionId& server_connection_id) {
1810 ProcessUndecryptableEarlyPacket(version_, client_addr_,
1811 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001812 }
1813
1814 protected:
QUICHE teama6ef0a62019-03-07 20:34:33 -05001815 QuicSocketAddress client_addr_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001816};
1817
dschinazi8d1c9d42020-02-18 13:12:20 -08001818INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests,
1819 BufferedPacketStoreTest,
dschinazi42fc2da2020-04-24 16:19:17 -07001820 ::testing::ValuesIn(CurrentSupportedVersions()),
dschinazi8d1c9d42020-02-18 13:12:20 -08001821 ::testing::PrintToStringParamName());
1822
dschinazi42fc2da2020-04-24 16:19:17 -07001823TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
1824 InSequence s;
1825 QuicConnectionId conn_id = TestConnectionId(1);
1826 // Non-CHLO should be buffered upon arrival, and should trigger
1827 // ShouldCreateOrBufferPacketForConnection().
1828 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1829 ReceivedPacketInfoConnectionIdEquals(conn_id)));
1830 // Process non-CHLO packet.
1831 ProcessUndecryptableEarlyPacket(conn_id);
1832 EXPECT_EQ(0u, dispatcher_->session_map().size())
1833 << "No session should be created before CHLO arrives.";
1834
1835 // When CHLO arrives, a new session should be created, and all packets
1836 // buffered should be delivered to the session.
1837 EXPECT_CALL(*dispatcher_,
1838 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
1839 .WillOnce(Return(ByMove(CreateSession(
1840 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
1841 &mock_alarm_factory_, &crypto_config_,
1842 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1843 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1844 ProcessUdpPacket(_, _, _))
1845 .Times(2) // non-CHLO + CHLO.
1846 .WillRepeatedly(
1847 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1848 if (version_.UsesQuicCrypto()) {
1849 ValidatePacket(conn_id, packet);
1850 }
1851 })));
1852 ProcessFirstFlight(conn_id);
1853}
1854
dschinazi8d1c9d42020-02-18 13:12:20 -08001855TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001856 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001857 QuicConnectionId conn_id = TestConnectionId(1);
1858 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1859 // should trigger ShouldCreateOrBufferPacketForConnection().
fayang1ed1f762019-06-24 11:40:04 -07001860 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1861 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001862 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
dschinazi42fc2da2020-04-24 16:19:17 -07001863 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001864 }
1865 EXPECT_EQ(0u, dispatcher_->session_map().size())
1866 << "No session should be created before CHLO arrives.";
1867
1868 // Pop out the last packet as it is also be dropped by the store.
1869 data_connection_map_[conn_id].pop_back();
1870 // When CHLO arrives, a new session should be created, and all packets
1871 // buffered should be delivered to the session.
dschinazi42fc2da2020-04-24 16:19:17 -07001872 EXPECT_CALL(*dispatcher_,
1873 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001874 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07001875 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001876 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001877 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001878
1879 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1880 // should be delivered in arrival order.
1881 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1882 ProcessUdpPacket(_, _, _))
1883 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1884 .WillRepeatedly(
1885 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001886 if (version_.UsesQuicCrypto()) {
1887 ValidatePacket(conn_id, packet);
1888 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001889 })));
dschinazi42fc2da2020-04-24 16:19:17 -07001890 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001891}
1892
dschinazi8d1c9d42020-02-18 13:12:20 -08001893TEST_P(BufferedPacketStoreTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001894 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1895 InSequence s;
1896 // A bunch of non-CHLO should be buffered upon arrival.
1897 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1898 for (size_t i = 1; i <= kNumConnections; ++i) {
1899 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1900 QuicConnectionId conn_id = TestConnectionId(i);
1901 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001902 ShouldCreateOrBufferPacketForConnection(
1903 ReceivedPacketInfoConnectionIdEquals(conn_id)));
dschinazi42fc2da2020-04-24 16:19:17 -07001904 ProcessUndecryptableEarlyPacket(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001905 }
1906
1907 // Pop out the packet on last connection as it shouldn't be enqueued in store
1908 // as well.
1909 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1910
1911 // Reset session creation counter to ensure processing CHLO can always
1912 // create session.
1913 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
1914 kNumConnections);
1915 // Process CHLOs to create session for these connections.
1916 for (size_t i = 1; i <= kNumConnections; ++i) {
1917 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1918 QuicConnectionId conn_id = TestConnectionId(i);
1919 if (i == kNumConnections) {
1920 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001921 ShouldCreateOrBufferPacketForConnection(
1922 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001923 }
1924 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address,
dschinazi42fc2da2020-04-24 16:19:17 -07001925 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001926 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001927 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1928 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001929 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001930 // First |kNumConnections| - 1 connections should have buffered
1931 // a packet in store. The rest should have been dropped.
1932 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
1933 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1934 ProcessUdpPacket(_, client_address, _))
1935 .Times(num_packet_to_process)
1936 .WillRepeatedly(WithArg<2>(
1937 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001938 if (version_.UsesQuicCrypto()) {
1939 ValidatePacket(conn_id, packet);
1940 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001941 })));
1942
dschinazi42fc2da2020-04-24 16:19:17 -07001943 ProcessFirstFlight(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001944 }
1945}
1946
1947// Tests that store delivers empty packet list if CHLO arrives firstly.
dschinazi8d1c9d42020-02-18 13:12:20 -08001948TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001949 QuicConnectionId conn_id = TestConnectionId(1);
fayang1ed1f762019-06-24 11:40:04 -07001950 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1951 ReceivedPacketInfoConnectionIdEquals(conn_id)));
dschinazi42fc2da2020-04-24 16:19:17 -07001952 EXPECT_CALL(*dispatcher_,
1953 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001954 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07001955 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001956 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001957 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001958 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
dschinazi42fc2da2020-04-24 16:19:17 -07001959 ProcessUdpPacket(_, client_addr_, _));
1960 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001961}
1962
1963// Tests that a retransmitted CHLO arrives after a connection for the
1964// CHLO has been created.
dschinazi8d1c9d42020-02-18 13:12:20 -08001965TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001966 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001967 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07001968 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001969
1970 // When CHLO arrives, a new session should be created, and all packets
1971 // buffered should be delivered to the session.
dschinazi42fc2da2020-04-24 16:19:17 -07001972 EXPECT_CALL(*dispatcher_,
1973 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001974 .Times(1) // Only triggered by 1st CHLO.
wub89490e02019-12-12 12:45:58 -08001975 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07001976 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001977 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001978 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001979 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1980 ProcessUdpPacket(_, _, _))
1981 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
1982 .WillRepeatedly(
1983 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001984 if (version_.UsesQuicCrypto()) {
1985 ValidatePacket(conn_id, packet);
1986 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001987 })));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001988
dschinazi42fc2da2020-04-24 16:19:17 -07001989 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
1990 GetFirstFlightOfPackets(version_, conn_id);
1991 ASSERT_EQ(packets.size(), 1u);
1992 // Receive the CHLO once.
1993 ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
1994 // Receive the CHLO a second time to simulate retransmission.
1995 ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001996}
1997
1998// Tests that expiration of a connection add connection id to time wait list.
dschinazi8d1c9d42020-02-18 13:12:20 -08001999TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002000 InSequence s;
2001 CreateTimeWaitListManager();
2002 QuicBufferedPacketStore* store =
2003 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2004 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2005
QUICHE teama6ef0a62019-03-07 20:34:33 -05002006 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07002007 ProcessPacket(client_addr_, conn_id, true,
dmcardlecf0bfcf2019-12-13 08:08:21 -08002008 quiche::QuicheStrCat("data packet ", 2), CONNECTION_ID_PRESENT,
2009 PACKET_4BYTE_PACKET_NUMBER,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002010 /*packet_number=*/2);
2011
2012 mock_helper_.AdvanceTime(
2013 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2014 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
2015 // Cancel alarm as if it had been fired.
2016 alarm->Cancel();
2017 store->OnExpirationTimeout();
2018 // New arrived CHLO will be dropped because this connection is in time wait
2019 // list.
2020 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2021 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
dschinazi42fc2da2020-04-24 16:19:17 -07002022 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002023}
2024
dschinazi8d1c9d42020-02-18 13:12:20 -08002025TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002026 // Process more than (|kMaxNumSessionsToCreate| +
2027 // |kDefaultMaxConnectionsInStore|) CHLOs,
2028 // the first |kMaxNumSessionsToCreate| should create connections immediately,
2029 // the next |kDefaultMaxConnectionsInStore| should be buffered,
2030 // the rest should be dropped.
2031 QuicBufferedPacketStore* store =
2032 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2033 const size_t kNumCHLOs =
2034 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
2035 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
fayang1ed1f762019-06-24 11:40:04 -07002036 EXPECT_CALL(
2037 *dispatcher_,
2038 ShouldCreateOrBufferPacketForConnection(
2039 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002040 if (conn_id <= kMaxNumSessionsToCreate) {
2041 EXPECT_CALL(*dispatcher_,
2042 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002043 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002044 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002045 dispatcher_.get(), config_, TestConnectionId(conn_id),
2046 client_addr_, &mock_helper_, &mock_alarm_factory_,
2047 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002048 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002049 EXPECT_CALL(
2050 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2051 ProcessUdpPacket(_, _, _))
2052 .WillOnce(WithArg<2>(
2053 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002054 if (version_.UsesQuicCrypto()) {
2055 ValidatePacket(TestConnectionId(conn_id), packet);
2056 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002057 })));
2058 }
dschinazi42fc2da2020-04-24 16:19:17 -07002059 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002060 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
2061 conn_id > kMaxNumSessionsToCreate) {
2062 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
2063 } else {
2064 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
2065 // connections immediately, and the last CHLO should be dropped as the
2066 // store is full.
2067 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
2068 }
2069 }
2070
2071 // Graduately consume buffered CHLOs. The buffered connections should be
2072 // created but the dropped one shouldn't.
2073 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2074 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
2075 ++conn_id) {
2076 EXPECT_CALL(*dispatcher_,
2077 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002078 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002079 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002080 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2081 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002082 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002083 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2084 ProcessUdpPacket(_, _, _))
2085 .WillOnce(WithArg<2>(
2086 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002087 if (version_.UsesQuicCrypto()) {
2088 ValidatePacket(TestConnectionId(conn_id), packet);
2089 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002090 })));
2091 }
2092 EXPECT_CALL(*dispatcher_,
2093 CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002094 Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05002095 .Times(0);
2096
2097 while (store->HasChlosBuffered()) {
2098 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2099 }
2100
2101 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
2102 kDefaultMaxConnectionsInStore),
2103 session1_->connection_id());
2104}
2105
2106// Duplicated CHLO shouldn't be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002107TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002108 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
2109 ++conn_id) {
2110 // Last CHLO will be buffered. Others will create connection right away.
2111 if (conn_id <= kMaxNumSessionsToCreate) {
2112 EXPECT_CALL(*dispatcher_,
2113 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002114 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002115 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002116 dispatcher_.get(), config_, TestConnectionId(conn_id),
2117 client_addr_, &mock_helper_, &mock_alarm_factory_,
2118 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002119 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002120 EXPECT_CALL(
2121 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2122 ProcessUdpPacket(_, _, _))
2123 .WillOnce(WithArg<2>(
2124 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002125 if (version_.UsesQuicCrypto()) {
2126 ValidatePacket(TestConnectionId(conn_id), packet);
2127 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002128 })));
2129 }
dschinazi42fc2da2020-04-24 16:19:17 -07002130 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002131 }
2132 // Retransmit CHLO on last connection should be dropped.
2133 QuicConnectionId last_connection =
2134 TestConnectionId(kMaxNumSessionsToCreate + 1);
dschinazi42fc2da2020-04-24 16:19:17 -07002135 ProcessFirstFlight(last_connection);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002136
2137 size_t packets_buffered = 2;
2138
2139 // Reset counter and process buffered CHLO.
2140 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002141 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002142 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002143 dispatcher_.get(), config_, last_connection, client_addr_,
2144 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002145 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002146 // Only one packet(CHLO) should be process.
2147 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2148 ProcessUdpPacket(_, _, _))
2149 .Times(packets_buffered)
2150 .WillRepeatedly(WithArg<2>(
2151 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002152 if (version_.UsesQuicCrypto()) {
2153 ValidatePacket(last_connection, packet);
2154 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002155 })));
2156 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2157}
2158
dschinazi8d1c9d42020-02-18 13:12:20 -08002159TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002160 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2161 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2162 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2163 // Last CHLO will be buffered. Others will create connection right away.
2164 if (conn_id <= kMaxNumSessionsToCreate) {
2165 EXPECT_CALL(*dispatcher_,
2166 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002167 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002168 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002169 dispatcher_.get(), config_, TestConnectionId(conn_id),
2170 client_addr_, &mock_helper_, &mock_alarm_factory_,
2171 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002172 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002173 EXPECT_CALL(
2174 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2175 ProcessUdpPacket(_, _, _))
2176 .WillRepeatedly(WithArg<2>(
2177 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002178 if (version_.UsesQuicCrypto()) {
2179 ValidatePacket(TestConnectionId(conn_id), packet);
2180 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002181 })));
2182 }
dschinazi42fc2da2020-04-24 16:19:17 -07002183 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002184 }
2185
2186 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
2187 // last one should be dropped.
2188 for (uint64_t packet_number = 2;
2189 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
2190 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
2191 }
2192
2193 // Reset counter and process buffered CHLO.
2194 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002195 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002196 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002197 dispatcher_.get(), config_, last_connection_id, client_addr_,
2198 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002199 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002200 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
2201 // should be process.
2202 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2203 ProcessUdpPacket(_, _, _))
2204 .Times(kDefaultMaxUndecryptablePackets + 1)
2205 .WillRepeatedly(WithArg<2>(
2206 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002207 if (version_.UsesQuicCrypto()) {
2208 ValidatePacket(last_connection_id, packet);
2209 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002210 })));
2211 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2212}
2213
2214// Tests that when dispatcher's packet buffer is full, a CHLO on connection
2215// which doesn't have buffered CHLO should be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002216TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002217 QuicBufferedPacketStore* store =
2218 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2219
2220 uint64_t conn_id = 1;
dschinazi42fc2da2020-04-24 16:19:17 -07002221 ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002222 // Fill packet buffer to full with CHLOs on other connections. Need to feed
2223 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
2224 // session directly.
2225 for (conn_id = 2;
2226 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
2227 ++conn_id) {
2228 if (conn_id <= kMaxNumSessionsToCreate + 1) {
2229 EXPECT_CALL(*dispatcher_,
2230 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002231 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002232 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002233 dispatcher_.get(), config_, TestConnectionId(conn_id),
2234 client_addr_, &mock_helper_, &mock_alarm_factory_,
2235 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002236 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002237 EXPECT_CALL(
2238 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2239 ProcessUdpPacket(_, _, _))
2240 .WillOnce(WithArg<2>(
2241 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002242 if (version_.UsesQuicCrypto()) {
2243 ValidatePacket(TestConnectionId(conn_id), packet);
2244 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002245 })));
2246 }
dschinazi42fc2da2020-04-24 16:19:17 -07002247 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002248 }
2249 EXPECT_FALSE(store->HasChloForConnection(
2250 /*connection_id=*/TestConnectionId(1)));
2251
2252 // CHLO on connection 1 should still be buffered.
dschinazi42fc2da2020-04-24 16:19:17 -07002253 ProcessFirstFlight(TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002254 EXPECT_TRUE(store->HasChloForConnection(
2255 /*connection_id=*/TestConnectionId(1)));
2256}
2257
2258// Regression test for b/117874922.
dschinazi8d1c9d42020-02-18 13:12:20 -08002259TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
dschinazic3316f32020-03-05 14:34:36 -08002260 // Ensure the preferred version is not supported by the server.
dschinazi5a50d932020-06-17 12:43:36 -07002261 QuicDisableVersion(AllSupportedVersions().front());
dschinazib3fed9e2020-06-11 11:59:33 -07002262
QUICHE teama6ef0a62019-03-07 20:34:33 -05002263 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
2264 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
2265 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
2266 // Last 5 CHLOs will be buffered. Others will create connection right away.
2267 ParsedQuicVersion version =
2268 supported_versions[(conn_id - 1) % supported_versions.size()];
2269 if (conn_id <= kMaxNumSessionsToCreate) {
dschinazi42fc2da2020-04-24 16:19:17 -07002270 EXPECT_CALL(
2271 *dispatcher_,
2272 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2273 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002274 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002275 dispatcher_.get(), config_, TestConnectionId(conn_id),
2276 client_addr_, &mock_helper_, &mock_alarm_factory_,
2277 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002278 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002279 EXPECT_CALL(
2280 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2281 ProcessUdpPacket(_, _, _))
2282 .WillRepeatedly(WithArg<2>(
2283 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002284 if (version_.UsesQuicCrypto()) {
2285 ValidatePacket(TestConnectionId(conn_id), packet);
2286 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002287 })));
2288 }
dschinazi42fc2da2020-04-24 16:19:17 -07002289 ProcessFirstFlight(version, TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002290 }
2291
2292 // Process buffered CHLOs. Verify the version is correct.
2293 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2294 conn_id <= last_connection_id; ++conn_id) {
2295 ParsedQuicVersion version =
2296 supported_versions[(conn_id - 1) % supported_versions.size()];
2297 EXPECT_CALL(*dispatcher_,
2298 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002299 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002300 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002301 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2302 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002303 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002304 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2305 ProcessUdpPacket(_, _, _))
2306 .WillRepeatedly(WithArg<2>(
2307 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002308 if (version_.UsesQuicCrypto()) {
2309 ValidatePacket(TestConnectionId(conn_id), packet);
2310 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002311 })));
2312 }
2313 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2314}
2315
QUICHE teama6ef0a62019-03-07 20:34:33 -05002316} // namespace
2317} // namespace test
2318} // namespace quic