blob: 188707b707b8b89ce214ada65be91935ef875ad8 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
6
7#include <memory>
8#include <ostream>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/core/chlo_extractor.h"
12#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
13#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
14#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
15#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
16#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
17#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
18#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
19#include "net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h"
20#include "net/third_party/quiche/src/quic/core/quic_types.h"
21#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050022#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
25#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.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"
31#include "net/third_party/quiche/src/quic/test_tools/mock_quic_time_wait_list_manager.h"
32#include "net/third_party/quiche/src/quic/test_tools/quic_buffered_packet_store_peer.h"
33#include "net/third_party/quiche/src/quic/test_tools/quic_crypto_server_config_peer.h"
34#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
35#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
36#include "net/third_party/quiche/src/quic/test_tools/quic_time_wait_list_manager_peer.h"
37#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
38
39using testing::_;
40using testing::InSequence;
41using testing::Invoke;
42using testing::NiceMock;
43using testing::Return;
44using testing::WithArg;
45using testing::WithoutArgs;
46
47static const size_t kDefaultMaxConnectionsInStore = 100;
48static const size_t kMaxConnectionsWithoutCHLO =
49 kDefaultMaxConnectionsInStore / 2;
50static const int16_t kMaxNumSessionsToCreate = 16;
51
52namespace quic {
53namespace test {
54namespace {
55
56class TestQuicSpdyServerSession : public QuicServerSessionBase {
57 public:
58 TestQuicSpdyServerSession(const QuicConfig& config,
59 QuicConnection* connection,
60 const QuicCryptoServerConfig* crypto_config,
61 QuicCompressedCertsCache* compressed_certs_cache)
62 : QuicServerSessionBase(config,
63 CurrentSupportedVersions(),
64 connection,
65 nullptr,
66 nullptr,
67 crypto_config,
68 compressed_certs_cache),
69 crypto_stream_(QuicServerSessionBase::GetMutableCryptoStream()) {}
70 TestQuicSpdyServerSession(const TestQuicSpdyServerSession&) = delete;
71 TestQuicSpdyServerSession& operator=(const TestQuicSpdyServerSession&) =
72 delete;
73
74 ~TestQuicSpdyServerSession() override { delete connection(); }
75
76 MOCK_METHOD3(OnConnectionClosed,
77 void(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -070078 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 ConnectionCloseSource source));
80 MOCK_METHOD1(CreateIncomingStream, QuicSpdyStream*(QuicStreamId id));
renjietangbaea59c2019-05-29 15:08:14 -070081 MOCK_METHOD1(CreateIncomingStream, QuicSpdyStream*(PendingStream* pending));
QUICHE teama6ef0a62019-03-07 20:34:33 -050082 MOCK_METHOD0(CreateOutgoingBidirectionalStream, QuicSpdyStream*());
83 MOCK_METHOD0(CreateOutgoingUnidirectionalStream, QuicSpdyStream*());
84
85 QuicCryptoServerStreamBase* CreateQuicCryptoServerStream(
86 const QuicCryptoServerConfig* crypto_config,
87 QuicCompressedCertsCache* compressed_certs_cache) override {
wubd893df12019-05-15 18:48:20 -070088 return new QuicCryptoServerStream(crypto_config, compressed_certs_cache,
89 this, stream_helper());
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 }
91
92 void SetCryptoStream(QuicCryptoServerStream* crypto_stream) {
93 crypto_stream_ = crypto_stream;
94 }
95
96 QuicCryptoServerStreamBase* GetMutableCryptoStream() override {
97 return crypto_stream_;
98 }
99
100 const QuicCryptoServerStreamBase* GetCryptoStream() const override {
101 return crypto_stream_;
102 }
103
104 QuicCryptoServerStream::Helper* stream_helper() {
105 return QuicServerSessionBase::stream_helper();
106 }
107
108 private:
109 QuicCryptoServerStreamBase* crypto_stream_;
110};
111
112class TestDispatcher : public QuicDispatcher {
113 public:
114 TestDispatcher(const QuicConfig* config,
115 const QuicCryptoServerConfig* crypto_config,
QUICHE teamc65d1d12019-03-19 20:58:04 -0700116 QuicVersionManager* version_manager,
117 QuicRandom* random)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500118 : QuicDispatcher(config,
119 crypto_config,
120 version_manager,
121 QuicMakeUnique<MockQuicConnectionHelper>(),
122 std::unique_ptr<QuicCryptoServerStream::Helper>(
QUICHE teamc65d1d12019-03-19 20:58:04 -0700123 new QuicSimpleCryptoServerStreamHelper(random)),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500124 QuicMakeUnique<MockAlarmFactory>(),
125 kQuicDefaultConnectionIdLength) {}
126
127 MOCK_METHOD4(CreateQuicSession,
128 QuicServerSessionBase*(QuicConnectionId connection_id,
129 const QuicSocketAddress& peer_address,
130 QuicStringPiece alpn,
131 const quic::ParsedQuicVersion& version));
132
133 MOCK_METHOD2(ShouldCreateOrBufferPacketForConnection,
134 bool(QuicConnectionId connection_id, bool ietf_quic));
135
136 struct TestQuicPerPacketContext : public QuicPerPacketContext {
vasilvvc48c8712019-03-11 13:38:16 -0700137 std::string custom_packet_context;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138 };
139
140 std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const override {
141 auto test_context = QuicMakeUnique<TestQuicPerPacketContext>();
142 test_context->custom_packet_context = custom_packet_context_;
143 return std::move(test_context);
144 }
145
146 void RestorePerPacketContext(
147 std::unique_ptr<QuicPerPacketContext> context) override {
148 TestQuicPerPacketContext* test_context =
149 static_cast<TestQuicPerPacketContext*>(context.get());
150 custom_packet_context_ = test_context->custom_packet_context;
151 }
152
vasilvvc48c8712019-03-11 13:38:16 -0700153 std::string custom_packet_context_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154
155 using QuicDispatcher::current_client_address;
156 using QuicDispatcher::current_peer_address;
157 using QuicDispatcher::current_self_address;
dschinazi7b9278c2019-05-20 07:36:21 -0700158 using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500159 using QuicDispatcher::writer;
160};
161
162// A Connection class which unregisters the session from the dispatcher when
163// sending connection close.
164// It'd be slightly more realistic to do this from the Session but it would
165// involve a lot more mocking.
166class MockServerConnection : public MockQuicConnection {
167 public:
168 MockServerConnection(QuicConnectionId connection_id,
169 MockQuicConnectionHelper* helper,
170 MockAlarmFactory* alarm_factory,
171 QuicDispatcher* dispatcher)
172 : MockQuicConnection(connection_id,
173 helper,
174 alarm_factory,
175 Perspective::IS_SERVER),
176 dispatcher_(dispatcher) {}
177
178 void UnregisterOnConnectionClosed() {
179 QUIC_LOG(ERROR) << "Unregistering " << connection_id();
180 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR,
181 "Unregistering.",
182 ConnectionCloseSource::FROM_SELF);
183 }
184
185 private:
186 QuicDispatcher* dispatcher_;
187};
188
189class QuicDispatcherTest : public QuicTest {
190 public:
191 QuicDispatcherTest()
192 : QuicDispatcherTest(crypto_test_utils::ProofSourceForTesting()) {}
193
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 explicit QuicDispatcherTest(std::unique_ptr<ProofSource> proof_source)
195 :
196
nharperf5e68452019-05-29 17:24:18 -0700197 version_manager_(AllSupportedVersions()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198 crypto_config_(QuicCryptoServerConfig::TESTING,
199 QuicRandom::GetInstance(),
200 std::move(proof_source),
201 KeyExchangeSource::Default(),
202 TlsServerHandshaker::CreateSslCtx()),
203 server_address_(QuicIpAddress::Any4(), 5),
QUICHE teamc65d1d12019-03-19 20:58:04 -0700204 dispatcher_(
205 new NiceMock<TestDispatcher>(&config_,
206 &crypto_config_,
207 &version_manager_,
208 mock_helper_.GetRandomGenerator())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 time_wait_list_manager_(nullptr),
210 session1_(nullptr),
211 session2_(nullptr),
212 store_(nullptr) {}
213
214 void SetUp() override {
215 dispatcher_->InitializeWithWriter(new MockPacketWriter());
216 // Set the counter to some value to start with.
217 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(
218 dispatcher_.get(), kMaxNumSessionsToCreate);
219 ON_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(_, _))
220 .WillByDefault(Return(true));
221 }
222
223 MockQuicConnection* connection1() {
224 if (session1_ == nullptr) {
225 return nullptr;
226 }
227 return reinterpret_cast<MockQuicConnection*>(session1_->connection());
228 }
229
230 MockQuicConnection* connection2() {
231 if (session2_ == nullptr) {
232 return nullptr;
233 }
234 return reinterpret_cast<MockQuicConnection*>(session2_->connection());
235 }
236
237 // Process a packet with an 8 byte connection id,
238 // 6 byte packet number, default path id, and packet number 1,
239 // using the first supported version.
240 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700241 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500242 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700243 const std::string& data) {
dschinazi346b7ce2019-06-05 01:38:18 -0700244 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500245 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER);
246 }
247
248 // Process a packet with a default path id, and packet number 1,
249 // using the first supported version.
250 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700251 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700253 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700254 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500255 QuicPacketNumberLength packet_number_length) {
dschinazi346b7ce2019-06-05 01:38:18 -0700256 ProcessPacket(peer_address, server_connection_id, has_version_flag, data,
257 server_connection_id_included, packet_number_length, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258 }
259
260 // Process a packet using the first supported version.
261 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700262 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500263 bool has_version_flag,
vasilvvc48c8712019-03-11 13:38:16 -0700264 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700265 QuicConnectionIdIncluded server_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500266 QuicPacketNumberLength packet_number_length,
267 uint64_t packet_number) {
dschinazi346b7ce2019-06-05 01:38:18 -0700268 ProcessPacket(peer_address, server_connection_id, has_version_flag,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500269 CurrentSupportedVersions().front(), data,
dschinazi346b7ce2019-06-05 01:38:18 -0700270 server_connection_id_included, packet_number_length,
271 packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 }
273
274 // Processes a packet.
275 void ProcessPacket(QuicSocketAddress peer_address,
dschinazi346b7ce2019-06-05 01:38:18 -0700276 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500277 bool has_version_flag,
278 ParsedQuicVersion version,
vasilvvc48c8712019-03-11 13:38:16 -0700279 const std::string& data,
dschinazi346b7ce2019-06-05 01:38:18 -0700280 QuicConnectionIdIncluded server_connection_id_included,
281 QuicPacketNumberLength packet_number_length,
282 uint64_t packet_number) {
283 ProcessPacket(peer_address, server_connection_id, EmptyQuicConnectionId(),
284 has_version_flag, version, data,
285 server_connection_id_included, CONNECTION_ID_ABSENT,
286 packet_number_length, packet_number);
287 }
288
289 // Processes a packet.
290 void ProcessPacket(QuicSocketAddress peer_address,
291 QuicConnectionId server_connection_id,
292 QuicConnectionId client_connection_id,
293 bool has_version_flag,
294 ParsedQuicVersion version,
295 const std::string& data,
296 QuicConnectionIdIncluded server_connection_id_included,
297 QuicConnectionIdIncluded client_connection_id_included,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298 QuicPacketNumberLength packet_number_length,
299 uint64_t packet_number) {
300 ParsedQuicVersionVector versions(SupportedVersions(version));
301 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
dschinazi346b7ce2019-06-05 01:38:18 -0700302 server_connection_id, client_connection_id, has_version_flag, false,
303 packet_number, data, server_connection_id_included,
304 client_connection_id_included, packet_number_length, &versions));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500305 std::unique_ptr<QuicReceivedPacket> received_packet(
306 ConstructReceivedPacket(*packet, mock_helper_.GetClock()->Now()));
307
308 if (ChloExtractor::Extract(*packet, versions, {}, nullptr,
dschinazi346b7ce2019-06-05 01:38:18 -0700309 server_connection_id.length())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310 // Add CHLO packet to the beginning to be verified first, because it is
311 // also processed first by new session.
dschinazi346b7ce2019-06-05 01:38:18 -0700312 data_connection_map_[server_connection_id].push_front(
vasilvvc48c8712019-03-11 13:38:16 -0700313 std::string(packet->data(), packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314 } else {
315 // For non-CHLO, always append to last.
dschinazi346b7ce2019-06-05 01:38:18 -0700316 data_connection_map_[server_connection_id].push_back(
vasilvvc48c8712019-03-11 13:38:16 -0700317 std::string(packet->data(), packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500318 }
319 dispatcher_->ProcessPacket(server_address_, peer_address, *received_packet);
320 }
321
322 void ValidatePacket(QuicConnectionId conn_id,
323 const QuicEncryptedPacket& packet) {
324 EXPECT_EQ(data_connection_map_[conn_id].front().length(),
325 packet.AsStringPiece().length());
326 EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece());
327 data_connection_map_[conn_id].pop_front();
328 }
329
330 QuicServerSessionBase* CreateSession(
331 TestDispatcher* dispatcher,
332 const QuicConfig& config,
333 QuicConnectionId connection_id,
334 const QuicSocketAddress& peer_address,
335 MockQuicConnectionHelper* helper,
336 MockAlarmFactory* alarm_factory,
337 const QuicCryptoServerConfig* crypto_config,
338 QuicCompressedCertsCache* compressed_certs_cache,
339 TestQuicSpdyServerSession** session) {
340 MockServerConnection* connection = new MockServerConnection(
341 connection_id, helper, alarm_factory, dispatcher);
342 connection->SetQuicPacketWriter(dispatcher->writer(),
343 /*owns_writer=*/false);
344 *session = new TestQuicSpdyServerSession(config, connection, crypto_config,
345 compressed_certs_cache);
346 connection->set_visitor(*session);
347 ON_CALL(*connection, CloseConnection(_, _, _))
348 .WillByDefault(WithoutArgs(Invoke(
349 connection, &MockServerConnection::UnregisterOnConnectionClosed)));
350 return *session;
351 }
352
353 void CreateTimeWaitListManager() {
354 time_wait_list_manager_ = new MockTimeWaitListManager(
355 QuicDispatcherPeer::GetWriter(dispatcher_.get()), dispatcher_.get(),
356 mock_helper_.GetClock(), &mock_alarm_factory_);
357 // dispatcher_ takes the ownership of time_wait_list_manager_.
358 QuicDispatcherPeer::SetTimeWaitListManager(dispatcher_.get(),
359 time_wait_list_manager_);
360 }
361
vasilvvc48c8712019-03-11 13:38:16 -0700362 std::string SerializeCHLO() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500363 CryptoHandshakeMessage client_hello;
364 client_hello.set_tag(kCHLO);
365 client_hello.SetStringPiece(kALPN, "hq");
vasilvvc48c8712019-03-11 13:38:16 -0700366 return std::string(client_hello.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500367 }
368
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369 void MarkSession1Deleted() { session1_ = nullptr; }
370
371 MockQuicConnectionHelper mock_helper_;
372 MockAlarmFactory mock_alarm_factory_;
373 QuicConfig config_;
374 QuicVersionManager version_manager_;
375 QuicCryptoServerConfig crypto_config_;
376 QuicSocketAddress server_address_;
377 std::unique_ptr<NiceMock<TestDispatcher>> dispatcher_;
378 MockTimeWaitListManager* time_wait_list_manager_;
379 TestQuicSpdyServerSession* session1_;
380 TestQuicSpdyServerSession* session2_;
vasilvvc48c8712019-03-11 13:38:16 -0700381 std::map<QuicConnectionId, std::list<std::string>> data_connection_map_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500382 QuicBufferedPacketStore* store_;
383};
384
385TEST_F(QuicDispatcherTest, TlsClientHelloCreatesSession) {
QUICHE teamea740082019-03-11 17:58:43 -0700386 if (!QuicVersionUsesCryptoFrames(
387 CurrentSupportedVersions().front().transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388 // TLS is only supported in versions 47 and greater.
389 return;
390 }
wub49855982019-05-01 14:16:26 -0700391 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500392 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
393
394 EXPECT_CALL(*dispatcher_,
395 CreateQuicSession(TestConnectionId(1), client_address,
396 QuicStringPiece(""), _))
397 .WillOnce(testing::Return(CreateSession(
398 dispatcher_.get(), config_, TestConnectionId(1), client_address,
399 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
400 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
401 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
402 ProcessUdpPacket(_, _, _))
403 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
404 ValidatePacket(TestConnectionId(1), packet);
405 })));
406 EXPECT_CALL(*dispatcher_,
407 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
408 ProcessPacket(
409 client_address, TestConnectionId(1), true,
410 ParsedQuicVersion(PROTOCOL_TLS1_3,
411 CurrentSupportedVersions().front().transport_version),
412 SerializeCHLO(), CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
413 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
414 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
415}
416
417TEST_F(QuicDispatcherTest, ProcessPackets) {
418 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
419
420 EXPECT_CALL(*dispatcher_,
421 CreateQuicSession(TestConnectionId(1), client_address,
422 QuicStringPiece("hq"), _))
423 .WillOnce(testing::Return(CreateSession(
424 dispatcher_.get(), config_, TestConnectionId(1), client_address,
425 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
426 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
427 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
428 ProcessUdpPacket(_, _, _))
429 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
430 ValidatePacket(TestConnectionId(1), packet);
431 })));
432 EXPECT_CALL(*dispatcher_,
433 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
434 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
435 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
436 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
437
438 EXPECT_CALL(*dispatcher_,
439 CreateQuicSession(TestConnectionId(2), client_address,
440 QuicStringPiece("hq"), _))
441 .WillOnce(testing::Return(CreateSession(
442 dispatcher_.get(), config_, TestConnectionId(2), client_address,
443 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
444 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
445 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
446 ProcessUdpPacket(_, _, _))
447 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
448 ValidatePacket(TestConnectionId(2), packet);
449 })));
450 EXPECT_CALL(*dispatcher_,
451 ShouldCreateOrBufferPacketForConnection(TestConnectionId(2), _));
452 ProcessPacket(client_address, TestConnectionId(2), true, SerializeCHLO());
453
454 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
455 ProcessUdpPacket(_, _, _))
456 .Times(1)
457 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
458 ValidatePacket(TestConnectionId(1), packet);
459 })));
460 ProcessPacket(client_address, TestConnectionId(1), false, "data");
461}
462
463// Regression test of b/93325907.
464TEST_F(QuicDispatcherTest, DispatcherDoesNotRejectPacketNumberZero) {
465 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
466
467 EXPECT_CALL(*dispatcher_,
468 CreateQuicSession(TestConnectionId(1), client_address,
469 QuicStringPiece("hq"), _))
470 .WillOnce(testing::Return(CreateSession(
471 dispatcher_.get(), config_, TestConnectionId(1), client_address,
472 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
473 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
474 // Verify both packets 1 and 2 are processed by connection 1.
475 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
476 ProcessUdpPacket(_, _, _))
477 .Times(2)
478 .WillRepeatedly(
479 WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
480 ValidatePacket(TestConnectionId(1), packet);
481 })));
482 EXPECT_CALL(*dispatcher_,
483 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
484 ProcessPacket(
485 client_address, TestConnectionId(1), true,
486 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
487 CurrentSupportedVersions().front().transport_version),
488 SerializeCHLO(), CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
489 // Packet number 256 with packet number length 1 would be considered as 0 in
490 // dispatcher.
491 ProcessPacket(
492 client_address, TestConnectionId(1), false,
493 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
494 CurrentSupportedVersions().front().transport_version),
495 "", CONNECTION_ID_PRESENT, PACKET_1BYTE_PACKET_NUMBER, 256);
496 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
497 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
498}
499
500TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
501 CreateTimeWaitListManager();
502 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
503
504 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
dschinazi346b7ce2019-06-05 01:38:18 -0700505 EXPECT_CALL(
506 *time_wait_list_manager_,
507 SendVersionNegotiationPacket(TestConnectionId(1), _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508 .Times(1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509 // Pad the CHLO message with enough data to make the packet large enough
510 // to trigger version negotiation.
vasilvvc48c8712019-03-11 13:38:16 -0700511 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512 DCHECK_LE(1200u, chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700513 ProcessPacket(client_address, TestConnectionId(1), true,
514 QuicVersionReservedForNegotiation(), chlo,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500515 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
516}
517
dschinazi346b7ce2019-06-05 01:38:18 -0700518TEST_F(QuicDispatcherTest, StatelessVersionNegotiationWithClientConnectionId) {
519 SetQuicRestartFlag(quic_do_not_override_connection_id, true);
520 CreateTimeWaitListManager();
521 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
522
523 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
524 EXPECT_CALL(*time_wait_list_manager_,
525 SendVersionNegotiationPacket(TestConnectionId(1),
526 TestConnectionId(2), _, _, _, _, _))
527 .Times(1);
528 // Pad the CHLO message with enough data to make the packet large enough
529 // to trigger version negotiation.
530 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
531 DCHECK_LE(1200u, chlo.length());
532 ProcessPacket(client_address, TestConnectionId(1), TestConnectionId(2), true,
533 QuicVersionReservedForNegotiation(), chlo,
534 CONNECTION_ID_PRESENT, CONNECTION_ID_PRESENT,
535 PACKET_4BYTE_PACKET_NUMBER, 1);
536}
537
QUICHE teama6ef0a62019-03-07 20:34:33 -0500538TEST_F(QuicDispatcherTest, NoVersionNegotiationWithSmallPacket) {
539 CreateTimeWaitListManager();
540 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
541
542 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
543 EXPECT_CALL(*time_wait_list_manager_,
dschinazib417d602019-05-29 13:08:45 -0700544 SendVersionNegotiationPacket(_, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500545 .Times(0);
vasilvvc48c8712019-03-11 13:38:16 -0700546 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500547 // Truncate to 1100 bytes of payload which results in a packet just
548 // under 1200 bytes after framing, packet, and encryption overhead.
549 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700550 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500551 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700552 ProcessPacket(client_address, TestConnectionId(1), true,
553 QuicVersionReservedForNegotiation(), truncated_chlo,
554 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500555}
556
557// Disabling CHLO size validation allows the dispatcher to send version
558// negotiation packets in response to a CHLO that is otherwise too small.
559TEST_F(QuicDispatcherTest, VersionNegotiationWithoutChloSizeValidation) {
560 crypto_config_.set_validate_chlo_size(false);
561
562 CreateTimeWaitListManager();
563 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
564
565 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _)).Times(0);
566 EXPECT_CALL(*time_wait_list_manager_,
dschinazib417d602019-05-29 13:08:45 -0700567 SendVersionNegotiationPacket(_, _, _, _, _, _, _))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500568 .Times(1);
vasilvvc48c8712019-03-11 13:38:16 -0700569 std::string chlo = SerializeCHLO() + std::string(1200, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500570 // Truncate to 1100 bytes of payload which results in a packet just
571 // under 1200 bytes after framing, packet, and encryption overhead.
572 DCHECK_LE(1200u, chlo.length());
vasilvvc48c8712019-03-11 13:38:16 -0700573 std::string truncated_chlo = chlo.substr(0, 1100);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500574 DCHECK_EQ(1100u, truncated_chlo.length());
nharper4fd11052019-06-04 14:23:22 -0700575 ProcessPacket(client_address, TestConnectionId(1), true,
576 QuicVersionReservedForNegotiation(), truncated_chlo,
577 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500578}
579
580TEST_F(QuicDispatcherTest, Shutdown) {
581 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
582
583 EXPECT_CALL(*dispatcher_,
584 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
585 .WillOnce(testing::Return(CreateSession(
586 dispatcher_.get(), config_, TestConnectionId(1), client_address,
587 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
588 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
589 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
590 ProcessUdpPacket(_, _, _))
591 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
592 ValidatePacket(TestConnectionId(1), packet);
593 })));
594
595 EXPECT_CALL(*dispatcher_,
596 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
597 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
598
599 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
600 CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
601
602 dispatcher_->Shutdown();
603}
604
605TEST_F(QuicDispatcherTest, TimeWaitListManager) {
606 CreateTimeWaitListManager();
607
608 // Create a new session.
609 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
610 QuicConnectionId connection_id = TestConnectionId(1);
611 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
612 QuicStringPiece("hq"), _))
613 .WillOnce(testing::Return(CreateSession(
614 dispatcher_.get(), config_, connection_id, client_address,
615 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
616 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
617 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
618 ProcessUdpPacket(_, _, _))
619 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
620 ValidatePacket(TestConnectionId(1), packet);
621 })));
622
623 EXPECT_CALL(*dispatcher_,
624 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
625 ProcessPacket(client_address, connection_id, true, SerializeCHLO());
626
627 // Now close the connection, which should add it to the time wait list.
628 session1_->connection()->CloseConnection(
629 QUIC_INVALID_VERSION,
630 "Server: Packet 2 without version flag before version negotiated.",
631 ConnectionCloseBehavior::SILENT_CLOSE);
632 EXPECT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
633
634 // Dispatcher forwards subsequent packets for this connection_id to the time
635 // wait list manager.
636 EXPECT_CALL(*time_wait_list_manager_,
637 ProcessPacket(_, _, connection_id, _, _))
638 .Times(1);
639 EXPECT_CALL(*time_wait_list_manager_,
640 AddConnectionIdToTimeWait(_, _, _, _, _))
641 .Times(0);
642 ProcessPacket(client_address, connection_id, true, "data");
643}
644
645TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
646 CreateTimeWaitListManager();
647
648 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
649 QuicConnectionId connection_id = TestConnectionId(1);
650 // Dispatcher forwards all packets for this connection_id to the time wait
651 // list manager.
652 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
653 .Times(0);
654 EXPECT_CALL(*time_wait_list_manager_,
655 ProcessPacket(_, _, connection_id, _, _))
656 .Times(1);
657 EXPECT_CALL(*time_wait_list_manager_,
658 AddConnectionIdToTimeWait(_, _, _, _, _))
659 .Times(1);
660 ProcessPacket(client_address, connection_id, false, SerializeCHLO());
661}
662
QUICHE teamc65d1d12019-03-19 20:58:04 -0700663// Makes sure nine-byte connection IDs are replaced by 8-byte ones.
QUICHE team963d57e2019-03-21 10:58:47 -0700664TEST_F(QuicDispatcherTest, LongConnectionIdLengthReplaced) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700665 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
666 CurrentSupportedVersions()[0].transport_version)) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700667 // When variable length connection IDs are not supported, the connection
668 // fails. See StrayPacketTruncatedConnectionId.
QUICHE team8e2e4532019-03-14 14:37:56 -0700669 return;
670 }
QUICHE team8e2e4532019-03-14 14:37:56 -0700671 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
672
QUICHE teamc65d1d12019-03-19 20:58:04 -0700673 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
674 QuicConnectionId fixed_connection_id =
675 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
676
677 EXPECT_CALL(*dispatcher_,
678 CreateQuicSession(fixed_connection_id, client_address,
679 QuicStringPiece("hq"), _))
680 .WillOnce(testing::Return(CreateSession(
681 dispatcher_.get(), config_, fixed_connection_id, client_address,
682 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
683 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
684 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
685 ProcessUdpPacket(_, _, _))
686 .WillOnce(WithArg<2>(
687 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
688 ValidatePacket(bad_connection_id, packet);
689 })));
690 EXPECT_CALL(*dispatcher_,
691 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
692 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
693 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
694 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
QUICHE team8e2e4532019-03-14 14:37:56 -0700695}
696
QUICHE team963d57e2019-03-21 10:58:47 -0700697// Makes sure zero-byte connection IDs are replaced by 8-byte ones.
698TEST_F(QuicDispatcherTest, InvalidShortConnectionIdLengthReplaced) {
699 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
700 CurrentSupportedVersions()[0].transport_version)) {
701 // When variable length connection IDs are not supported, the connection
702 // fails. See StrayPacketTruncatedConnectionId.
703 return;
704 }
705 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
706
707 QuicConnectionId bad_connection_id = EmptyQuicConnectionId();
708 QuicConnectionId fixed_connection_id =
709 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
710
711 // Disable validation of invalid short connection IDs.
dschinazi7b9278c2019-05-20 07:36:21 -0700712 dispatcher_->SetAllowShortInitialServerConnectionIds(true);
QUICHE team963d57e2019-03-21 10:58:47 -0700713 // Note that StrayPacketTruncatedConnectionId covers the case where the
714 // validation is still enabled.
715
716 EXPECT_CALL(*dispatcher_,
717 CreateQuicSession(fixed_connection_id, client_address,
718 QuicStringPiece("hq"), _))
719 .WillOnce(testing::Return(CreateSession(
720 dispatcher_.get(), config_, fixed_connection_id, client_address,
721 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
722 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
723 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
724 ProcessUdpPacket(_, _, _))
725 .WillOnce(WithArg<2>(
726 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
727 ValidatePacket(bad_connection_id, packet);
728 })));
729 EXPECT_CALL(*dispatcher_,
730 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
731 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
732 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
733 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
734}
735
QUICHE teamc65d1d12019-03-19 20:58:04 -0700736// Makes sure TestConnectionId(1) creates a new connection and
737// TestConnectionIdNineBytesLong(2) gets replaced.
QUICHE team8e2e4532019-03-14 14:37:56 -0700738TEST_F(QuicDispatcherTest, MixGoodAndBadConnectionIdLengthPackets) {
739 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
740 CurrentSupportedVersions()[0].transport_version)) {
741 return;
742 }
QUICHE teamc65d1d12019-03-19 20:58:04 -0700743
QUICHE team8e2e4532019-03-14 14:37:56 -0700744 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700745 QuicConnectionId bad_connection_id = TestConnectionIdNineBytesLong(2);
746 QuicConnectionId fixed_connection_id =
747 QuicUtils::CreateRandomConnectionId(mock_helper_.GetRandomGenerator());
QUICHE team8e2e4532019-03-14 14:37:56 -0700748
749 EXPECT_CALL(*dispatcher_,
750 CreateQuicSession(TestConnectionId(1), client_address,
751 QuicStringPiece("hq"), _))
752 .WillOnce(testing::Return(CreateSession(
753 dispatcher_.get(), config_, TestConnectionId(1), client_address,
754 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
755 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
756 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
757 ProcessUdpPacket(_, _, _))
758 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
759 ValidatePacket(TestConnectionId(1), packet);
760 })));
761 EXPECT_CALL(*dispatcher_,
762 ShouldCreateOrBufferPacketForConnection(TestConnectionId(1), _));
763 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
764 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
765 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
766
QUICHE teamc65d1d12019-03-19 20:58:04 -0700767 EXPECT_CALL(*dispatcher_,
768 CreateQuicSession(fixed_connection_id, client_address,
769 QuicStringPiece("hq"), _))
770 .WillOnce(testing::Return(CreateSession(
771 dispatcher_.get(), config_, fixed_connection_id, client_address,
772 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
773 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
774 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
775 ProcessUdpPacket(_, _, _))
776 .WillOnce(WithArg<2>(
777 Invoke([this, bad_connection_id](const QuicEncryptedPacket& packet) {
778 ValidatePacket(bad_connection_id, packet);
779 })));
780 EXPECT_CALL(*dispatcher_,
781 ShouldCreateOrBufferPacketForConnection(bad_connection_id, _));
782 ProcessPacket(client_address, bad_connection_id, true, SerializeCHLO());
QUICHE team8e2e4532019-03-14 14:37:56 -0700783
784 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
785 ProcessUdpPacket(_, _, _))
786 .Times(1)
787 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
788 ValidatePacket(TestConnectionId(1), packet);
789 })));
790 ProcessPacket(client_address, TestConnectionId(1), false, "data");
791}
792
QUICHE teama6ef0a62019-03-07 20:34:33 -0500793TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) {
794 CreateTimeWaitListManager();
795
796 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 0);
797
798 // dispatcher_ should drop this packet.
799 EXPECT_CALL(*dispatcher_,
800 CreateQuicSession(TestConnectionId(1), client_address,
801 QuicStringPiece("hq"), _))
802 .Times(0);
803 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _)).Times(0);
804 EXPECT_CALL(*time_wait_list_manager_,
805 AddConnectionIdToTimeWait(_, _, _, _, _))
806 .Times(0);
807 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
808}
809
810TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
811 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
812 QuicConnectionId connection_id = TestConnectionId(1);
813
814 EXPECT_CALL(*dispatcher_,
815 CreateQuicSession(TestConnectionId(1), client_address,
816 QuicStringPiece("hq"), _))
817 .WillOnce(testing::Return(CreateSession(
818 dispatcher_.get(), config_, TestConnectionId(1), client_address,
819 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
820 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
821 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
822 ProcessUdpPacket(_, _, _))
823 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
824 ValidatePacket(TestConnectionId(1), packet);
825 })));
826
827 // A packet whose packet number is the largest that is allowed to start a
828 // connection.
829 EXPECT_CALL(*dispatcher_,
830 ShouldCreateOrBufferPacketForConnection(connection_id, _));
831 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
832 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
833 QuicDispatcher::kMaxReasonableInitialPacketNumber);
834 EXPECT_EQ(client_address, dispatcher_->current_peer_address());
835 EXPECT_EQ(server_address_, dispatcher_->current_self_address());
836}
837
838TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
fayangccbab732019-05-13 10:11:25 -0700839 if (CurrentSupportedVersions().front().HasHeaderProtection() ||
840 GetQuicRestartFlag(quic_no_framer_object_in_dispatcher)) {
nharper55fa6132019-05-07 19:37:21 -0700841 // When header protection is in use, we don't put packets in the time wait
842 // list manager based on packet number.
843 return;
844 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500845 CreateTimeWaitListManager();
846 SetQuicRestartFlag(quic_enable_accept_random_ipn, false);
847 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
848 QuicConnectionId connection_id = TestConnectionId(1);
849
850 // Dispatcher forwards this packet for this connection_id to the time wait
851 // list manager.
852 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
853 .Times(0);
854 EXPECT_CALL(*time_wait_list_manager_,
855 ProcessPacket(_, _, TestConnectionId(1), _, _))
856 .Times(1);
857 EXPECT_CALL(*time_wait_list_manager_,
858 ProcessPacket(_, _, TestConnectionId(2), _, _))
859 .Times(1);
860 EXPECT_CALL(*time_wait_list_manager_,
861 AddConnectionIdToTimeWait(_, _, _, _, _))
862 .Times(2);
863 // A packet whose packet number is one to large to be allowed to start a
864 // connection.
865 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
866 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
867 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
868 connection_id = TestConnectionId(2);
869 SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
870 ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
871 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
872 MaxRandomInitialPacketNumber().ToUint64() +
873 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
874}
875
876TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
fayang374888f2019-05-31 06:47:21 -0700877 static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 5u,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500878 "Supported versions out of sync");
879 SetQuicReloadableFlag(quic_disable_version_39, false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500880 SetQuicReloadableFlag(quic_enable_version_46, true);
881 SetQuicReloadableFlag(quic_enable_version_47, true);
882 SetQuicReloadableFlag(quic_enable_version_99, true);
883 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
884 uint64_t conn_id = 1;
885 QuicConnectionId connection_id = TestConnectionId(conn_id);
886
887 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
888 QuicStringPiece("hq"), _))
889 .Times(0);
nharper4fd11052019-06-04 14:23:22 -0700890 ProcessPacket(client_address, connection_id, true,
891 QuicVersionReservedForNegotiation(), SerializeCHLO(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500892 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER, 1);
893 connection_id = TestConnectionId(++conn_id);
894 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
895 QuicStringPiece("hq"), _))
896 .WillOnce(testing::Return(CreateSession(
897 dispatcher_.get(), config_, connection_id, client_address,
898 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
899 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
900 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
901 ProcessUdpPacket(_, _, _))
902 .WillOnce(WithArg<2>(
903 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
904 ValidatePacket(connection_id, packet);
905 })));
906 EXPECT_CALL(*dispatcher_,
907 ShouldCreateOrBufferPacketForConnection(connection_id, _));
908 ProcessPacket(client_address, connection_id, true,
909 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
910 QuicVersionMin().transport_version),
911 SerializeCHLO(), CONNECTION_ID_PRESENT,
912 PACKET_4BYTE_PACKET_NUMBER, 1);
913 connection_id = TestConnectionId(++conn_id);
914 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
915 QuicStringPiece("hq"), _))
916 .WillOnce(testing::Return(CreateSession(
917 dispatcher_.get(), config_, connection_id, client_address,
918 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
919 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
920 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
921 ProcessUdpPacket(_, _, _))
922 .WillOnce(WithArg<2>(
923 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
924 ValidatePacket(connection_id, packet);
925 })));
926 EXPECT_CALL(*dispatcher_,
927 ShouldCreateOrBufferPacketForConnection(connection_id, _));
928 ProcessPacket(client_address, connection_id, true, QuicVersionMax(),
929 SerializeCHLO(), CONNECTION_ID_PRESENT,
930 PACKET_4BYTE_PACKET_NUMBER, 1);
931
932 // Turn off version 47.
933 SetQuicReloadableFlag(quic_enable_version_47, false);
934 connection_id = TestConnectionId(++conn_id);
935 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
936 QuicStringPiece("hq"), _))
937 .Times(0);
938 ProcessPacket(client_address, connection_id, true,
939 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
940 SerializeCHLO(), CONNECTION_ID_PRESENT,
941 PACKET_4BYTE_PACKET_NUMBER, 1);
942
943 // Turn on version 47.
944 SetQuicReloadableFlag(quic_enable_version_47, true);
945 connection_id = TestConnectionId(++conn_id);
946 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
947 QuicStringPiece("hq"), _))
948 .WillOnce(testing::Return(CreateSession(
949 dispatcher_.get(), config_, connection_id, client_address,
950 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
951 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
952 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
953 ProcessUdpPacket(_, _, _))
954 .WillOnce(WithArg<2>(
955 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
956 ValidatePacket(connection_id, packet);
957 })));
958 EXPECT_CALL(*dispatcher_,
959 ShouldCreateOrBufferPacketForConnection(connection_id, _));
960 ProcessPacket(client_address, connection_id, true,
961 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47),
962 SerializeCHLO(), CONNECTION_ID_PRESENT,
963 PACKET_4BYTE_PACKET_NUMBER, 1);
964
965 // Turn off version 46.
966 SetQuicReloadableFlag(quic_enable_version_46, false);
967 connection_id = TestConnectionId(++conn_id);
968 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
969 QuicStringPiece("hq"), _))
970 .Times(0);
971 ProcessPacket(client_address, connection_id, true,
972 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
973 SerializeCHLO(), CONNECTION_ID_PRESENT,
974 PACKET_4BYTE_PACKET_NUMBER, 1);
975
976 // Turn on version 46.
977 SetQuicReloadableFlag(quic_enable_version_46, true);
978 connection_id = TestConnectionId(++conn_id);
979 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
980 QuicStringPiece("hq"), _))
981 .WillOnce(testing::Return(CreateSession(
982 dispatcher_.get(), config_, connection_id, client_address,
983 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
984 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
985 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
986 ProcessUdpPacket(_, _, _))
987 .WillOnce(WithArg<2>(
988 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
989 ValidatePacket(connection_id, packet);
990 })));
991 EXPECT_CALL(*dispatcher_,
992 ShouldCreateOrBufferPacketForConnection(connection_id, _));
993 ProcessPacket(client_address, connection_id, true,
994 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
995 SerializeCHLO(), CONNECTION_ID_PRESENT,
996 PACKET_4BYTE_PACKET_NUMBER, 1);
997
QUICHE teama6ef0a62019-03-07 20:34:33 -0500998 // Turn off version 39.
999 SetQuicReloadableFlag(quic_disable_version_39, true);
1000 connection_id = TestConnectionId(++conn_id);
1001 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1002 QuicStringPiece("hq"), _))
1003 .Times(0);
1004 ProcessPacket(client_address, connection_id, true,
1005 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1006 SerializeCHLO(), CONNECTION_ID_PRESENT,
1007 PACKET_4BYTE_PACKET_NUMBER, 1);
1008
1009 // Turn on version 39.
1010 SetQuicReloadableFlag(quic_disable_version_39, false);
1011 connection_id = TestConnectionId(++conn_id);
1012 EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
1013 QuicStringPiece("hq"), _))
1014 .WillOnce(testing::Return(CreateSession(
1015 dispatcher_.get(), config_, connection_id, client_address,
1016 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1017 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1018 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1019 ProcessUdpPacket(_, _, _))
1020 .WillOnce(WithArg<2>(
1021 Invoke([this, connection_id](const QuicEncryptedPacket& packet) {
1022 ValidatePacket(connection_id, packet);
1023 })));
1024 EXPECT_CALL(*dispatcher_,
1025 ShouldCreateOrBufferPacketForConnection(connection_id, _));
1026 ProcessPacket(client_address, connection_id, true,
1027 ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
1028 SerializeCHLO(), CONNECTION_ID_PRESENT,
1029 PACKET_4BYTE_PACKET_NUMBER, 1);
1030}
1031
1032// Enables mocking of the handshake-confirmation for stateless rejects.
1033class MockQuicCryptoServerStream : public QuicCryptoServerStream {
1034 public:
1035 MockQuicCryptoServerStream(const QuicCryptoServerConfig& crypto_config,
1036 QuicCompressedCertsCache* compressed_certs_cache,
1037 QuicServerSessionBase* session,
1038 QuicCryptoServerStream::Helper* helper)
wubd893df12019-05-15 18:48:20 -07001039 : QuicCryptoServerStream(&crypto_config,
1040 compressed_certs_cache,
1041 session,
1042 helper),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001043 handshake_confirmed_(false) {}
1044 MockQuicCryptoServerStream(const MockQuicCryptoServerStream&) = delete;
1045 MockQuicCryptoServerStream& operator=(const MockQuicCryptoServerStream&) =
1046 delete;
1047
1048 void set_handshake_confirmed_for_testing(bool handshake_confirmed) {
1049 handshake_confirmed_ = handshake_confirmed;
1050 }
1051
1052 bool handshake_confirmed() const override { return handshake_confirmed_; }
1053
1054 private:
1055 bool handshake_confirmed_;
1056};
1057
QUICHE teama6ef0a62019-03-07 20:34:33 -05001058// Verify the stopgap test: Packets with truncated connection IDs should be
1059// dropped.
1060class QuicDispatcherTestStrayPacketConnectionId : public QuicDispatcherTest {};
1061
1062// Packets with truncated connection IDs should be dropped.
1063TEST_F(QuicDispatcherTestStrayPacketConnectionId,
1064 StrayPacketTruncatedConnectionId) {
1065 CreateTimeWaitListManager();
1066
1067 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1068 QuicConnectionId connection_id = TestConnectionId(1);
1069 EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, QuicStringPiece("hq"), _))
1070 .Times(0);
fayangd4291e42019-05-30 10:31:21 -07001071 if (VersionHasIetfInvariantHeader(
1072 CurrentSupportedVersions()[0].transport_version) &&
QUICHE team963d57e2019-03-21 10:58:47 -07001073 !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
1074 CurrentSupportedVersions()[0].transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001075 // This IETF packet has invalid connection ID length.
1076 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1077 .Times(0);
1078 EXPECT_CALL(*time_wait_list_manager_,
1079 AddConnectionIdToTimeWait(_, _, _, _, _))
1080 .Times(0);
1081 } else {
QUICHE team8e2e4532019-03-14 14:37:56 -07001082 // This is either:
1083 // - a GQUIC packet considered as IETF QUIC packet with short header
1084 // with unacceptable packet number or
1085 // - an IETF QUIC packet with bad connection ID length which is rejected.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001086 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _))
1087 .Times(1);
1088 EXPECT_CALL(*time_wait_list_manager_,
1089 AddConnectionIdToTimeWait(_, _, _, _, _))
1090 .Times(1);
1091 }
1092 ProcessPacket(client_address, connection_id, true, "data",
1093 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER);
1094}
1095
1096class BlockingWriter : public QuicPacketWriterWrapper {
1097 public:
1098 BlockingWriter() : write_blocked_(false) {}
1099
1100 bool IsWriteBlocked() const override { return write_blocked_; }
1101 void SetWritable() override { write_blocked_ = false; }
1102
1103 WriteResult WritePacket(const char* buffer,
1104 size_t buf_len,
1105 const QuicIpAddress& self_client_address,
1106 const QuicSocketAddress& peer_client_address,
1107 PerPacketOptions* options) override {
1108 // It would be quite possible to actually implement this method here with
1109 // the fake blocked status, but it would be significantly more work in
1110 // Chromium, and since it's not called anyway, don't bother.
1111 QUIC_LOG(DFATAL) << "Not supported";
1112 return WriteResult();
1113 }
1114
1115 bool write_blocked_;
1116};
1117
1118class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest {
1119 public:
1120 void SetUp() override {
1121 QuicDispatcherTest::SetUp();
1122 writer_ = new BlockingWriter;
1123 QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_);
1124
1125 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1126
1127 EXPECT_CALL(*dispatcher_,
1128 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1129 .WillOnce(testing::Return(CreateSession(
1130 dispatcher_.get(), config_, TestConnectionId(1), client_address,
1131 &helper_, &alarm_factory_, &crypto_config_,
1132 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1133 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1134 ProcessUdpPacket(_, _, _))
1135 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1136 ValidatePacket(TestConnectionId(1), packet);
1137 })));
1138 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1139 TestConnectionId(1), _));
1140 ProcessPacket(client_address, TestConnectionId(1), true, SerializeCHLO());
1141
1142 EXPECT_CALL(*dispatcher_,
1143 CreateQuicSession(_, client_address, QuicStringPiece("hq"), _))
1144 .WillOnce(testing::Return(CreateSession(
1145 dispatcher_.get(), config_, TestConnectionId(2), client_address,
1146 &helper_, &alarm_factory_, &crypto_config_,
1147 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_)));
1148 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()),
1149 ProcessUdpPacket(_, _, _))
1150 .WillOnce(WithArg<2>(Invoke([this](const QuicEncryptedPacket& packet) {
1151 ValidatePacket(TestConnectionId(2), packet);
1152 })));
1153 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1154 TestConnectionId(2), _));
1155 ProcessPacket(client_address, TestConnectionId(2), true, SerializeCHLO());
1156
1157 blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get());
1158 }
1159
1160 void TearDown() override {
1161 if (connection1() != nullptr) {
1162 EXPECT_CALL(*connection1(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1163 }
1164
1165 if (connection2() != nullptr) {
1166 EXPECT_CALL(*connection2(), CloseConnection(QUIC_PEER_GOING_AWAY, _, _));
1167 }
1168 dispatcher_->Shutdown();
1169 }
1170
1171 // Set the dispatcher's writer to be blocked. By default, all connections use
1172 // the same writer as the dispatcher in this test.
1173 void SetBlocked() {
1174 QUIC_LOG(INFO) << "set writer " << writer_ << " to blocked";
1175 writer_->write_blocked_ = true;
1176 }
1177
1178 // Simulate what happens when connection1 gets blocked when writing.
1179 void BlockConnection1() {
1180 Connection1Writer()->write_blocked_ = true;
1181 dispatcher_->OnWriteBlocked(connection1());
1182 }
1183
1184 BlockingWriter* Connection1Writer() {
1185 return static_cast<BlockingWriter*>(connection1()->writer());
1186 }
1187
1188 // Simulate what happens when connection2 gets blocked when writing.
1189 void BlockConnection2() {
1190 Connection2Writer()->write_blocked_ = true;
1191 dispatcher_->OnWriteBlocked(connection2());
1192 }
1193
1194 BlockingWriter* Connection2Writer() {
1195 return static_cast<BlockingWriter*>(connection2()->writer());
1196 }
1197
1198 protected:
1199 MockQuicConnectionHelper helper_;
1200 MockAlarmFactory alarm_factory_;
1201 BlockingWriter* writer_;
1202 QuicDispatcher::WriteBlockedList* blocked_list_;
1203};
1204
1205TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) {
1206 // No OnCanWrite calls because no connections are blocked.
1207 dispatcher_->OnCanWrite();
1208
1209 // Register connection 1 for events, and make sure it's notified.
1210 SetBlocked();
1211 dispatcher_->OnWriteBlocked(connection1());
1212 EXPECT_CALL(*connection1(), OnCanWrite());
1213 dispatcher_->OnCanWrite();
1214
1215 // It should get only one notification.
1216 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1217 dispatcher_->OnCanWrite();
1218 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1219}
1220
1221TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) {
1222 // Make sure we handle events in order.
1223 InSequence s;
1224 SetBlocked();
1225 dispatcher_->OnWriteBlocked(connection1());
1226 dispatcher_->OnWriteBlocked(connection2());
1227 EXPECT_CALL(*connection1(), OnCanWrite());
1228 EXPECT_CALL(*connection2(), OnCanWrite());
1229 dispatcher_->OnCanWrite();
1230
1231 // Check the other ordering.
1232 SetBlocked();
1233 dispatcher_->OnWriteBlocked(connection2());
1234 dispatcher_->OnWriteBlocked(connection1());
1235 EXPECT_CALL(*connection2(), OnCanWrite());
1236 EXPECT_CALL(*connection1(), OnCanWrite());
1237 dispatcher_->OnCanWrite();
1238}
1239
1240TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) {
1241 // Add and remove one connction.
1242 SetBlocked();
1243 dispatcher_->OnWriteBlocked(connection1());
1244 blocked_list_->erase(connection1());
1245 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1246 dispatcher_->OnCanWrite();
1247
1248 // Add and remove one connction and make sure it doesn't affect others.
1249 SetBlocked();
1250 dispatcher_->OnWriteBlocked(connection1());
1251 dispatcher_->OnWriteBlocked(connection2());
1252 blocked_list_->erase(connection1());
1253 EXPECT_CALL(*connection2(), OnCanWrite());
1254 dispatcher_->OnCanWrite();
1255
1256 // Add it, remove it, and add it back and make sure things are OK.
1257 SetBlocked();
1258 dispatcher_->OnWriteBlocked(connection1());
1259 blocked_list_->erase(connection1());
1260 dispatcher_->OnWriteBlocked(connection1());
1261 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1262 dispatcher_->OnCanWrite();
1263}
1264
1265TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) {
1266 // Make sure a double add does not necessitate a double remove.
1267 SetBlocked();
1268 dispatcher_->OnWriteBlocked(connection1());
1269 dispatcher_->OnWriteBlocked(connection1());
1270 blocked_list_->erase(connection1());
1271 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1272 dispatcher_->OnCanWrite();
1273
1274 // Make sure a double add does not result in two OnCanWrite calls.
1275 SetBlocked();
1276 dispatcher_->OnWriteBlocked(connection1());
1277 dispatcher_->OnWriteBlocked(connection1());
1278 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1);
1279 dispatcher_->OnCanWrite();
1280}
1281
1282TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection1) {
1283 // If the 1st blocked writer gets blocked in OnCanWrite, it will be added back
1284 // into the write blocked list.
1285 InSequence s;
1286 SetBlocked();
1287 dispatcher_->OnWriteBlocked(connection1());
1288 dispatcher_->OnWriteBlocked(connection2());
1289 EXPECT_CALL(*connection1(), OnCanWrite())
1290 .WillOnce(
1291 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1292 EXPECT_CALL(*connection2(), OnCanWrite());
1293 dispatcher_->OnCanWrite();
1294
1295 // connection1 should be still in the write blocked list.
1296 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1297
1298 // Now call OnCanWrite again, connection1 should get its second chance.
1299 EXPECT_CALL(*connection1(), OnCanWrite());
1300 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0);
1301 dispatcher_->OnCanWrite();
1302 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1303}
1304
1305TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlockConnection2) {
1306 // If the 2nd blocked writer gets blocked in OnCanWrite, it will be added back
1307 // into the write blocked list.
1308 InSequence s;
1309 SetBlocked();
1310 dispatcher_->OnWriteBlocked(connection1());
1311 dispatcher_->OnWriteBlocked(connection2());
1312 EXPECT_CALL(*connection1(), OnCanWrite());
1313 EXPECT_CALL(*connection2(), OnCanWrite())
1314 .WillOnce(
1315 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1316 dispatcher_->OnCanWrite();
1317
1318 // connection2 should be still in the write blocked list.
1319 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1320
1321 // Now call OnCanWrite again, connection2 should get its second chance.
1322 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0);
1323 EXPECT_CALL(*connection2(), OnCanWrite());
1324 dispatcher_->OnCanWrite();
1325 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1326}
1327
1328TEST_F(QuicDispatcherWriteBlockedListTest,
1329 OnCanWriteHandleBlockBothConnections) {
1330 // Both connections get blocked in OnCanWrite, and added back into the write
1331 // blocked list.
1332 InSequence s;
1333 SetBlocked();
1334 dispatcher_->OnWriteBlocked(connection1());
1335 dispatcher_->OnWriteBlocked(connection2());
1336 EXPECT_CALL(*connection1(), OnCanWrite())
1337 .WillOnce(
1338 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection1));
1339 EXPECT_CALL(*connection2(), OnCanWrite())
1340 .WillOnce(
1341 Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2));
1342 dispatcher_->OnCanWrite();
1343
1344 // Both connections should be still in the write blocked list.
1345 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1346
1347 // Now call OnCanWrite again, both connections should get its second chance.
1348 EXPECT_CALL(*connection1(), OnCanWrite());
1349 EXPECT_CALL(*connection2(), OnCanWrite());
1350 dispatcher_->OnCanWrite();
1351 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1352}
1353
1354TEST_F(QuicDispatcherWriteBlockedListTest, PerConnectionWriterBlocked) {
1355 // By default, all connections share the same packet writer with the
1356 // dispatcher.
1357 EXPECT_EQ(dispatcher_->writer(), connection1()->writer());
1358 EXPECT_EQ(dispatcher_->writer(), connection2()->writer());
1359
1360 // Test the case where connection1 shares the same packet writer as the
1361 // dispatcher, whereas connection2 owns it's packet writer.
1362 // Change connection2's writer.
1363 connection2()->SetQuicPacketWriter(new BlockingWriter, /*owns_writer=*/true);
1364 EXPECT_NE(dispatcher_->writer(), connection2()->writer());
1365
1366 BlockConnection2();
1367 EXPECT_TRUE(dispatcher_->HasPendingWrites());
1368
1369 EXPECT_CALL(*connection2(), OnCanWrite());
1370 dispatcher_->OnCanWrite();
1371 EXPECT_FALSE(dispatcher_->HasPendingWrites());
1372}
1373
1374TEST_F(QuicDispatcherWriteBlockedListTest,
1375 RemoveConnectionFromWriteBlockedListWhenDeletingSessions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001376 dispatcher_->OnConnectionClosed(connection1()->connection_id(),
1377 QUIC_PACKET_WRITE_ERROR, "Closed by test.",
1378 ConnectionCloseSource::FROM_SELF);
1379
1380 SetBlocked();
1381
1382 ASSERT_FALSE(dispatcher_->HasPendingWrites());
1383 SetBlocked();
1384 dispatcher_->OnWriteBlocked(connection1());
1385 ASSERT_TRUE(dispatcher_->HasPendingWrites());
1386
1387 EXPECT_QUIC_BUG(dispatcher_->DeleteSessions(),
1388 "QuicConnection was in WriteBlockedList before destruction");
1389 MarkSession1Deleted();
1390}
1391
QUICHE teama6ef0a62019-03-07 20:34:33 -05001392// A dispatcher whose stateless rejector will always ACCEPTs CHLO.
wub0a4b9c52019-05-28 13:18:58 -07001393class BufferedPacketStoreTest : public QuicDispatcherTest {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001394 public:
1395 BufferedPacketStoreTest()
1396 : QuicDispatcherTest(),
1397 server_addr_(QuicSocketAddress(QuicIpAddress::Any4(), 5)),
1398 client_addr_(QuicIpAddress::Loopback4(), 1234),
wub0a4b9c52019-05-28 13:18:58 -07001399 signed_config_(new QuicSignedServerConfig) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -05001400
1401 void SetUp() override {
1402 QuicDispatcherTest::SetUp();
1403 clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock();
1404
1405 QuicTransportVersion version = AllSupportedTransportVersions().front();
1406 CryptoHandshakeMessage chlo =
1407 crypto_test_utils::GenerateDefaultInchoateCHLO(clock_, version,
1408 &crypto_config_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001409 // Pass an inchoate CHLO.
1410 crypto_test_utils::GenerateFullCHLO(
1411 chlo, &crypto_config_, server_addr_, client_addr_, version, clock_,
1412 signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1413 &full_chlo_);
1414 }
1415
vasilvvc48c8712019-03-11 13:38:16 -07001416 std::string SerializeFullCHLO() {
1417 return std::string(full_chlo_.GetSerialized().AsStringPiece());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001418 }
1419
1420 protected:
1421 QuicSocketAddress server_addr_;
1422 QuicSocketAddress client_addr_;
1423 QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
1424 const QuicClock* clock_;
1425 CryptoHandshakeMessage full_chlo_;
1426};
1427
wub0a4b9c52019-05-28 13:18:58 -07001428TEST_F(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001429 InSequence s;
1430 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1431 QuicConnectionId conn_id = TestConnectionId(1);
1432 // A bunch of non-CHLO should be buffered upon arrival, and the first one
1433 // should trigger ShouldCreateOrBufferPacketForConnection().
1434 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id, _))
1435 .Times(1);
1436 for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
1437 ProcessPacket(client_address, conn_id, true,
1438 QuicStrCat("data packet ", i + 1), CONNECTION_ID_PRESENT,
1439 PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
1440 }
1441 EXPECT_EQ(0u, dispatcher_->session_map().size())
1442 << "No session should be created before CHLO arrives.";
1443
1444 // Pop out the last packet as it is also be dropped by the store.
1445 data_connection_map_[conn_id].pop_back();
1446 // When CHLO arrives, a new session should be created, and all packets
1447 // buffered should be delivered to the session.
1448 EXPECT_CALL(*dispatcher_,
1449 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1450 .WillOnce(testing::Return(CreateSession(
1451 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1452 &mock_alarm_factory_, &crypto_config_,
1453 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1454
1455 // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they
1456 // should be delivered in arrival order.
1457 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1458 ProcessUdpPacket(_, _, _))
1459 .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO.
1460 .WillRepeatedly(
1461 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1462 ValidatePacket(conn_id, packet);
1463 })));
1464 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1465}
1466
wub0a4b9c52019-05-28 13:18:58 -07001467TEST_F(BufferedPacketStoreTest,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001468 ProcessNonChloPacketsForDifferentConnectionsUptoLimit) {
1469 InSequence s;
1470 // A bunch of non-CHLO should be buffered upon arrival.
1471 size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
1472 for (size_t i = 1; i <= kNumConnections; ++i) {
1473 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1474 QuicConnectionId conn_id = TestConnectionId(i);
1475 EXPECT_CALL(*dispatcher_,
1476 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1477 ProcessPacket(client_address, conn_id, true,
1478 QuicStrCat("data packet on connection ", i),
1479 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1480 /*packet_number=*/2);
1481 }
1482
1483 // Pop out the packet on last connection as it shouldn't be enqueued in store
1484 // as well.
1485 data_connection_map_[TestConnectionId(kNumConnections)].pop_front();
1486
1487 // Reset session creation counter to ensure processing CHLO can always
1488 // create session.
1489 QuicDispatcherPeer::set_new_sessions_allowed_per_event_loop(dispatcher_.get(),
1490 kNumConnections);
1491 // Process CHLOs to create session for these connections.
1492 for (size_t i = 1; i <= kNumConnections; ++i) {
1493 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), i);
1494 QuicConnectionId conn_id = TestConnectionId(i);
1495 if (i == kNumConnections) {
1496 EXPECT_CALL(*dispatcher_,
1497 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1498 }
1499 EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address,
1500 QuicStringPiece(), _))
1501 .WillOnce(testing::Return(CreateSession(
1502 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1503 &mock_alarm_factory_, &crypto_config_,
1504 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1505 // First |kNumConnections| - 1 connections should have buffered
1506 // a packet in store. The rest should have been dropped.
1507 size_t num_packet_to_process = i <= kMaxConnectionsWithoutCHLO ? 2u : 1u;
1508 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1509 ProcessUdpPacket(_, client_address, _))
1510 .Times(num_packet_to_process)
1511 .WillRepeatedly(WithArg<2>(
1512 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1513 ValidatePacket(conn_id, packet);
1514 })));
1515
1516 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1517 }
1518}
1519
1520// Tests that store delivers empty packet list if CHLO arrives firstly.
wub0a4b9c52019-05-28 13:18:58 -07001521TEST_F(BufferedPacketStoreTest, DeliverEmptyPackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001522 QuicConnectionId conn_id = TestConnectionId(1);
1523 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1524 EXPECT_CALL(*dispatcher_,
1525 ShouldCreateOrBufferPacketForConnection(conn_id, _));
1526 EXPECT_CALL(*dispatcher_,
1527 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1528 .WillOnce(testing::Return(CreateSession(
1529 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1530 &mock_alarm_factory_, &crypto_config_,
1531 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1532 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1533 ProcessUdpPacket(_, client_address, _));
1534 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1535}
1536
1537// Tests that a retransmitted CHLO arrives after a connection for the
1538// CHLO has been created.
wub0a4b9c52019-05-28 13:18:58 -07001539TEST_F(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001540 InSequence s;
1541 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1542 QuicConnectionId conn_id = TestConnectionId(1);
1543 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1544 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1545 /*packet_number=*/2);
1546
1547 // When CHLO arrives, a new session should be created, and all packets
1548 // buffered should be delivered to the session.
1549 EXPECT_CALL(*dispatcher_,
1550 CreateQuicSession(conn_id, client_address, QuicStringPiece(), _))
1551 .Times(1) // Only triggered by 1st CHLO.
1552 .WillOnce(testing::Return(CreateSession(
1553 dispatcher_.get(), config_, conn_id, client_address, &mock_helper_,
1554 &mock_alarm_factory_, &crypto_config_,
1555 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1556 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1557 ProcessUdpPacket(_, _, _))
1558 .Times(3) // Triggered by 1 data packet and 2 CHLOs.
1559 .WillRepeatedly(
1560 WithArg<2>(Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1561 ValidatePacket(conn_id, packet);
1562 })));
1563 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1564
1565 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1566}
1567
1568// Tests that expiration of a connection add connection id to time wait list.
wub0a4b9c52019-05-28 13:18:58 -07001569TEST_F(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001570 InSequence s;
1571 CreateTimeWaitListManager();
1572 QuicBufferedPacketStore* store =
1573 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1574 QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock());
1575
1576 QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
1577 QuicConnectionId conn_id = TestConnectionId(1);
1578 ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
1579 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1580 /*packet_number=*/2);
1581
1582 mock_helper_.AdvanceTime(
1583 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
1584 QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store);
1585 // Cancel alarm as if it had been fired.
1586 alarm->Cancel();
1587 store->OnExpirationTimeout();
1588 // New arrived CHLO will be dropped because this connection is in time wait
1589 // list.
1590 ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id));
1591 EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _));
1592 ProcessPacket(client_address, conn_id, true, SerializeFullCHLO());
1593}
1594
wub0a4b9c52019-05-28 13:18:58 -07001595TEST_F(BufferedPacketStoreTest, ProcessCHLOsUptoLimitAndBufferTheRest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001596 // Process more than (|kMaxNumSessionsToCreate| +
1597 // |kDefaultMaxConnectionsInStore|) CHLOs,
1598 // the first |kMaxNumSessionsToCreate| should create connections immediately,
1599 // the next |kDefaultMaxConnectionsInStore| should be buffered,
1600 // the rest should be dropped.
1601 QuicBufferedPacketStore* store =
1602 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1603 const size_t kNumCHLOs =
1604 kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore + 1;
1605 for (uint64_t conn_id = 1; conn_id <= kNumCHLOs; ++conn_id) {
1606 EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(
1607 TestConnectionId(conn_id), _));
1608 if (conn_id <= kMaxNumSessionsToCreate) {
1609 EXPECT_CALL(*dispatcher_,
1610 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1611 QuicStringPiece(), _))
1612 .WillOnce(testing::Return(CreateSession(
1613 dispatcher_.get(), config_, TestConnectionId(conn_id),
1614 client_addr_, &mock_helper_, &mock_alarm_factory_,
1615 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1616 &session1_)));
1617 EXPECT_CALL(
1618 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1619 ProcessUdpPacket(_, _, _))
1620 .WillOnce(WithArg<2>(
1621 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1622 ValidatePacket(TestConnectionId(conn_id), packet);
1623 })));
1624 }
1625 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1626 SerializeFullCHLO());
1627 if (conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore &&
1628 conn_id > kMaxNumSessionsToCreate) {
1629 EXPECT_TRUE(store->HasChloForConnection(TestConnectionId(conn_id)));
1630 } else {
1631 // First |kMaxNumSessionsToCreate| CHLOs should be passed to new
1632 // connections immediately, and the last CHLO should be dropped as the
1633 // store is full.
1634 EXPECT_FALSE(store->HasChloForConnection(TestConnectionId(conn_id)));
1635 }
1636 }
1637
1638 // Graduately consume buffered CHLOs. The buffered connections should be
1639 // created but the dropped one shouldn't.
1640 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
1641 conn_id <= kMaxNumSessionsToCreate + kDefaultMaxConnectionsInStore;
1642 ++conn_id) {
1643 EXPECT_CALL(*dispatcher_,
1644 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1645 QuicStringPiece(), _))
1646 .WillOnce(testing::Return(CreateSession(
1647 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
1648 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1649 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1650 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1651 ProcessUdpPacket(_, _, _))
1652 .WillOnce(WithArg<2>(
1653 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1654 ValidatePacket(TestConnectionId(conn_id), packet);
1655 })));
1656 }
1657 EXPECT_CALL(*dispatcher_,
1658 CreateQuicSession(TestConnectionId(kNumCHLOs), client_addr_,
1659 QuicStringPiece(), _))
1660 .Times(0);
1661
1662 while (store->HasChlosBuffered()) {
1663 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
1664 }
1665
1666 EXPECT_EQ(TestConnectionId(static_cast<size_t>(kMaxNumSessionsToCreate) +
1667 kDefaultMaxConnectionsInStore),
1668 session1_->connection_id());
1669}
1670
1671// Duplicated CHLO shouldn't be buffered.
wub0a4b9c52019-05-28 13:18:58 -07001672TEST_F(BufferedPacketStoreTest, BufferDuplicatedCHLO) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001673 for (uint64_t conn_id = 1; conn_id <= kMaxNumSessionsToCreate + 1;
1674 ++conn_id) {
1675 // Last CHLO will be buffered. Others will create connection right away.
1676 if (conn_id <= kMaxNumSessionsToCreate) {
1677 EXPECT_CALL(*dispatcher_,
1678 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1679 QuicStringPiece(), _))
1680 .WillOnce(testing::Return(CreateSession(
1681 dispatcher_.get(), config_, TestConnectionId(conn_id),
1682 client_addr_, &mock_helper_, &mock_alarm_factory_,
1683 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1684 &session1_)));
1685 EXPECT_CALL(
1686 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1687 ProcessUdpPacket(_, _, _))
1688 .WillOnce(WithArg<2>(
1689 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1690 ValidatePacket(TestConnectionId(conn_id), packet);
1691 })));
1692 }
1693 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1694 SerializeFullCHLO());
1695 }
1696 // Retransmit CHLO on last connection should be dropped.
1697 QuicConnectionId last_connection =
1698 TestConnectionId(kMaxNumSessionsToCreate + 1);
1699 ProcessPacket(client_addr_, last_connection, true, SerializeFullCHLO());
1700
1701 size_t packets_buffered = 2;
1702
1703 // Reset counter and process buffered CHLO.
1704 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection, client_addr_,
1705 QuicStringPiece(), _))
1706 .WillOnce(testing::Return(CreateSession(
1707 dispatcher_.get(), config_, last_connection, client_addr_,
1708 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1709 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1710 // Only one packet(CHLO) should be process.
1711 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1712 ProcessUdpPacket(_, _, _))
1713 .Times(packets_buffered)
1714 .WillRepeatedly(WithArg<2>(
1715 Invoke([this, last_connection](const QuicEncryptedPacket& packet) {
1716 ValidatePacket(last_connection, packet);
1717 })));
1718 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
1719}
1720
wub0a4b9c52019-05-28 13:18:58 -07001721TEST_F(BufferedPacketStoreTest, BufferNonChloPacketsUptoLimitWithChloBuffered) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001722 uint64_t last_conn_id = kMaxNumSessionsToCreate + 1;
1723 QuicConnectionId last_connection_id = TestConnectionId(last_conn_id);
1724 for (uint64_t conn_id = 1; conn_id <= last_conn_id; ++conn_id) {
1725 // Last CHLO will be buffered. Others will create connection right away.
1726 if (conn_id <= kMaxNumSessionsToCreate) {
1727 EXPECT_CALL(*dispatcher_,
1728 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1729 QuicStringPiece(), _))
1730 .WillOnce(testing::Return(CreateSession(
1731 dispatcher_.get(), config_, TestConnectionId(conn_id),
1732 client_addr_, &mock_helper_, &mock_alarm_factory_,
1733 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1734 &session1_)));
1735 EXPECT_CALL(
1736 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1737 ProcessUdpPacket(_, _, _))
1738 .WillRepeatedly(WithArg<2>(
1739 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1740 ValidatePacket(TestConnectionId(conn_id), packet);
1741 })));
1742 }
1743 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1744 SerializeFullCHLO());
1745 }
1746
1747 // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
1748 // last one should be dropped.
1749 for (uint64_t packet_number = 2;
1750 packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
1751 ProcessPacket(client_addr_, last_connection_id, true, "data packet");
1752 }
1753
1754 // Reset counter and process buffered CHLO.
1755 EXPECT_CALL(*dispatcher_, CreateQuicSession(last_connection_id, client_addr_,
1756 QuicStringPiece(), _))
1757 .WillOnce(testing::Return(CreateSession(
1758 dispatcher_.get(), config_, last_connection_id, client_addr_,
1759 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1760 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1761 // Only CHLO and following |kDefaultMaxUndecryptablePackets| data packets
1762 // should be process.
1763 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1764 ProcessUdpPacket(_, _, _))
1765 .Times(kDefaultMaxUndecryptablePackets + 1)
1766 .WillRepeatedly(WithArg<2>(
1767 Invoke([this, last_connection_id](const QuicEncryptedPacket& packet) {
1768 ValidatePacket(last_connection_id, packet);
1769 })));
1770 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
1771}
1772
1773// Tests that when dispatcher's packet buffer is full, a CHLO on connection
1774// which doesn't have buffered CHLO should be buffered.
wub0a4b9c52019-05-28 13:18:58 -07001775TEST_F(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001776 QuicBufferedPacketStore* store =
1777 QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get());
1778
1779 uint64_t conn_id = 1;
1780 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, "data packet",
1781 CONNECTION_ID_PRESENT, PACKET_4BYTE_PACKET_NUMBER,
1782 /*packet_number=*/1);
1783 // Fill packet buffer to full with CHLOs on other connections. Need to feed
1784 // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
1785 // session directly.
1786 for (conn_id = 2;
1787 conn_id <= kDefaultMaxConnectionsInStore + kMaxNumSessionsToCreate;
1788 ++conn_id) {
1789 if (conn_id <= kMaxNumSessionsToCreate + 1) {
1790 EXPECT_CALL(*dispatcher_,
1791 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1792 QuicStringPiece(), _))
1793 .WillOnce(testing::Return(CreateSession(
1794 dispatcher_.get(), config_, TestConnectionId(conn_id),
1795 client_addr_, &mock_helper_, &mock_alarm_factory_,
1796 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1797 &session1_)));
1798 EXPECT_CALL(
1799 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1800 ProcessUdpPacket(_, _, _))
1801 .WillOnce(WithArg<2>(
1802 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1803 ValidatePacket(TestConnectionId(conn_id), packet);
1804 })));
1805 }
1806 ProcessPacket(client_addr_, TestConnectionId(conn_id), true,
1807 SerializeFullCHLO());
1808 }
1809 EXPECT_FALSE(store->HasChloForConnection(
1810 /*connection_id=*/TestConnectionId(1)));
1811
1812 // CHLO on connection 1 should still be buffered.
1813 ProcessPacket(client_addr_, /*connection_id=*/TestConnectionId(1), true,
1814 SerializeFullCHLO());
1815 EXPECT_TRUE(store->HasChloForConnection(
1816 /*connection_id=*/TestConnectionId(1)));
1817}
1818
1819// Regression test for b/117874922.
wub0a4b9c52019-05-28 13:18:58 -07001820TEST_F(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001821 // Turn off version 99, such that the preferred version is not supported by
1822 // the server.
1823 SetQuicReloadableFlag(quic_enable_version_99, false);
1824 uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
1825 ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
1826 for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
1827 // Last 5 CHLOs will be buffered. Others will create connection right away.
1828 ParsedQuicVersion version =
1829 supported_versions[(conn_id - 1) % supported_versions.size()];
1830 if (conn_id <= kMaxNumSessionsToCreate) {
1831 EXPECT_CALL(*dispatcher_,
1832 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1833 QuicStringPiece(), version))
1834 .WillOnce(testing::Return(CreateSession(
1835 dispatcher_.get(), config_, TestConnectionId(conn_id),
1836 client_addr_, &mock_helper_, &mock_alarm_factory_,
1837 &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
1838 &session1_)));
1839 EXPECT_CALL(
1840 *reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1841 ProcessUdpPacket(_, _, _))
1842 .WillRepeatedly(WithArg<2>(
1843 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1844 ValidatePacket(TestConnectionId(conn_id), packet);
1845 })));
1846 }
1847 ProcessPacket(client_addr_, TestConnectionId(conn_id), true, version,
1848 SerializeFullCHLO(), CONNECTION_ID_PRESENT,
1849 PACKET_4BYTE_PACKET_NUMBER, 1);
1850 }
1851
1852 // Process buffered CHLOs. Verify the version is correct.
1853 for (uint64_t conn_id = kMaxNumSessionsToCreate + 1;
1854 conn_id <= last_connection_id; ++conn_id) {
1855 ParsedQuicVersion version =
1856 supported_versions[(conn_id - 1) % supported_versions.size()];
1857 EXPECT_CALL(*dispatcher_,
1858 CreateQuicSession(TestConnectionId(conn_id), client_addr_,
1859 QuicStringPiece(), version))
1860 .WillOnce(testing::Return(CreateSession(
1861 dispatcher_.get(), config_, TestConnectionId(conn_id), client_addr_,
1862 &mock_helper_, &mock_alarm_factory_, &crypto_config_,
1863 QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_)));
1864 EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()),
1865 ProcessUdpPacket(_, _, _))
1866 .WillRepeatedly(WithArg<2>(
1867 Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
1868 ValidatePacket(TestConnectionId(conn_id), packet);
1869 })));
1870 }
1871 dispatcher_->ProcessBufferedChlos(kMaxNumSessionsToCreate);
1872}
1873
QUICHE teama6ef0a62019-03-07 20:34:33 -05001874} // namespace
1875} // namespace test
1876} // namespace quic