blob: 01ed4fb7f566e144603c6839c4e351ea97efefbd [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
dschinazi6458eb32020-06-23 12:38:41 -0700583TEST_P(QuicDispatcherTestAllVersions, LegacyVersionEncapsulation) {
584 if (!version_.HasLongHeaderLengths()) {
585 // Decapsulating Legacy Version Encapsulation packets from these versions
586 // is not currently supported in QuicDispatcher.
587 return;
588 }
589 SetQuicReloadableFlag(quic_dont_pad_chlo, true);
590 SetQuicReloadableFlag(quic_dispatcher_legacy_version_encapsulation, true);
591 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
592 QuicConnectionId server_connection_id = TestConnectionId();
593 QuicConfig client_config = DefaultQuicConfig();
594 client_config.SetClientConnectionOptions(QuicTagVector{kQLVE});
595 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
596 GetFirstFlightOfPackets(version_, client_config, server_connection_id);
597 ASSERT_EQ(packets.size(), 1u);
598
599 // Validate that Legacy Version Encapsulation is actually being used by
600 // checking the version of the packet before processing it.
601 PacketHeaderFormat format = IETF_QUIC_LONG_HEADER_PACKET;
602 QuicLongHeaderType long_packet_type;
603 bool version_present;
604 bool has_length_prefix;
605 QuicVersionLabel version_label;
606 ParsedQuicVersion parsed_version = ParsedQuicVersion::Unsupported();
607 QuicConnectionId destination_connection_id, source_connection_id;
608 bool retry_token_present;
609 quiche::QuicheStringPiece retry_token;
610 std::string detailed_error;
611 const QuicErrorCode error = QuicFramer::ParsePublicHeaderDispatcher(
612 QuicEncryptedPacket(packets[0]->data(), packets[0]->length()),
613 kQuicDefaultConnectionIdLength, &format, &long_packet_type,
614 &version_present, &has_length_prefix, &version_label, &parsed_version,
615 &destination_connection_id, &source_connection_id, &retry_token_present,
616 &retry_token, &detailed_error);
617 ASSERT_THAT(error, IsQuicNoError()) << detailed_error;
618 EXPECT_EQ(format, GOOGLE_QUIC_PACKET);
619 EXPECT_TRUE(version_present);
620 EXPECT_FALSE(has_length_prefix);
621 EXPECT_EQ(parsed_version, LegacyVersionForEncapsulation());
622 EXPECT_EQ(destination_connection_id, server_connection_id);
623 EXPECT_EQ(source_connection_id, EmptyQuicConnectionId());
624 EXPECT_FALSE(retry_token_present);
625 EXPECT_TRUE(detailed_error.empty());
626
627 // Processing the packet should create a new session.
628 EXPECT_CALL(*dispatcher_,
629 CreateQuicSession(server_connection_id, client_address,
630 Eq(ExpectedAlpn()), _))
631 .WillOnce(Return(ByMove(CreateSession(
632 dispatcher_.get(), config_, server_connection_id, client_address,
633 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
634 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
635 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
636 ProcessUdpPacket(_, _, _))
637 .Times(2);
638
639 ProcessReceivedPacket(packets[0]->Clone(), client_address, version_,
640 server_connection_id);
641 EXPECT_EQ(dispatcher_->session_map().size(), 1u);
642
643 // Processing the same packet a second time should also be routed by the
644 // dispatcher to the right connection (we expect ProcessUdpPacket to be
645 // called twice, see the EXPECT_CALL above).
646 ProcessReceivedPacket(std::move(packets[0]), client_address, version_,
647 server_connection_id);
648}
649
dschinazi8d1c9d42020-02-18 13:12:20 -0800650TEST_P(QuicDispatcherTestAllVersions, ProcessPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500651 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
652
653 EXPECT_CALL(*dispatcher_,
654 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800655 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800656 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500657 dispatcher_.get(), config_, TestConnectionId(1), client_address,
658 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800659 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500660 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
661 ProcessUdpPacket(_, _, _))
662 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
663 ValidatePacket(TestConnectionId(1), packet);
664 })));
665 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700666 ShouldCreateOrBufferPacketForConnection(
667 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700668 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500669
670 EXPECT_CALL(*dispatcher_,
671 CreateQuicSession(TestConnectionId(2), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800672 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800673 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500674 dispatcher_.get(), config_, TestConnectionId(2), client_address,
675 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800676 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500677 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
678 ProcessUdpPacket(_, _, _))
679 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
680 ValidatePacket(TestConnectionId(2), packet);
681 })));
682 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700683 ShouldCreateOrBufferPacketForConnection(
684 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700685 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500686
687 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
688 ProcessUdpPacket(_, _, _))
689 .Times(1)
690 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
691 ValidatePacket(TestConnectionId(1), packet);
692 })));
693 ProcessPacket(client_address, TestConnectionId(1), false, "data");
694}
695
696// Regression test of b/93325907.
dschinazi8d1c9d42020-02-18 13:12:20 -0800697TEST_P(QuicDispatcherTestAllVersions, DispatcherDoesNotRejectPacketNumberZero) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500698 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
699
700 EXPECT_CALL(*dispatcher_,
701 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800702 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800703 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500704 dispatcher_.get(), config_, TestConnectionId(1), client_address,
705 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800706 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500707 // Verify both packets 1 and 2 are processed by connection 1.
708 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
709 ProcessUdpPacket(_, _, _))
710 .Times(2)
711 .WillRepeatedly(
712 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
713 ValidatePacket(TestConnectionId(1), packet);
714 })));
715 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700716 ShouldCreateOrBufferPacketForConnection(
717 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700718 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500719 // Packet number 256 with packet number length 1 would be considered as 0 in
720 // dispatcher.
dschinazi8d1c9d42020-02-18 13:12:20 -0800721 ProcessPacket(client_address, TestConnectionId(1), false, version_, "", true,
722 CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500723}
724
dschinazi8d1c9d42020-02-18 13:12:20 -0800725TEST_P(QuicDispatcherTestOneVersion, StatelessVersionNegotiation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500726 CreateTimeWaitListManager();
727 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
728
729 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
dschinazi346b7ce2019-06-05 01:38:18 -0700730 EXPECT_CALL(
731 *time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700732 SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500733 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700734 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
735 TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500736}
737
dschinazi8d1c9d42020-02-18 13:12:20 -0800738TEST_P(QuicDispatcherTestOneVersion,
dschinaziffa83552019-12-17 11:00:23 -0800739 StatelessVersionNegotiationWithVeryLongConnectionId) {
dschinaziffa83552019-12-17 11:00:23 -0800740 QuicConnectionId connection_id = QuicUtils::CreateRandomConnectionId(33);
741 CreateTimeWaitListManager();
742 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
743
744 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
745 EXPECT_CALL(*time_wait_list_manager_,
746 SendVersionNegotiationPacket(connection_id, _, _, _, _, _, _, _))
747 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700748 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
749 connection_id);
dschinaziffa83552019-12-17 11:00:23 -0800750}
751
dschinazi8d1c9d42020-02-18 13:12:20 -0800752TEST_P(QuicDispatcherTestOneVersion,
753 StatelessVersionNegotiationWithClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700754 CreateTimeWaitListManager();
755 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
756
757 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
758 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700759 SendVersionNegotiationPacket(
760 TestConnectionId(1), TestConnectionId(2), _, _, _, _, _, _))
dschinazi346b7ce2019-06-05 01:38:18 -0700761 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700762 ProcessFirstFlight(QuicVersionReservedForNegotiation(), client_address,
763 TestConnectionId(1), TestConnectionId(2));
dschinazi346b7ce2019-06-05 01:38:18 -0700764}
765
dschinazi8d1c9d42020-02-18 13:12:20 -0800766TEST_P(QuicDispatcherTestOneVersion, NoVersionNegotiationWithSmallPacket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500767 CreateTimeWaitListManager();
768 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
769
770 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
771 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700772 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500773 .Times(0);
vasilvvc48c8712019-03-11 13:38:16 -0700774 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500775 // Truncate to 1100 bytes of payload which results in a packet just
776 // under 1200 bytes after framing, packet, and encryption overhead.
777 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700778 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500779 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700780 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700781 QuicVersionReservedForNegotiation(), truncated_chlo, false,
nharper4fd11052019-06-04 14:23:22 -0700782 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500783}
784
785// Disabling CHLO size validation allows the dispatcher to send version
786// negotiation packets in response to a CHLO that is otherwise too small.
dschinazi8d1c9d42020-02-18 13:12:20 -0800787TEST_P(QuicDispatcherTestOneVersion,
788 VersionNegotiationWithoutChloSizeValidation) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500789 crypto_config_.set_validate_chlo_size(false);
790
791 CreateTimeWaitListManager();
792 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
793
794 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
795 EXPECT_CALL(*time_wait_list_manager_,
dschinazi48ac9192019-07-31 00:07:26 -0700796 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500797 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -0700798 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500799 // Truncate to 1100 bytes of payload which results in a packet just
800 // under 1200 bytes after framing, packet, and encryption overhead.
801 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700802 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500803 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700804 ProcessPacket(client_address, TestConnectionId(1), true,
fayange3f2f7b2019-09-19 17:01:57 -0700805 QuicVersionReservedForNegotiation(), truncated_chlo, true,
nharper4fd11052019-06-04 14:23:22 -0700806 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500807}
808
dschinazi8d1c9d42020-02-18 13:12:20 -0800809TEST_P(QuicDispatcherTestAllVersions, Shutdown) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500810 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
811
dschinazi8d1c9d42020-02-18 13:12:20 -0800812 EXPECT_CALL(*dispatcher_,
813 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800814 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500815 dispatcher_.get(), config_, TestConnectionId(1), client_address,
816 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800817 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500818 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
819 ProcessUdpPacket(_, _, _))
820 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
821 ValidatePacket(TestConnectionId(1), packet);
822 })));
823
824 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700825 ShouldCreateOrBufferPacketForConnection(
826 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700827 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500828
829 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
830 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
831
832 dispatcher_->Shutdown();
833}
834
dschinazi8d1c9d42020-02-18 13:12:20 -0800835TEST_P(QuicDispatcherTestAllVersions, TimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500836 CreateTimeWaitListManager();
837
838 // Create a new session.
839 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
840 QuicConnectionId connection_id = TestConnectionId(1);
dschinazi8d1c9d42020-02-18 13:12:20 -0800841 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
842 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800843 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500844 dispatcher_.get(), config_, connection_id, client_address,
845 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800846 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500847 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
848 ProcessUdpPacket(_, _, _))
849 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
850 ValidatePacket(TestConnectionId(1), packet);
851 })));
852
853 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700854 ShouldCreateOrBufferPacketForConnection(
855 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -0700856 ProcessFirstFlight(client_address, connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500857
858 // Now close the connection, which should add it to the time wait list.
859 session1_->connection()->CloseConnection(
860 QUIC_INVALID_VERSION,
861 "Server: Packet 2 without version flag before version negotiated.",
862 ConnectionCloseBehavior::SILENT_CLOSE);
863 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
864
865 // Dispatcher forwards subsequent packets for this connection_id to the time
866 // wait list manager.
867 EXPECT_CALL(*time_wait_list_manager_,
868 ProcessPacket(_, _, connection_id, _, _))
869 .Times(1);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700870 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500871 .Times(0);
872 ProcessPacket(client_address, connection_id, true, "data");
873}
874
dschinazi8d1c9d42020-02-18 13:12:20 -0800875TEST_P(QuicDispatcherTestAllVersions, NoVersionPacketToTimeWaitListManager) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500876 CreateTimeWaitListManager();
877
878 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
879 QuicConnectionId connection_id = TestConnectionId(1);
880 // Dispatcher forwards all packets for this connection_id to the time wait
881 // list manager.
dschinazi8d1c9d42020-02-18 13:12:20 -0800882 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800883 EXPECT_CALL(*time_wait_list_manager_,
884 ProcessPacket(_, _, connection_id, _, _))
885 .Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700886 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
fayang9d6231c2019-12-04 07:10:13 -0800887 .Times(0);
888 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
889 .Times(1);
dschinazi6b40b1d2020-04-22 06:15:46 -0700890 ProcessPacket(client_address, connection_id, /*has_version_flag=*/false,
891 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500892}
893
dschinazi8d1c9d42020-02-18 13:12:20 -0800894TEST_P(QuicDispatcherTestAllVersions,
fayangd057e662019-07-10 13:29:41 -0700895 DonotTimeWaitPacketsWithUnknownConnectionIdAndNoVersion) {
896 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
897 CreateTimeWaitListManager();
898
899 char short_packet[22] = {0x70, 0xa7, 0x02, 0x6b};
900 QuicReceivedPacket packet(short_packet, 22, QuicTime::Zero());
901 char valid_size_packet[23] = {0x70, 0xa7, 0x02, 0x6c};
902 QuicReceivedPacket packet2(valid_size_packet, 23, QuicTime::Zero());
903 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
fayang9d6231c2019-12-04 07:10:13 -0800904 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -0700905 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
fayang9d6231c2019-12-04 07:10:13 -0800906 .Times(0);
907 // Verify small packet is silently dropped.
908 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
909 .Times(0);
fayangd057e662019-07-10 13:29:41 -0700910 dispatcher_->ProcessPacket(server_address_, client_address, packet);
fayang9d6231c2019-12-04 07:10:13 -0800911 EXPECT_CALL(*time_wait_list_manager_, SendPublicReset(_, _, _, _, _))
912 .Times(1);
fayangd057e662019-07-10 13:29:41 -0700913 dispatcher_->ProcessPacket(server_address_, client_address, packet2);
914}
915
QUICHE teamc65d1d12019-03-19 20:58:04 -0700916// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800917TEST_P(QuicDispatcherTestAllVersions, LongConnectionIdLengthReplaced) {
918 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700919 // When variable length connection IDs are not supported, the connection
920 // fails. See StrayPacketTruncatedConnectionId.
QUICHE team8e2e4532019-03-14 14:37:56 -0700921 return;
922 }
QUICHE team8e2e4532019-03-14 14:37:56 -0700923 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
924
QUICHE teamc65d1d12019-03-19 20:58:04 -0700925 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700926 QuicConnectionId fixed_connection_id =
927 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700928
929 EXPECT_CALL(*dispatcher_,
930 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800931 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800932 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700933 dispatcher_.get(), config_, fixed_connection_id, client_address,
934 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800935 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -0700936 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
937 ProcessUdpPacket(_, _, _))
938 .WillOnce(WithArg<2>(
939 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
940 ValidatePacket(bad_connection_id, packet);
941 })));
942 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700943 ShouldCreateOrBufferPacketForConnection(
944 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700945 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700946}
947
QUICHE team963d57e2019-03-21 10:58:47 -0700948// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
dschinazi8d1c9d42020-02-18 13:12:20 -0800949TEST_P(QuicDispatcherTestAllVersions, InvalidShortConnectionIdLengthReplaced) {
950 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team963d57e2019-03-21 10:58:47 -0700951 // When variable length connection IDs are not supported, the connection
952 // fails. See StrayPacketTruncatedConnectionId.
953 return;
954 }
955 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
956
957 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
dschinazi28c1bf32019-08-19 11:54:46 -0700958 QuicConnectionId fixed_connection_id =
959 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700960
961 // Disable validation of invalid short connection IDs.
dschinazi7b9278c2019-05-20 07:36:21 -0700962 dispatcher_->SetAllowShortInitialServerConnectionIds(true);
QUICHE team963d57e2019-03-21 10:58:47 -0700963 // Note that StrayPacketTruncatedConnectionId covers the case where the
964 // validation is still enabled.
965
966 EXPECT_CALL(*dispatcher_,
967 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800968 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -0800969 .WillOnce(Return(ByMove(CreateSession(
QUICHE team963d57e2019-03-21 10:58:47 -0700970 dispatcher_.get(), config_, fixed_connection_id, client_address,
971 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -0800972 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team963d57e2019-03-21 10:58:47 -0700973 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
974 ProcessUdpPacket(_, _, _))
975 .WillOnce(WithArg<2>(
976 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
977 ValidatePacket(bad_connection_id, packet);
978 })));
979 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -0700980 ShouldCreateOrBufferPacketForConnection(
981 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -0700982 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team963d57e2019-03-21 10:58:47 -0700983}
984
QUICHE teamc65d1d12019-03-19 20:58:04 -0700985// Makes sure TestConnectionId(1) creates a new connection and
986// TestConnectionIdNineBytesLong(2) gets replaced.
dschinazi8d1c9d42020-02-18 13:12:20 -0800987TEST_P(QuicDispatcherTestAllVersions, MixGoodAndBadConnectionIdLengthPackets) {
988 if (!version_.AllowsVariableLengthConnectionIds()) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700989 return;
990 }
QUICHE teamc65d1d12019-03-19 20:58:04 -0700991
QUICHE team8e2e4532019-03-14 14:37:56 -0700992 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700993 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
dschinazi28c1bf32019-08-19 11:54:46 -0700994 QuicConnectionId fixed_connection_id =
995 QuicUtils::CreateReplacementConnectionId(bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -0700996
997 EXPECT_CALL(*dispatcher_,
998 CreateQuicSession(TestConnectionId(1), client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -0800999 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001000 .WillOnce(Return(ByMove(CreateSession(
QUICHE team8e2e4532019-03-14 14:37:56 -07001001 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1002 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001003 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE team8e2e4532019-03-14 14:37:56 -07001004 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1005 ProcessUdpPacket(_, _, _))
1006 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1007 ValidatePacket(TestConnectionId(1), packet);
1008 })));
1009 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001010 ShouldCreateOrBufferPacketForConnection(
1011 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001012 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE team8e2e4532019-03-14 14:37:56 -07001013
QUICHE teamc65d1d12019-03-19 20:58:04 -07001014 EXPECT_CALL(*dispatcher_,
1015 CreateQuicSession(fixed_connection_id, client_address,
dschinazi8d1c9d42020-02-18 13:12:20 -08001016 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001017 .WillOnce(Return(ByMove(CreateSession(
QUICHE teamc65d1d12019-03-19 20:58:04 -07001018 dispatcher_.get(), config_, fixed_connection_id, client_address,
1019 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001020 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teamc65d1d12019-03-19 20:58:04 -07001021 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1022 ProcessUdpPacket(_, _, _))
1023 .WillOnce(WithArg<2>(
1024 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
1025 ValidatePacket(bad_connection_id, packet);
1026 })));
1027 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001028 ShouldCreateOrBufferPacketForConnection(
1029 ReceivedPacketInfoConnectionIdEquals(bad_connection_id)));
dschinazi6b40b1d2020-04-22 06:15:46 -07001030 ProcessFirstFlight(client_address, bad_connection_id);
QUICHE team8e2e4532019-03-14 14:37:56 -07001031
1032 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1033 ProcessUdpPacket(_, _, _))
1034 .Times(1)
1035 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1036 ValidatePacket(TestConnectionId(1), packet);
1037 })));
1038 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1039}
1040
dschinazi8d1c9d42020-02-18 13:12:20 -08001041TEST_P(QuicDispatcherTestAllVersions, ProcessPacketWithZeroPort) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001042 CreateTimeWaitListManager();
1043
1044 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
1045
1046 // dispatcher_ should drop this packet.
1047 EXPECT_CALL(*dispatcher_,
dschinazi8d1c9d42020-02-18 13:12:20 -08001048 CreateQuicSession(TestConnectionId(1), client_address, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001049 .Times(0);
1050 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001051 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001052 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -07001053 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1054 "data");
QUICHE teama6ef0a62019-03-07 20:34:33 -05001055}
1056
dschinazi8d1c9d42020-02-18 13:12:20 -08001057TEST_P(QuicDispatcherTestAllVersions,
1058 ProcessPacketWithInvalidShortInitialConnectionId) {
1059 if (!version_.AllowsVariableLengthConnectionIds()) {
1060 return;
1061 }
dschinaziee07e472019-06-19 09:56:56 -07001062 CreateTimeWaitListManager();
1063
1064 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1065
1066 // dispatcher_ should drop this packet.
dschinazi8d1c9d42020-02-18 13:12:20 -08001067 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address, _, _))
dschinaziee07e472019-06-19 09:56:56 -07001068 .Times(0);
1069 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001070 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
dschinaziee07e472019-06-19 09:56:56 -07001071 .Times(0);
dschinazi6b40b1d2020-04-22 06:15:46 -07001072 ProcessFirstFlight(client_address, EmptyQuicConnectionId());
dschinaziee07e472019-06-19 09:56:56 -07001073}
1074
dschinazi8d1c9d42020-02-18 13:12:20 -08001075TEST_P(QuicDispatcherTestOneVersion, VersionsChangeInFlight) {
fayangb880b4c2019-06-14 12:26:35 -07001076 VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
dschinazi8d1c9d42020-02-18 13:12:20 -08001077 for (ParsedQuicVersion version : CurrentSupportedVersions()) {
1078 VerifyVersionSupported(version);
dschinazi5a50d932020-06-17 12:43:36 -07001079 QuicDisableVersion(version);
1080 VerifyVersionNotSupported(version);
1081 QuicEnableVersion(version);
1082 VerifyVersionSupported(version);
dschinazi8d1c9d42020-02-18 13:12:20 -08001083 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001084}
1085
dschinazi8d1c9d42020-02-18 13:12:20 -08001086TEST_P(QuicDispatcherTestOneVersion,
1087 RejectDeprecatedVersionsWithVersionNegotiation) {
dschinazi6ab45242020-06-23 00:20:37 -07001088 static_assert(quic::SupportedVersions().size() == 9u,
fayangb54ac5b2019-07-01 10:30:37 -07001089 "Please add deprecated versions to this test");
1090 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1091 CreateTimeWaitListManager();
1092
dschinazi8b1c45a2019-10-17 08:48:13 -07001093 {
1094 char packet47[kMinPacketSizeForVersionNegotiation] = {
1095 0xC0, 'Q', '0', '4', '7', /*connection ID length byte*/ 0x50};
1096 QuicReceivedPacket received_packet47(
1097 packet47, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1098 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1099 EXPECT_CALL(*time_wait_list_manager_,
1100 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1101 .Times(1);
1102 dispatcher_->ProcessPacket(server_address_, client_address,
1103 received_packet47);
1104 }
fayang36825da2019-08-21 14:01:27 -07001105
dschinazi8b1c45a2019-10-17 08:48:13 -07001106 {
1107 char packet45[kMinPacketSizeForVersionNegotiation] = {
1108 0xC0, 'Q', '0', '4', '5', /*connection ID length byte*/ 0x50};
1109 QuicReceivedPacket received_packet45(
1110 packet45, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1111 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1112 EXPECT_CALL(*time_wait_list_manager_,
1113 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1114 .Times(1);
1115 dispatcher_->ProcessPacket(server_address_, client_address,
1116 received_packet45);
1117 }
1118
1119 {
1120 char packet44[kMinPacketSizeForVersionNegotiation] = {
1121 0xFF, 'Q', '0', '4', '4', /*connection ID length byte*/ 0x50};
1122 QuicReceivedPacket received_packet44(
1123 packet44, kMinPacketSizeForVersionNegotiation, QuicTime::Zero());
1124 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1125 EXPECT_CALL(*time_wait_list_manager_,
1126 SendVersionNegotiationPacket(_, _, _, _, _, _, _, _))
1127 .Times(1);
1128 dispatcher_->ProcessPacket(server_address_, client_address,
1129 received_packet44);
1130 }
fayangb54ac5b2019-07-01 10:30:37 -07001131}
1132
dschinazi8d1c9d42020-02-18 13:12:20 -08001133TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeOld) {
dschinazi30ab6db2019-08-13 14:43:32 -07001134 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi30ab6db2019-08-13 14:43:32 -07001135 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1136 CreateTimeWaitListManager();
1137 char packet[1200];
1138 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1139 0x6c, 0x7a, 0x20, 0x21};
1140 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1141 packet, sizeof(packet), destination_connection_id_bytes,
1142 sizeof(destination_connection_id_bytes)));
1143 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1144 std::unique_ptr<QuicReceivedPacket> received_packet(
1145 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1146 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1147 QuicConnectionId server_connection_id(
1148 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1149 bool ietf_quic = true;
1150 bool use_length_prefix =
1151 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1152 EXPECT_CALL(
1153 *time_wait_list_manager_,
1154 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1155 ietf_quic, use_length_prefix, _, _, _, _))
1156 .Times(1);
1157 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1158
1159 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1160}
1161
dschinazi8d1c9d42020-02-18 13:12:20 -08001162TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbe) {
dschinazi30ab6db2019-08-13 14:43:32 -07001163 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi30ab6db2019-08-13 14:43:32 -07001164 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1165 CreateTimeWaitListManager();
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 QuicConnectionId client_connection_id = EmptyQuicConnectionId();
1176 QuicConnectionId server_connection_id(
1177 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1178 bool ietf_quic = true;
1179 bool use_length_prefix =
1180 GetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids);
1181 EXPECT_CALL(
1182 *time_wait_list_manager_,
1183 SendVersionNegotiationPacket(server_connection_id, client_connection_id,
1184 ietf_quic, use_length_prefix, _, _, _, _))
1185 .Times(1);
1186 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1187
1188 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1189}
1190
dschinazi0185ebb2019-08-14 11:09:35 -07001191// Testing packet writer that saves all packets instead of sending them.
1192// Useful for tests that need access to sent packets.
1193class SavingWriter : public QuicPacketWriterWrapper {
1194 public:
1195 bool IsWriteBlocked() const override { return false; }
1196
1197 WriteResult WritePacket(const char* buffer,
1198 size_t buf_len,
1199 const QuicIpAddress& /*self_client_address*/,
1200 const QuicSocketAddress& /*peer_client_address*/,
1201 PerPacketOptions* /*options*/) override {
1202 packets_.push_back(
1203 QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
1204 return WriteResult(WRITE_STATUS_OK, buf_len);
1205 }
1206
1207 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets() {
1208 return &packets_;
1209 }
1210
1211 private:
1212 std::vector<std::unique_ptr<QuicEncryptedPacket>> packets_;
1213};
1214
dschinazi8d1c9d42020-02-18 13:12:20 -08001215TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEndOld) {
dschinazi0185ebb2019-08-14 11:09:35 -07001216 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, false);
dschinazi0185ebb2019-08-14 11:09:35 -07001217
1218 SavingWriter* saving_writer = new SavingWriter();
1219 // dispatcher_ takes ownership of saving_writer.
1220 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1221
1222 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1223 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1224 &mock_alarm_factory_);
1225 // dispatcher_ takes ownership of time_wait_list_manager.
1226 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1227 time_wait_list_manager);
1228 char packet[1200] = {};
1229 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1230 0x6c, 0x7a, 0x20, 0x21};
1231 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1232 packet, sizeof(packet), destination_connection_id_bytes,
1233 sizeof(destination_connection_id_bytes)));
1234 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1235 std::unique_ptr<QuicReceivedPacket> received_packet(
1236 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1237 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1238
1239 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1240 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1241 ASSERT_EQ(1u, saving_writer->packets()->size());
1242
1243 char source_connection_id_bytes[255] = {};
1244 uint8_t source_connection_id_length = 0;
1245 std::string detailed_error = "foobar";
1246 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1247 (*(saving_writer->packets()))[0]->data(),
1248 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1249 &source_connection_id_length, &detailed_error));
1250 EXPECT_EQ("", detailed_error);
1251
1252 // The source connection ID of the probe response should match the
1253 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001254 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001255 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1256 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1257}
1258
dschinazi8d1c9d42020-02-18 13:12:20 -08001259TEST_P(QuicDispatcherTestOneVersion, VersionNegotiationProbeEndToEnd) {
dschinazi0185ebb2019-08-14 11:09:35 -07001260 SetQuicFlag(FLAGS_quic_prober_uses_length_prefixed_connection_ids, true);
dschinazi0185ebb2019-08-14 11:09:35 -07001261
1262 SavingWriter* saving_writer = new SavingWriter();
1263 // dispatcher_ takes ownership of saving_writer.
1264 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1265
1266 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1267 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1268 &mock_alarm_factory_);
1269 // dispatcher_ takes ownership of time_wait_list_manager.
1270 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1271 time_wait_list_manager);
1272 char packet[1200] = {};
1273 char destination_connection_id_bytes[] = {0x56, 0x4e, 0x20, 0x70,
1274 0x6c, 0x7a, 0x20, 0x21};
1275 EXPECT_TRUE(QuicFramer::WriteClientVersionNegotiationProbePacket(
1276 packet, sizeof(packet), destination_connection_id_bytes,
1277 sizeof(destination_connection_id_bytes)));
1278 QuicEncryptedPacket encrypted(packet, sizeof(packet), false);
1279 std::unique_ptr<QuicReceivedPacket> received_packet(
1280 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1281 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1282
1283 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1284 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1285 ASSERT_EQ(1u, saving_writer->packets()->size());
1286
1287 char source_connection_id_bytes[255] = {};
1288 uint8_t source_connection_id_length = 0;
1289 std::string detailed_error = "foobar";
1290 EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
1291 (*(saving_writer->packets()))[0]->data(),
1292 (*(saving_writer->packets()))[0]->length(), source_connection_id_bytes,
1293 &source_connection_id_length, &detailed_error));
1294 EXPECT_EQ("", detailed_error);
1295
1296 // The source connection ID of the probe response should match the
1297 // destination connection ID of the probe request.
dmcardle8f7df532020-01-07 13:28:57 -08001298 quiche::test::CompareCharArraysWithHexError(
dschinazi0185ebb2019-08-14 11:09:35 -07001299 "parsed probe", source_connection_id_bytes, source_connection_id_length,
1300 destination_connection_id_bytes, sizeof(destination_connection_id_bytes));
1301}
1302
dschinazi8d1c9d42020-02-18 13:12:20 -08001303TEST_P(QuicDispatcherTestOneVersion, AndroidConformanceTest) {
dschinazi5b236be2019-08-19 14:55:22 -07001304 // WARNING: do not remove or modify this test without making sure that we
1305 // still have adequate coverage for the Android conformance test.
dschinazi5b236be2019-08-19 14:55:22 -07001306 SavingWriter* saving_writer = new SavingWriter();
1307 // dispatcher_ takes ownership of saving_writer.
1308 QuicDispatcherPeer::UseWriter(dispatcher_.get(), saving_writer);
1309
1310 QuicTimeWaitListManager* time_wait_list_manager = new QuicTimeWaitListManager(
1311 saving_writer, dispatcher_.get(), mock_helper_.GetClock(),
1312 &mock_alarm_factory_);
1313 // dispatcher_ takes ownership of time_wait_list_manager.
1314 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
1315 time_wait_list_manager);
1316 // clang-format off
1317 static const unsigned char packet[1200] = {
1318 // Android UDP network conformance test packet as it was after this change:
1319 // https://android-review.googlesource.com/c/platform/cts/+/1104285
1320 0x0d, // public flags: version, 8-byte connection ID, 1-byte packet number
1321 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, // 8-byte connection ID
1322 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number
1323 0x01, // 1-byte packet number
1324 0x00, // private flags
1325 0x07, // PING frame
1326 };
1327 // clang-format on
1328
1329 QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
1330 sizeof(packet), false);
1331 std::unique_ptr<QuicReceivedPacket> received_packet(
1332 ConstructReceivedPacket(encrypted, mock_helper_.GetClock()->Now()));
1333 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1334
1335 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1336 dispatcher_->ProcessPacket(server_address_, client_address, *received_packet);
1337 ASSERT_EQ(1u, saving_writer->packets()->size());
1338
1339 // The Android UDP network conformance test directly checks that bytes 1-9
1340 // of the response match the connection ID that was sent.
1341 static const char connection_id_bytes[] = {0x71, 0x72, 0x73, 0x74,
1342 0x75, 0x76, 0x77, 0x78};
1343 ASSERT_GE((*(saving_writer->packets()))[0]->length(),
1344 1u + sizeof(connection_id_bytes));
dmcardle8f7df532020-01-07 13:28:57 -08001345 quiche::test::CompareCharArraysWithHexError(
dschinazi5b236be2019-08-19 14:55:22 -07001346 "response connection ID", &(*(saving_writer->packets()))[0]->data()[1],
1347 sizeof(connection_id_bytes), connection_id_bytes,
1348 sizeof(connection_id_bytes));
1349}
1350
dschinazi8d1c9d42020-02-18 13:12:20 -08001351TEST_P(QuicDispatcherTestAllVersions, DoNotProcessSmallPacket) {
dschinazi942a9f82020-06-19 09:23:20 -07001352 if (!version_.HasIetfInvariantHeader() &&
1353 !GetQuicReloadableFlag(quic_dont_pad_chlo)) {
1354 // When quic_dont_pad_chlo is false, we only drop small packets when using
1355 // IETF_QUIC_LONG_HEADER_PACKET. When quic_dont_pad_chlo is true, we drop
1356 // small packets for all versions.
1357 // TODO(dschinazi) remove this early return when we deprecate the flag.
dschinazi8d1c9d42020-02-18 13:12:20 -08001358 return;
1359 }
fayange3f2f7b2019-09-19 17:01:57 -07001360 CreateTimeWaitListManager();
1361 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1362
1363 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
dschinazicdc73612020-03-02 10:34:01 -08001364 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001365 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
rch9d76c2d2019-12-20 12:19:48 -08001366 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001367 ProcessPacket(client_address, TestConnectionId(1), /*has_version_flag=*/true,
1368 version_, SerializeCHLO(), /*full_padding=*/false,
fayange3f2f7b2019-09-19 17:01:57 -07001369 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
1370}
1371
dschinazi8d1c9d42020-02-18 13:12:20 -08001372TEST_P(QuicDispatcherTestAllVersions, ProcessSmallCoalescedPacket) {
fayange3f2f7b2019-09-19 17:01:57 -07001373 CreateTimeWaitListManager();
1374 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1375
1376 EXPECT_CALL(*time_wait_list_manager_, SendPacket(_, _, _)).Times(0);
1377
1378 // clang-format off
1379 char coalesced_packet[1200] = {
1380 // first coalesced packet
1381 // public flags (long header with packet type INITIAL and
1382 // 4-byte packet number)
1383 0xC3,
1384 // version
1385 'Q', '0', '9', '9',
1386 // destination connection ID length
1387 0x08,
1388 // destination connection ID
1389 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1390 // source connection ID length
1391 0x00,
1392 // long header packet length
1393 0x05,
1394 // packet number
1395 0x12, 0x34, 0x56, 0x78,
1396 // Padding
1397 0x00,
1398 // second coalesced packet
1399 // public flags (long header with packet type ZERO_RTT_PROTECTED and
1400 // 4-byte packet number)
1401 0xC3,
1402 // version
1403 'Q', '0', '9', '9',
1404 // destination connection ID length
1405 0x08,
1406 // destination connection ID
1407 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
1408 // source connection ID length
1409 0x00,
1410 // long header packet length
1411 0x1E,
1412 // packet number
1413 0x12, 0x34, 0x56, 0x79,
1414 };
1415 // clang-format on
1416 QuicReceivedPacket packet(coalesced_packet, 1200, QuicTime::Zero());
1417 dispatcher_->ProcessPacket(server_address_, client_address, packet);
1418}
1419
danzh72e0dab2020-03-05 20:00:50 -08001420TEST_P(QuicDispatcherTestAllVersions, StopAcceptingNewConnections) {
1421 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1422
1423 EXPECT_CALL(*dispatcher_,
1424 CreateQuicSession(TestConnectionId(1), client_address,
1425 Eq(ExpectedAlpn()), _))
1426 .WillOnce(Return(ByMove(CreateSession(
1427 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1428 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1429 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1430 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1431 ProcessUdpPacket(_, _, _))
1432 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1433 ValidatePacket(TestConnectionId(1), packet);
1434 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001435 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001436
1437 dispatcher_->StopAcceptingNewConnections();
1438 EXPECT_FALSE(dispatcher_->accept_new_connections());
1439
1440 // No more new connections afterwards.
1441 EXPECT_CALL(*dispatcher_,
1442 CreateQuicSession(TestConnectionId(2), client_address,
1443 Eq(ExpectedAlpn()), _))
1444 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001445 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001446
1447 // Existing connections should be able to continue.
1448 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1449 ProcessUdpPacket(_, _, _))
1450 .Times(1u)
1451 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1452 ValidatePacket(TestConnectionId(1), packet);
1453 })));
1454 ProcessPacket(client_address, TestConnectionId(1), false, "data");
1455}
1456
1457TEST_P(QuicDispatcherTestAllVersions, StartAcceptingNewConnections) {
1458 dispatcher_->StopAcceptingNewConnections();
1459 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1460
1461 // No more new connections afterwards.
1462 EXPECT_CALL(*dispatcher_,
1463 CreateQuicSession(TestConnectionId(2), client_address,
1464 Eq(ExpectedAlpn()), _))
1465 .Times(0u);
dschinazi6b40b1d2020-04-22 06:15:46 -07001466 ProcessFirstFlight(client_address, TestConnectionId(2));
danzh72e0dab2020-03-05 20:00:50 -08001467
1468 dispatcher_->StartAcceptingNewConnections();
1469 EXPECT_TRUE(dispatcher_->accept_new_connections());
1470
1471 EXPECT_CALL(*dispatcher_,
1472 CreateQuicSession(TestConnectionId(1), client_address,
1473 Eq(ExpectedAlpn()), _))
1474 .WillOnce(Return(ByMove(CreateSession(
1475 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1476 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1477 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1478 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1479 ProcessUdpPacket(_, _, _))
1480 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1481 ValidatePacket(TestConnectionId(1), packet);
1482 })));
dschinazi6b40b1d2020-04-22 06:15:46 -07001483 ProcessFirstFlight(client_address, TestConnectionId(1));
danzh72e0dab2020-03-05 20:00:50 -08001484}
1485
dschinazi71116fd2020-04-22 16:07:04 -07001486TEST_P(QuicDispatcherTestOneVersion, SelectAlpn) {
1487 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {}), "");
1488 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {""}), "");
1489 EXPECT_EQ(QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"hq"}), "hq");
1490 // Q033 is no longer supported but Q050 is.
1491 QuicEnableVersion(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50));
1492 EXPECT_EQ(
1493 QuicDispatcherPeer::SelectAlpn(dispatcher_.get(), {"h3-Q033", "h3-Q050"}),
1494 "h3-Q050");
1495}
1496
QUICHE teama6ef0a62019-03-07 20:34:33 -05001497// Verify the stopgap test: Packets with truncated connection IDs should be
1498// dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001499class QuicDispatcherTestStrayPacketConnectionId
1500 : public QuicDispatcherTestBase {};
1501
1502INSTANTIATE_TEST_SUITE_P(QuicDispatcherTestsStrayPacketConnectionId,
1503 QuicDispatcherTestStrayPacketConnectionId,
1504 ::testing::ValuesIn(CurrentSupportedVersions()),
1505 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001506
1507// Packets with truncated connection IDs should be dropped.
dschinazi8d1c9d42020-02-18 13:12:20 -08001508TEST_P(QuicDispatcherTestStrayPacketConnectionId,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001509 StrayPacketTruncatedConnectionId) {
1510 CreateTimeWaitListManager();
1511
1512 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1513 QuicConnectionId connection_id = TestConnectionId(1);
dschinazi8d1c9d42020-02-18 13:12:20 -08001514 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
1515 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
haoyuewangfe3d30a2020-06-29 13:09:18 -07001516 EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05001517 .Times(0);
dschinazi8d1c9d42020-02-18 13:12:20 -08001518
QUICHE teama6ef0a62019-03-07 20:34:33 -05001519 ProcessPacket(client_address, connection_id, true, "data",
1520 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1521}
1522
1523class BlockingWriter : public QuicPacketWriterWrapper {
1524 public:
1525 BlockingWriter() : write_blocked_(false) {}
1526
1527 bool IsWriteBlocked() const override { return write_blocked_; }
1528 void SetWritable() override { write_blocked_ = false; }
1529
dschinazi17d42422019-06-18 16:35:07 -07001530 WriteResult WritePacket(const char* /*buffer*/,
1531 size_t /*buf_len*/,
1532 const QuicIpAddress& /*self_client_address*/,
1533 const QuicSocketAddress& /*peer_client_address*/,
1534 PerPacketOptions* /*options*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001535 // It would be quite possible to actually implement this method here with
1536 // the fake blocked status, but it would be significantly more work in
1537 // Chromium, and since it's not called anyway, don't bother.
1538 QUIC_LOG(DFATAL) << "Not supported";
1539 return WriteResult();
1540 }
1541
1542 bool write_blocked_;
1543};
1544
dschinazi8d1c9d42020-02-18 13:12:20 -08001545class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001546 public:
1547 void SetUp() override {
dschinazi8d1c9d42020-02-18 13:12:20 -08001548 QuicDispatcherTestBase::SetUp();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001549 writer_ = new BlockingWriter;
1550 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1551
1552 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1553
1554 EXPECT_CALL(*dispatcher_,
bncf6e95ea2020-02-27 04:59:49 -08001555 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001556 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001557 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1558 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001559 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001560 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1561 ProcessUdpPacket(_, _, _))
1562 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1563 ValidatePacket(TestConnectionId(1), packet);
1564 })));
fayang1ed1f762019-06-24 11:40:04 -07001565 EXPECT_CALL(*dispatcher_,
1566 ShouldCreateOrBufferPacketForConnection(
1567 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(1))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001568 ProcessFirstFlight(client_address, TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001569
1570 EXPECT_CALL(*dispatcher_,
bncf6e95ea2020-02-27 04:59:49 -08001571 CreateQuicSession(_, client_address, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001572 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001573 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1574 &helper_, &alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001575 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001576 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1577 ProcessUdpPacket(_, _, _))
1578 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1579 ValidatePacket(TestConnectionId(2), packet);
1580 })));
fayang1ed1f762019-06-24 11:40:04 -07001581 EXPECT_CALL(*dispatcher_,
1582 ShouldCreateOrBufferPacketForConnection(
1583 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(2))));
dschinazi6b40b1d2020-04-22 06:15:46 -07001584 ProcessFirstFlight(client_address, TestConnectionId(2));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001585
1586 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1587 }
1588
1589 void TearDown() override {
1590 if (connection1() != nullptr) {
1591 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1592 }
1593
1594 if (connection2() != nullptr) {
1595 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1596 }
1597 dispatcher_->Shutdown();
1598 }
1599
1600 // Set the dispatcher's writer to be blocked. By default, all connections use
1601 // the same writer as the dispatcher in this test.
1602 void SetBlocked() {
1603 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1604 writer_->write_blocked_ = true;
1605 }
1606
1607 // Simulate what happens when connection1 gets blocked when writing.
1608 void BlockConnection1() {
1609 Connection1Writer()->write_blocked_ = true;
1610 dispatcher_->OnWriteBlocked(connection1());
1611 }
1612
1613 BlockingWriter* Connection1Writer() {
1614 return static_cast<BlockingWriter*>(connection1()->writer());
1615 }
1616
1617 // Simulate what happens when connection2 gets blocked when writing.
1618 void BlockConnection2() {
1619 Connection2Writer()->write_blocked_ = true;
1620 dispatcher_->OnWriteBlocked(connection2());
1621 }
1622
1623 BlockingWriter* Connection2Writer() {
1624 return static_cast<BlockingWriter*>(connection2()->writer());
1625 }
1626
1627 protected:
1628 MockQuicConnectionHelper helper_;
1629 MockAlarmFactory alarm_factory_;
1630 BlockingWriter* writer_;
1631 QuicDispatcher::WriteBlockedList* blocked_list_;
1632};
1633
dschinazi8d1c9d42020-02-18 13:12:20 -08001634INSTANTIATE_TEST_SUITE_P(QuicDispatcherWriteBlockedListTests,
1635 QuicDispatcherWriteBlockedListTest,
1636 ::testing::Values(CurrentSupportedVersions().front()),
1637 ::testing::PrintToStringParamName());
1638
1639TEST_P(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001640 // No OnCanWrite calls because no connections are blocked.
1641 dispatcher_->OnCanWrite();
1642
1643 // Register connection 1 for events, and make sure it's notified.
1644 SetBlocked();
1645 dispatcher_->OnWriteBlocked(connection1());
1646 EXPECT_CALL(*connection1(), OnCanWrite());
1647 dispatcher_->OnCanWrite();
1648
1649 // It should get only one notification.
1650 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1651 dispatcher_->OnCanWrite();
1652 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1653}
1654
dschinazi8d1c9d42020-02-18 13:12:20 -08001655TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001656 // Make sure we handle events in order.
1657 InSequence s;
1658 SetBlocked();
1659 dispatcher_->OnWriteBlocked(connection1());
1660 dispatcher_->OnWriteBlocked(connection2());
1661 EXPECT_CALL(*connection1(), OnCanWrite());
1662 EXPECT_CALL(*connection2(), OnCanWrite());
1663 dispatcher_->OnCanWrite();
1664
1665 // Check the other ordering.
1666 SetBlocked();
1667 dispatcher_->OnWriteBlocked(connection2());
1668 dispatcher_->OnWriteBlocked(connection1());
1669 EXPECT_CALL(*connection2(), OnCanWrite());
1670 EXPECT_CALL(*connection1(), OnCanWrite());
1671 dispatcher_->OnCanWrite();
1672}
1673
dschinazi8d1c9d42020-02-18 13:12:20 -08001674TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001675 // Add and remove one connction.
1676 SetBlocked();
1677 dispatcher_->OnWriteBlocked(connection1());
1678 blocked_list_->erase(connection1());
1679 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1680 dispatcher_->OnCanWrite();
1681
1682 // Add and remove one connction and make sure it doesn't affect others.
1683 SetBlocked();
1684 dispatcher_->OnWriteBlocked(connection1());
1685 dispatcher_->OnWriteBlocked(connection2());
1686 blocked_list_->erase(connection1());
1687 EXPECT_CALL(*connection2(), OnCanWrite());
1688 dispatcher_->OnCanWrite();
1689
1690 // Add it, remove it, and add it back and make sure things are OK.
1691 SetBlocked();
1692 dispatcher_->OnWriteBlocked(connection1());
1693 blocked_list_->erase(connection1());
1694 dispatcher_->OnWriteBlocked(connection1());
1695 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1696 dispatcher_->OnCanWrite();
1697}
1698
dschinazi8d1c9d42020-02-18 13:12:20 -08001699TEST_P(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001700 // Make sure a double add does not necessitate a double remove.
1701 SetBlocked();
1702 dispatcher_->OnWriteBlocked(connection1());
1703 dispatcher_->OnWriteBlocked(connection1());
1704 blocked_list_->erase(connection1());
1705 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1706 dispatcher_->OnCanWrite();
1707
1708 // Make sure a double add does not result in two OnCanWrite calls.
1709 SetBlocked();
1710 dispatcher_->OnWriteBlocked(connection1());
1711 dispatcher_->OnWriteBlocked(connection1());
1712 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1713 dispatcher_->OnCanWrite();
1714}
1715
dschinazi8d1c9d42020-02-18 13:12:20 -08001716TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001717 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1718 // into the write blocked list.
1719 InSequence s;
1720 SetBlocked();
1721 dispatcher_->OnWriteBlocked(connection1());
1722 dispatcher_->OnWriteBlocked(connection2());
1723 EXPECT_CALL(*connection1(), OnCanWrite())
1724 .WillOnce(
1725 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1726 EXPECT_CALL(*connection2(), OnCanWrite());
1727 dispatcher_->OnCanWrite();
1728
1729 // connection1 should be still in the write blocked list.
1730 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1731
1732 // Now call OnCanWrite again, connection1 should get its second chance.
1733 EXPECT_CALL(*connection1(), OnCanWrite());
1734 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1735 dispatcher_->OnCanWrite();
1736 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1737}
1738
dschinazi8d1c9d42020-02-18 13:12:20 -08001739TEST_P(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001740 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1741 // into the write blocked list.
1742 InSequence s;
1743 SetBlocked();
1744 dispatcher_->OnWriteBlocked(connection1());
1745 dispatcher_->OnWriteBlocked(connection2());
1746 EXPECT_CALL(*connection1(), OnCanWrite());
1747 EXPECT_CALL(*connection2(), OnCanWrite())
1748 .WillOnce(
1749 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1750 dispatcher_->OnCanWrite();
1751
1752 // connection2 should be still in the write blocked list.
1753 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1754
1755 // Now call OnCanWrite again, connection2 should get its second chance.
1756 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1757 EXPECT_CALL(*connection2(), OnCanWrite());
1758 dispatcher_->OnCanWrite();
1759 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1760}
1761
dschinazi8d1c9d42020-02-18 13:12:20 -08001762TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001763 OnCanWriteHandleBlockBothConnections) {
1764 // Both connections get blocked in OnCanWrite, and added back into the write
1765 // blocked list.
1766 InSequence s;
1767 SetBlocked();
1768 dispatcher_->OnWriteBlocked(connection1());
1769 dispatcher_->OnWriteBlocked(connection2());
1770 EXPECT_CALL(*connection1(), OnCanWrite())
1771 .WillOnce(
1772 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1773 EXPECT_CALL(*connection2(), OnCanWrite())
1774 .WillOnce(
1775 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1776 dispatcher_->OnCanWrite();
1777
1778 // Both connections should be still in the write blocked list.
1779 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1780
1781 // Now call OnCanWrite again, both connections should get its second chance.
1782 EXPECT_CALL(*connection1(), OnCanWrite());
1783 EXPECT_CALL(*connection2(), OnCanWrite());
1784 dispatcher_->OnCanWrite();
1785 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1786}
1787
dschinazi8d1c9d42020-02-18 13:12:20 -08001788TEST_P(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001789 // By default, all connections share the same packet writer with the
1790 // dispatcher.
1791 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1792 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1793
1794 // Test the case where connection1 shares the same packet writer as the
1795 // dispatcher, whereas connection2 owns it's packet writer.
1796 // Change connection2's writer.
1797 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1798 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1799
1800 BlockConnection2();
1801 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1802
1803 EXPECT_CALL(*connection2(), OnCanWrite());
1804 dispatcher_->OnCanWrite();
1805 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1806}
1807
dschinazi8d1c9d42020-02-18 13:12:20 -08001808TEST_P(QuicDispatcherWriteBlockedListTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001809 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001810 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1811 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1812 ConnectionCloseSource::FROM_SELF);
1813
1814 SetBlocked();
1815
1816 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1817 SetBlocked();
1818 dispatcher_->OnWriteBlocked(connection1());
1819 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1820
1821 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1822 "QuicConnection was in WriteBlockedList before destruction");
1823 MarkSession1Deleted();
1824}
1825
dschinazi8d1c9d42020-02-18 13:12:20 -08001826class BufferedPacketStoreTest : public QuicDispatcherTestBase {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001827 public:
1828 BufferedPacketStoreTest()
dschinazi8d1c9d42020-02-18 13:12:20 -08001829 : QuicDispatcherTestBase(),
dschinazi42fc2da2020-04-24 16:19:17 -07001830 client_addr_(QuicIpAddress::Loopback4(), 1234) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -05001831
dschinazi42fc2da2020-04-24 16:19:17 -07001832 void ProcessFirstFlight(const ParsedQuicVersion& version,
1833 const QuicSocketAddress& peer_address,
1834 const QuicConnectionId& server_connection_id) {
1835 QuicDispatcherTestBase::ProcessFirstFlight(version, peer_address,
1836 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001837 }
1838
dschinazi42fc2da2020-04-24 16:19:17 -07001839 void ProcessFirstFlight(const QuicSocketAddress& peer_address,
1840 const QuicConnectionId& server_connection_id) {
1841 ProcessFirstFlight(version_, peer_address, server_connection_id);
1842 }
1843
1844 void ProcessFirstFlight(const QuicConnectionId& server_connection_id) {
1845 ProcessFirstFlight(client_addr_, server_connection_id);
1846 }
1847
1848 void ProcessFirstFlight(const ParsedQuicVersion& version,
1849 const QuicConnectionId& server_connection_id) {
1850 ProcessFirstFlight(version, client_addr_, server_connection_id);
1851 }
1852
1853 void ProcessUndecryptableEarlyPacket(
1854 const ParsedQuicVersion& version,
1855 const QuicSocketAddress& peer_address,
1856 const QuicConnectionId& server_connection_id) {
1857 QuicDispatcherTestBase::ProcessUndecryptableEarlyPacket(
1858 version, peer_address, server_connection_id);
1859 }
1860
1861 void ProcessUndecryptableEarlyPacket(
1862 const QuicSocketAddress& peer_address,
1863 const QuicConnectionId& server_connection_id) {
1864 ProcessUndecryptableEarlyPacket(version_, peer_address,
1865 server_connection_id);
1866 }
1867
1868 void ProcessUndecryptableEarlyPacket(
1869 const QuicConnectionId& server_connection_id) {
1870 ProcessUndecryptableEarlyPacket(version_, client_addr_,
1871 server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001872 }
1873
1874 protected:
QUICHE teama6ef0a62019-03-07 20:34:33 -05001875 QuicSocketAddress client_addr_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001876};
1877
dschinazi8d1c9d42020-02-18 13:12:20 -08001878INSTANTIATE_TEST_SUITE_P(BufferedPacketStoreTests,
1879 BufferedPacketStoreTest,
dschinazi42fc2da2020-04-24 16:19:17 -07001880 ::testing::ValuesIn(CurrentSupportedVersions()),
dschinazi8d1c9d42020-02-18 13:12:20 -08001881 ::testing::PrintToStringParamName());
1882
dschinazi42fc2da2020-04-24 16:19:17 -07001883TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketBeforeChlo) {
1884 InSequence s;
1885 QuicConnectionId conn_id = TestConnectionId(1);
1886 // Non-CHLO should be buffered upon arrival, and should trigger
1887 // ShouldCreateOrBufferPacketForConnection().
1888 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1889 ReceivedPacketInfoConnectionIdEquals(conn_id)));
1890 // Process non-CHLO packet.
1891 ProcessUndecryptableEarlyPacket(conn_id);
1892 EXPECT_EQ(0u, dispatcher_->session_map().size())
1893 << "No session should be created before CHLO arrives.";
1894
1895 // When CHLO arrives, a new session should be created, and all packets
1896 // buffered should be delivered to the session.
1897 EXPECT_CALL(*dispatcher_,
1898 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
1899 .WillOnce(Return(ByMove(CreateSession(
1900 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
1901 &mock_alarm_factory_, &crypto_config_,
1902 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
1903 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1904 ProcessUdpPacket(_, _, _))
1905 .Times(2) // non-CHLO + CHLO.
1906 .WillRepeatedly(
1907 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1908 if (version_.UsesQuicCrypto()) {
1909 ValidatePacket(conn_id, packet);
1910 }
1911 })));
1912 ProcessFirstFlight(conn_id);
1913}
1914
dschinazi8d1c9d42020-02-18 13:12:20 -08001915TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001916 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001917 QuicConnectionId conn_id = TestConnectionId(1);
1918 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1919 // should trigger ShouldCreateOrBufferPacketForConnection().
fayang1ed1f762019-06-24 11:40:04 -07001920 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1921 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001922 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
dschinazi42fc2da2020-04-24 16:19:17 -07001923 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001924 }
1925 EXPECT_EQ(0u, dispatcher_->session_map().size())
1926 << "No session should be created before CHLO arrives.";
1927
1928 // Pop out the last packet as it is also be dropped by the store.
1929 data_connection_map_[conn_id].pop_back();
1930 // When CHLO arrives, a new session should be created, and all packets
1931 // buffered should be delivered to the session.
dschinazi42fc2da2020-04-24 16:19:17 -07001932 EXPECT_CALL(*dispatcher_,
1933 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001934 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07001935 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001936 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001937 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001938
1939 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1940 // should be delivered in arrival order.
1941 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1942 ProcessUdpPacket(_, _, _))
1943 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1944 .WillRepeatedly(
1945 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001946 if (version_.UsesQuicCrypto()) {
1947 ValidatePacket(conn_id, packet);
1948 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001949 })));
dschinazi42fc2da2020-04-24 16:19:17 -07001950 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001951}
1952
dschinazi8d1c9d42020-02-18 13:12:20 -08001953TEST_P(BufferedPacketStoreTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001954 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1955 InSequence s;
1956 // A bunch of non-CHLO should be buffered upon arrival.
1957 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1958 for (size_t i = 1; i <= kNumConnections; ++i) {
1959 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1960 QuicConnectionId conn_id = TestConnectionId(i);
1961 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001962 ShouldCreateOrBufferPacketForConnection(
1963 ReceivedPacketInfoConnectionIdEquals(conn_id)));
dschinazi42fc2da2020-04-24 16:19:17 -07001964 ProcessUndecryptableEarlyPacket(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001965 }
1966
1967 // Pop out the packet on last connection as it shouldn't be enqueued in store
1968 // as well.
1969 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1970
1971 // Reset session creation counter to ensure processing CHLO can always
1972 // create session.
1973 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
1974 kNumConnections);
1975 // Process CHLOs to create session for these connections.
1976 for (size_t i = 1; i <= kNumConnections; ++i) {
1977 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1978 QuicConnectionId conn_id = TestConnectionId(i);
1979 if (i == kNumConnections) {
1980 EXPECT_CALL(*dispatcher_,
fayang1ed1f762019-06-24 11:40:04 -07001981 ShouldCreateOrBufferPacketForConnection(
1982 ReceivedPacketInfoConnectionIdEquals(conn_id)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001983 }
1984 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address,
dschinazi42fc2da2020-04-24 16:19:17 -07001985 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08001986 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001987 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1988 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08001989 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001990 // First |kNumConnections| - 1 connections should have buffered
1991 // a packet in store. The rest should have been dropped.
1992 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
1993 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1994 ProcessUdpPacket(_, client_address, _))
1995 .Times(num_packet_to_process)
1996 .WillRepeatedly(WithArg<2>(
1997 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07001998 if (version_.UsesQuicCrypto()) {
1999 ValidatePacket(conn_id, packet);
2000 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002001 })));
2002
dschinazi42fc2da2020-04-24 16:19:17 -07002003 ProcessFirstFlight(client_address, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002004 }
2005}
2006
2007// Tests that store delivers empty packet list if CHLO arrives firstly.
dschinazi8d1c9d42020-02-18 13:12:20 -08002008TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002009 QuicConnectionId conn_id = TestConnectionId(1);
fayang1ed1f762019-06-24 11:40:04 -07002010 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
2011 ReceivedPacketInfoConnectionIdEquals(conn_id)));
dschinazi42fc2da2020-04-24 16:19:17 -07002012 EXPECT_CALL(*dispatcher_,
2013 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002014 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07002015 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002016 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002017 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002018 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
dschinazi42fc2da2020-04-24 16:19:17 -07002019 ProcessUdpPacket(_, client_addr_, _));
2020 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002021}
2022
2023// Tests that a retransmitted CHLO arrives after a connection for the
2024// CHLO has been created.
dschinazi8d1c9d42020-02-18 13:12:20 -08002025TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002026 InSequence s;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002027 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07002028 ProcessUndecryptableEarlyPacket(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002029
2030 // When CHLO arrives, a new session should be created, and all packets
2031 // buffered should be delivered to the session.
dschinazi42fc2da2020-04-24 16:19:17 -07002032 EXPECT_CALL(*dispatcher_,
2033 CreateQuicSession(conn_id, client_addr_, Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05002034 .Times(1) // Only triggered by 1st CHLO.
wub89490e02019-12-12 12:45:58 -08002035 .WillOnce(Return(ByMove(CreateSession(
dschinazi42fc2da2020-04-24 16:19:17 -07002036 dispatcher_.get(), config_, conn_id, client_addr_, &mock_helper_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002037 &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002038 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002039 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2040 ProcessUdpPacket(_, _, _))
2041 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
2042 .WillRepeatedly(
2043 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002044 if (version_.UsesQuicCrypto()) {
2045 ValidatePacket(conn_id, packet);
2046 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002047 })));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002048
dschinazi42fc2da2020-04-24 16:19:17 -07002049 std::vector<std::unique_ptr<QuicReceivedPacket>> packets =
2050 GetFirstFlightOfPackets(version_, conn_id);
2051 ASSERT_EQ(packets.size(), 1u);
2052 // Receive the CHLO once.
2053 ProcessReceivedPacket(packets[0]->Clone(), client_addr_, version_, conn_id);
2054 // Receive the CHLO a second time to simulate retransmission.
2055 ProcessReceivedPacket(std::move(packets[0]), client_addr_, version_, conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002056}
2057
2058// Tests that expiration of a connection add connection id to time wait list.
dschinazi8d1c9d42020-02-18 13:12:20 -08002059TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002060 InSequence s;
2061 CreateTimeWaitListManager();
2062 QuicBufferedPacketStore* store =
2063 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2064 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
2065
QUICHE teama6ef0a62019-03-07 20:34:33 -05002066 QuicConnectionId conn_id = TestConnectionId(1);
dschinazi42fc2da2020-04-24 16:19:17 -07002067 ProcessPacket(client_addr_, conn_id, true,
dmcardlecf0bfcf2019-12-13 08:08:21 -08002068 quiche::QuicheStrCat("data packet ", 2), CONNECTION_ID_PRESENT,
2069 PACKET_4BYTE_PACKET_NUMBER,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002070 /*packet_number=*/2);
2071
2072 mock_helper_.AdvanceTime(
2073 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
2074 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
2075 // Cancel alarm as if it had been fired.
2076 alarm->Cancel();
2077 store->OnExpirationTimeout();
2078 // New arrived CHLO will be dropped because this connection is in time wait
2079 // list.
2080 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
2081 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
dschinazi42fc2da2020-04-24 16:19:17 -07002082 ProcessFirstFlight(conn_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002083}
2084
dschinazi8d1c9d42020-02-18 13:12:20 -08002085TEST_P(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002086 // Process more than (|kMaxNumSessionsToCreate| +
2087 // |kDefaultMaxConnectionsInStore|) CHLOs,
2088 // the first |kMaxNumSessionsToCreate| should create connections immediately,
2089 // the next |kDefaultMaxConnectionsInStore| should be buffered,
2090 // the rest should be dropped.
2091 QuicBufferedPacketStore* store =
2092 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2093 const size_t kNumCHLOs =
2094 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
2095 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
fayang1ed1f762019-06-24 11:40:04 -07002096 EXPECT_CALL(
2097 *dispatcher_,
2098 ShouldCreateOrBufferPacketForConnection(
2099 ReceivedPacketInfoConnectionIdEquals(TestConnectionId(conn_id))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002100 if (conn_id <= kMaxNumSessionsToCreate) {
2101 EXPECT_CALL(*dispatcher_,
2102 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002103 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002104 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002105 dispatcher_.get(), config_, TestConnectionId(conn_id),
2106 client_addr_, &mock_helper_, &mock_alarm_factory_,
2107 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002108 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002109 EXPECT_CALL(
2110 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2111 ProcessUdpPacket(_, _, _))
2112 .WillOnce(WithArg<2>(
2113 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002114 if (version_.UsesQuicCrypto()) {
2115 ValidatePacket(TestConnectionId(conn_id), packet);
2116 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002117 })));
2118 }
dschinazi42fc2da2020-04-24 16:19:17 -07002119 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002120 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
2121 conn_id > kMaxNumSessionsToCreate) {
2122 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
2123 } else {
2124 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
2125 // connections immediately, and the last CHLO should be dropped as the
2126 // store is full.
2127 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
2128 }
2129 }
2130
2131 // Graduately consume buffered CHLOs. The buffered connections should be
2132 // created but the dropped one shouldn't.
2133 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2134 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
2135 ++conn_id) {
2136 EXPECT_CALL(*dispatcher_,
2137 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002138 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002139 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002140 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2141 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002142 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002143 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2144 ProcessUdpPacket(_, _, _))
2145 .WillOnce(WithArg<2>(
2146 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002147 if (version_.UsesQuicCrypto()) {
2148 ValidatePacket(TestConnectionId(conn_id), packet);
2149 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002150 })));
2151 }
2152 EXPECT_CALL(*dispatcher_,
2153 CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002154 Eq(ExpectedAlpn()), _))
QUICHE teama6ef0a62019-03-07 20:34:33 -05002155 .Times(0);
2156
2157 while (store->HasChlosBuffered()) {
2158 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2159 }
2160
2161 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
2162 kDefaultMaxConnectionsInStore),
2163 session1_->connection_id());
2164}
2165
2166// Duplicated CHLO shouldn't be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002167TEST_P(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002168 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
2169 ++conn_id) {
2170 // Last CHLO will be buffered. Others will create connection right away.
2171 if (conn_id <= kMaxNumSessionsToCreate) {
2172 EXPECT_CALL(*dispatcher_,
2173 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002174 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002175 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002176 dispatcher_.get(), config_, TestConnectionId(conn_id),
2177 client_addr_, &mock_helper_, &mock_alarm_factory_,
2178 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002179 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002180 EXPECT_CALL(
2181 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2182 ProcessUdpPacket(_, _, _))
2183 .WillOnce(WithArg<2>(
2184 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002185 if (version_.UsesQuicCrypto()) {
2186 ValidatePacket(TestConnectionId(conn_id), packet);
2187 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002188 })));
2189 }
dschinazi42fc2da2020-04-24 16:19:17 -07002190 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002191 }
2192 // Retransmit CHLO on last connection should be dropped.
2193 QuicConnectionId last_connection =
2194 TestConnectionId(kMaxNumSessionsToCreate + 1);
dschinazi42fc2da2020-04-24 16:19:17 -07002195 ProcessFirstFlight(last_connection);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002196
2197 size_t packets_buffered = 2;
2198
2199 // Reset counter and process buffered CHLO.
2200 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002201 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002202 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002203 dispatcher_.get(), config_, last_connection, client_addr_,
2204 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002205 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002206 // Only one packet(CHLO) should be process.
2207 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2208 ProcessUdpPacket(_, _, _))
2209 .Times(packets_buffered)
2210 .WillRepeatedly(WithArg<2>(
2211 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002212 if (version_.UsesQuicCrypto()) {
2213 ValidatePacket(last_connection, packet);
2214 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002215 })));
2216 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2217}
2218
dschinazi8d1c9d42020-02-18 13:12:20 -08002219TEST_P(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002220 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
2221 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
2222 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
2223 // Last CHLO will be buffered. Others will create connection right away.
2224 if (conn_id <= kMaxNumSessionsToCreate) {
2225 EXPECT_CALL(*dispatcher_,
2226 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002227 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002228 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002229 dispatcher_.get(), config_, TestConnectionId(conn_id),
2230 client_addr_, &mock_helper_, &mock_alarm_factory_,
2231 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002232 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002233 EXPECT_CALL(
2234 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2235 ProcessUdpPacket(_, _, _))
2236 .WillRepeatedly(WithArg<2>(
2237 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002238 if (version_.UsesQuicCrypto()) {
2239 ValidatePacket(TestConnectionId(conn_id), packet);
2240 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002241 })));
2242 }
dschinazi42fc2da2020-04-24 16:19:17 -07002243 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002244 }
2245
2246 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
2247 // last one should be dropped.
2248 for (uint64_t packet_number = 2;
2249 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
2250 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
2251 }
2252
2253 // Reset counter and process buffered CHLO.
2254 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002255 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002256 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002257 dispatcher_.get(), config_, last_connection_id, client_addr_,
2258 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002259 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002260 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
2261 // should be process.
2262 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2263 ProcessUdpPacket(_, _, _))
2264 .Times(kDefaultMaxUndecryptablePackets + 1)
2265 .WillRepeatedly(WithArg<2>(
2266 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002267 if (version_.UsesQuicCrypto()) {
2268 ValidatePacket(last_connection_id, packet);
2269 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002270 })));
2271 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2272}
2273
2274// Tests that when dispatcher's packet buffer is full, a CHLO on connection
2275// which doesn't have buffered CHLO should be buffered.
dschinazi8d1c9d42020-02-18 13:12:20 -08002276TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002277 QuicBufferedPacketStore* store =
2278 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
2279
2280 uint64_t conn_id = 1;
dschinazi42fc2da2020-04-24 16:19:17 -07002281 ProcessUndecryptableEarlyPacket(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002282 // Fill packet buffer to full with CHLOs on other connections. Need to feed
2283 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
2284 // session directly.
2285 for (conn_id = 2;
2286 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
2287 ++conn_id) {
2288 if (conn_id <= kMaxNumSessionsToCreate + 1) {
2289 EXPECT_CALL(*dispatcher_,
2290 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002291 Eq(ExpectedAlpn()), _))
wub89490e02019-12-12 12:45:58 -08002292 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002293 dispatcher_.get(), config_, TestConnectionId(conn_id),
2294 client_addr_, &mock_helper_, &mock_alarm_factory_,
2295 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002296 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002297 EXPECT_CALL(
2298 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2299 ProcessUdpPacket(_, _, _))
2300 .WillOnce(WithArg<2>(
2301 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002302 if (version_.UsesQuicCrypto()) {
2303 ValidatePacket(TestConnectionId(conn_id), packet);
2304 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002305 })));
2306 }
dschinazi42fc2da2020-04-24 16:19:17 -07002307 ProcessFirstFlight(TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002308 }
2309 EXPECT_FALSE(store->HasChloForConnection(
2310 /*connection_id=*/TestConnectionId(1)));
2311
2312 // CHLO on connection 1 should still be buffered.
dschinazi42fc2da2020-04-24 16:19:17 -07002313 ProcessFirstFlight(TestConnectionId(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002314 EXPECT_TRUE(store->HasChloForConnection(
2315 /*connection_id=*/TestConnectionId(1)));
2316}
2317
2318// Regression test for b/117874922.
dschinazi8d1c9d42020-02-18 13:12:20 -08002319TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
dschinazic3316f32020-03-05 14:34:36 -08002320 // Ensure the preferred version is not supported by the server.
dschinazi5a50d932020-06-17 12:43:36 -07002321 QuicDisableVersion(AllSupportedVersions().front());
dschinazib3fed9e2020-06-11 11:59:33 -07002322
QUICHE teama6ef0a62019-03-07 20:34:33 -05002323 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
2324 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
2325 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
2326 // Last 5 CHLOs will be buffered. Others will create connection right away.
2327 ParsedQuicVersion version =
2328 supported_versions[(conn_id - 1) % supported_versions.size()];
2329 if (conn_id <= kMaxNumSessionsToCreate) {
dschinazi42fc2da2020-04-24 16:19:17 -07002330 EXPECT_CALL(
2331 *dispatcher_,
2332 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
2333 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002334 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002335 dispatcher_.get(), config_, TestConnectionId(conn_id),
2336 client_addr_, &mock_helper_, &mock_alarm_factory_,
2337 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
wub89490e02019-12-12 12:45:58 -08002338 &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002339 EXPECT_CALL(
2340 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2341 ProcessUdpPacket(_, _, _))
2342 .WillRepeatedly(WithArg<2>(
2343 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002344 if (version_.UsesQuicCrypto()) {
2345 ValidatePacket(TestConnectionId(conn_id), packet);
2346 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002347 })));
2348 }
dschinazi42fc2da2020-04-24 16:19:17 -07002349 ProcessFirstFlight(version, TestConnectionId(conn_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002350 }
2351
2352 // Process buffered CHLOs. Verify the version is correct.
2353 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
2354 conn_id <= last_connection_id; ++conn_id) {
2355 ParsedQuicVersion version =
2356 supported_versions[(conn_id - 1) % supported_versions.size()];
2357 EXPECT_CALL(*dispatcher_,
2358 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
dschinazi42fc2da2020-04-24 16:19:17 -07002359 Eq(ExpectedAlpnForVersion(version)), version))
wub89490e02019-12-12 12:45:58 -08002360 .WillOnce(Return(ByMove(CreateSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002361 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
2362 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
wub89490e02019-12-12 12:45:58 -08002363 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002364 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
2365 ProcessUdpPacket(_, _, _))
2366 .WillRepeatedly(WithArg<2>(
2367 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
dschinazi42fc2da2020-04-24 16:19:17 -07002368 if (version_.UsesQuicCrypto()) {
2369 ValidatePacket(TestConnectionId(conn_id), packet);
2370 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002371 })));
2372 }
2373 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
2374}
2375
QUICHE teama6ef0a62019-03-07 20:34:33 -05002376} // namespace
2377} // namespace test
2378} // namespace quic