1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_time_wait_list_manager.h"
6
7 #include <cerrno>
8 #include <memory>
9 #include <ostream>
10 #include <utility>
11
12 #include "quiche/quic/core/crypto/crypto_protocol.h"
13 #include "quiche/quic/core/crypto/null_encrypter.h"
14 #include "quiche/quic/core/crypto/quic_decrypter.h"
15 #include "quiche/quic/core/crypto/quic_encrypter.h"
16 #include "quiche/quic/core/quic_connection_id.h"
17 #include "quiche/quic/core/quic_data_reader.h"
18 #include "quiche/quic/core/quic_framer.h"
19 #include "quiche/quic/core/quic_packet_writer.h"
20 #include "quiche/quic/core/quic_packets.h"
21 #include "quiche/quic/core/quic_utils.h"
22 #include "quiche/quic/platform/api/quic_expect_bug.h"
23 #include "quiche/quic/platform/api/quic_flags.h"
24 #include "quiche/quic/platform/api/quic_test.h"
25 #include "quiche/quic/test_tools/mock_quic_session_visitor.h"
26 #include "quiche/quic/test_tools/quic_test_utils.h"
27 #include "quiche/quic/test_tools/quic_time_wait_list_manager_peer.h"
28
29 using testing::_;
30 using testing::Args;
31 using testing::Assign;
32 using testing::DoAll;
33 using testing::Matcher;
34 using testing::NiceMock;
35 using testing::Return;
36 using testing::ReturnPointee;
37 using testing::StrictMock;
38 using testing::Truly;
39
40 namespace quic {
41 namespace test {
42 namespace {
43
44 const size_t kTestPacketSize = 100;
45
46 class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
47 public:
FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)48 FramerVisitorCapturingPublicReset(QuicConnectionId connection_id)
49 : connection_id_(connection_id) {}
50 ~FramerVisitorCapturingPublicReset() override = default;
51
IsValidStatelessResetToken(const StatelessResetToken & token) const52 bool IsValidStatelessResetToken(
53 const StatelessResetToken& token) const override {
54 return token == QuicUtils::GenerateStatelessResetToken(connection_id_);
55 }
56
OnAuthenticatedIetfStatelessResetPacket(const QuicIetfStatelessResetPacket & packet)57 void OnAuthenticatedIetfStatelessResetPacket(
58 const QuicIetfStatelessResetPacket& packet) override {
59 stateless_reset_packet_ = packet;
60 }
61
stateless_reset_packet()62 const QuicIetfStatelessResetPacket stateless_reset_packet() {
63 return stateless_reset_packet_;
64 }
65
66 private:
67 QuicIetfStatelessResetPacket stateless_reset_packet_;
68 QuicConnectionId connection_id_;
69 };
70
71 class MockAlarmFactory;
72 class MockAlarm : public QuicAlarm {
73 public:
MockAlarm(QuicArenaScopedPtr<Delegate> delegate,int alarm_index,MockAlarmFactory * factory)74 explicit MockAlarm(QuicArenaScopedPtr<Delegate> delegate, int alarm_index,
75 MockAlarmFactory* factory)
76 : QuicAlarm(std::move(delegate)),
77 alarm_index_(alarm_index),
78 factory_(factory) {}
~MockAlarm()79 virtual ~MockAlarm() {}
80
81 void SetImpl() override;
82 void CancelImpl() override;
83
84 private:
85 int alarm_index_;
86 MockAlarmFactory* factory_;
87 };
88
89 class MockAlarmFactory : public QuicAlarmFactory {
90 public:
~MockAlarmFactory()91 ~MockAlarmFactory() override {}
92
93 // Creates a new platform-specific alarm which will be configured to notify
94 // |delegate| when the alarm fires. Returns an alarm allocated on the heap.
95 // Caller takes ownership of the new alarm, which will not yet be "set" to
96 // fire.
CreateAlarm(QuicAlarm::Delegate * delegate)97 QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override {
98 return new MockAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate),
99 alarm_index_++, this);
100 }
CreateAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,QuicConnectionArena * arena)101 QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
102 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
103 QuicConnectionArena* arena) override {
104 if (arena != nullptr) {
105 return arena->New<MockAlarm>(std::move(delegate), alarm_index_++, this);
106 }
107 return QuicArenaScopedPtr<MockAlarm>(
108 new MockAlarm(std::move(delegate), alarm_index_++, this));
109 }
110 MOCK_METHOD(void, OnAlarmSet, (int, QuicTime), ());
111 MOCK_METHOD(void, OnAlarmCancelled, (int), ());
112
113 private:
114 int alarm_index_ = 0;
115 };
116
SetImpl()117 void MockAlarm::SetImpl() { factory_->OnAlarmSet(alarm_index_, deadline()); }
118
CancelImpl()119 void MockAlarm::CancelImpl() { factory_->OnAlarmCancelled(alarm_index_); }
120
121 class QuicTimeWaitListManagerTest : public QuicTest {
122 protected:
QuicTimeWaitListManagerTest()123 QuicTimeWaitListManagerTest()
124 : time_wait_list_manager_(&writer_, &visitor_, &clock_, &alarm_factory_),
125 connection_id_(TestConnectionId(45)),
126 peer_address_(TestPeerIPAddress(), kTestPort),
127 writer_is_blocked_(false) {}
128
129 ~QuicTimeWaitListManagerTest() override = default;
130
SetUp()131 void SetUp() override {
132 EXPECT_CALL(writer_, IsWriteBlocked())
133 .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
134 }
135
AddConnectionId(QuicConnectionId connection_id,QuicTimeWaitListManager::TimeWaitAction action)136 void AddConnectionId(QuicConnectionId connection_id,
137 QuicTimeWaitListManager::TimeWaitAction action) {
138 AddConnectionId(connection_id, action, nullptr);
139 }
140
AddStatelessConnectionId(QuicConnectionId connection_id)141 void AddStatelessConnectionId(QuicConnectionId connection_id) {
142 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
143 termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
144 new QuicEncryptedPacket(nullptr, 0, false)));
145 time_wait_list_manager_.AddConnectionIdToTimeWait(
146 QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
147 TimeWaitConnectionInfo(false, &termination_packets, {connection_id}));
148 }
149
AddConnectionId(QuicConnectionId connection_id,QuicTimeWaitListManager::TimeWaitAction action,std::vector<std::unique_ptr<QuicEncryptedPacket>> * packets)150 void AddConnectionId(
151 QuicConnectionId connection_id,
152 QuicTimeWaitListManager::TimeWaitAction action,
153 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
154 time_wait_list_manager_.AddConnectionIdToTimeWait(
155 action,
156 TimeWaitConnectionInfo(/*ietf_quic=*/true, packets, {connection_id}));
157 }
158
IsConnectionIdInTimeWait(QuicConnectionId connection_id)159 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
160 return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
161 }
162
ProcessPacket(QuicConnectionId connection_id)163 void ProcessPacket(QuicConnectionId connection_id) {
164 time_wait_list_manager_.ProcessPacket(
165 self_address_, peer_address_, connection_id, GOOGLE_QUIC_PACKET,
166 kTestPacketSize, std::make_unique<QuicPerPacketContext>());
167 }
168
ConstructEncryptedPacket(QuicConnectionId destination_connection_id,QuicConnectionId source_connection_id,uint64_t packet_number)169 QuicEncryptedPacket* ConstructEncryptedPacket(
170 QuicConnectionId destination_connection_id,
171 QuicConnectionId source_connection_id, uint64_t packet_number) {
172 return quic::test::ConstructEncryptedPacket(destination_connection_id,
173 source_connection_id, false,
174 false, packet_number, "data");
175 }
176
177 MockClock clock_;
178 MockAlarmFactory alarm_factory_;
179 NiceMock<MockPacketWriter> writer_;
180 StrictMock<MockQuicSessionVisitor> visitor_;
181 QuicTimeWaitListManager time_wait_list_manager_;
182 QuicConnectionId connection_id_;
183 QuicSocketAddress self_address_;
184 QuicSocketAddress peer_address_;
185 bool writer_is_blocked_;
186 };
187
ValidPublicResetPacketPredicate(QuicConnectionId expected_connection_id,const std::tuple<const char *,int> & packet_buffer)188 bool ValidPublicResetPacketPredicate(
189 QuicConnectionId expected_connection_id,
190 const std::tuple<const char*, int>& packet_buffer) {
191 FramerVisitorCapturingPublicReset visitor(expected_connection_id);
192 QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
193 Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
194 framer.set_visitor(&visitor);
195 QuicEncryptedPacket encrypted(std::get<0>(packet_buffer),
196 std::get<1>(packet_buffer));
197 framer.ProcessPacket(encrypted);
198
199 QuicIetfStatelessResetPacket stateless_reset =
200 visitor.stateless_reset_packet();
201
202 StatelessResetToken expected_stateless_reset_token =
203 QuicUtils::GenerateStatelessResetToken(expected_connection_id);
204
205 return stateless_reset.stateless_reset_token ==
206 expected_stateless_reset_token;
207 }
208
PublicResetPacketEq(QuicConnectionId connection_id)209 Matcher<const std::tuple<const char*, int>> PublicResetPacketEq(
210 QuicConnectionId connection_id) {
211 return Truly(
212 [connection_id](const std::tuple<const char*, int> packet_buffer) {
213 return ValidPublicResetPacketPredicate(connection_id, packet_buffer);
214 });
215 }
216
TEST_F(QuicTimeWaitListManagerTest,CheckConnectionIdInTimeWait)217 TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
218 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
219 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
220 AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
221 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
222 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
223 }
224
TEST_F(QuicTimeWaitListManagerTest,CheckStatelessConnectionIdInTimeWait)225 TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
226 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
227 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
228 AddStatelessConnectionId(connection_id_);
229 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
230 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
231 }
232
TEST_F(QuicTimeWaitListManagerTest,SendVersionNegotiationPacket)233 TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
234 std::unique_ptr<QuicEncryptedPacket> packet(
235 QuicFramer::BuildVersionNegotiationPacket(
236 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
237 /*use_length_prefix=*/false, AllSupportedVersions()));
238 EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
239 peer_address_, _, _))
240 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
241
242 time_wait_list_manager_.SendVersionNegotiationPacket(
243 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
244 /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
245 peer_address_, std::make_unique<QuicPerPacketContext>());
246 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
247 }
248
TEST_F(QuicTimeWaitListManagerTest,SendIetfVersionNegotiationPacketWithoutLengthPrefix)249 TEST_F(QuicTimeWaitListManagerTest,
250 SendIetfVersionNegotiationPacketWithoutLengthPrefix) {
251 std::unique_ptr<QuicEncryptedPacket> packet(
252 QuicFramer::BuildVersionNegotiationPacket(
253 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
254 /*use_length_prefix=*/false, AllSupportedVersions()));
255 EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
256 peer_address_, _, _))
257 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
258
259 time_wait_list_manager_.SendVersionNegotiationPacket(
260 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
261 /*use_length_prefix=*/false, AllSupportedVersions(), self_address_,
262 peer_address_, std::make_unique<QuicPerPacketContext>());
263 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
264 }
265
TEST_F(QuicTimeWaitListManagerTest,SendIetfVersionNegotiationPacket)266 TEST_F(QuicTimeWaitListManagerTest, SendIetfVersionNegotiationPacket) {
267 std::unique_ptr<QuicEncryptedPacket> packet(
268 QuicFramer::BuildVersionNegotiationPacket(
269 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
270 /*use_length_prefix=*/true, AllSupportedVersions()));
271 EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
272 peer_address_, _, _))
273 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
274
275 time_wait_list_manager_.SendVersionNegotiationPacket(
276 connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
277 /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
278 peer_address_, std::make_unique<QuicPerPacketContext>());
279 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
280 }
281
TEST_F(QuicTimeWaitListManagerTest,SendIetfVersionNegotiationPacketWithClientConnectionId)282 TEST_F(QuicTimeWaitListManagerTest,
283 SendIetfVersionNegotiationPacketWithClientConnectionId) {
284 std::unique_ptr<QuicEncryptedPacket> packet(
285 QuicFramer::BuildVersionNegotiationPacket(
286 connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
287 /*use_length_prefix=*/true, AllSupportedVersions()));
288 EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
289 peer_address_, _, _))
290 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
291
292 time_wait_list_manager_.SendVersionNegotiationPacket(
293 connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
294 /*use_length_prefix=*/true, AllSupportedVersions(), self_address_,
295 peer_address_, std::make_unique<QuicPerPacketContext>());
296 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
297 }
298
TEST_F(QuicTimeWaitListManagerTest,SendConnectionClose)299 TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
300 const size_t kConnectionCloseLength = 100;
301 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
302 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
303 termination_packets.push_back(
304 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
305 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
306 AddConnectionId(connection_id_,
307 QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
308 &termination_packets);
309 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
310 self_address_.host(), peer_address_, _, _))
311 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
312
313 ProcessPacket(connection_id_);
314 }
315
TEST_F(QuicTimeWaitListManagerTest,SendTwoConnectionCloses)316 TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) {
317 const size_t kConnectionCloseLength = 100;
318 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
319 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
320 termination_packets.push_back(
321 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
322 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
323 termination_packets.push_back(
324 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
325 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
326 AddConnectionId(connection_id_,
327 QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
328 &termination_packets);
329 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
330 self_address_.host(), peer_address_, _, _))
331 .Times(2)
332 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
333
334 ProcessPacket(connection_id_);
335 }
336
TEST_F(QuicTimeWaitListManagerTest,SendPublicReset)337 TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
338 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
339 AddConnectionId(connection_id_,
340 QuicTimeWaitListManager::SEND_STATELESS_RESET);
341 EXPECT_CALL(writer_,
342 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
343 .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
344 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
345
346 ProcessPacket(connection_id_);
347 }
348
TEST_F(QuicTimeWaitListManagerTest,SendPublicResetWithExponentialBackOff)349 TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
350 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
351 AddConnectionId(connection_id_,
352 QuicTimeWaitListManager::SEND_STATELESS_RESET);
353 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
354 for (int packet_number = 1; packet_number < 101; ++packet_number) {
355 if ((packet_number & (packet_number - 1)) == 0) {
356 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _))
357 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
358 }
359 ProcessPacket(connection_id_);
360 // Send public reset with exponential back off.
361 if ((packet_number & (packet_number - 1)) == 0) {
362 EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
363 &time_wait_list_manager_, packet_number));
364 } else {
365 EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
366 &time_wait_list_manager_, packet_number));
367 }
368 }
369 }
370
TEST_F(QuicTimeWaitListManagerTest,NoPublicResetForStatelessConnections)371 TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
372 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
373 AddStatelessConnectionId(connection_id_);
374
375 EXPECT_CALL(writer_,
376 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
377 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
378
379 ProcessPacket(connection_id_);
380 }
381
TEST_F(QuicTimeWaitListManagerTest,CleanUpOldConnectionIds)382 TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
383 const size_t kConnectionIdCount = 100;
384 const size_t kOldConnectionIdCount = 31;
385
386 // Add connection_ids such that their expiry time is time_wait_period_.
387 for (uint64_t conn_id = 1; conn_id <= kOldConnectionIdCount; ++conn_id) {
388 QuicConnectionId connection_id = TestConnectionId(conn_id);
389 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
390 AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
391 }
392 EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
393
394 // Add remaining connection_ids such that their add time is
395 // 2 * time_wait_period_.
396 const QuicTime::Delta time_wait_period =
397 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
398 clock_.AdvanceTime(time_wait_period);
399 for (uint64_t conn_id = kOldConnectionIdCount + 1;
400 conn_id <= kConnectionIdCount; ++conn_id) {
401 QuicConnectionId connection_id = TestConnectionId(conn_id);
402 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
403 AddConnectionId(connection_id, QuicTimeWaitListManager::DO_NOTHING);
404 }
405 EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
406
407 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
408 // Now set the current time as time_wait_period + offset usecs.
409 clock_.AdvanceTime(offset);
410 // After all the old connection_ids are cleaned up, check the next alarm
411 // interval.
412 QuicTime next_alarm_time = clock_.Now() + time_wait_period - offset;
413 EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
414
415 time_wait_list_manager_.CleanUpOldConnectionIds();
416 for (uint64_t conn_id = 1; conn_id <= kConnectionIdCount; ++conn_id) {
417 QuicConnectionId connection_id = TestConnectionId(conn_id);
418 EXPECT_EQ(conn_id > kOldConnectionIdCount,
419 IsConnectionIdInTimeWait(connection_id))
420 << "kOldConnectionIdCount: " << kOldConnectionIdCount
421 << " connection_id: " << connection_id;
422 }
423 EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
424 time_wait_list_manager_.num_connections());
425 }
426
TEST_F(QuicTimeWaitListManagerTest,CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection)427 TEST_F(QuicTimeWaitListManagerTest,
428 CleanUpOldConnectionIdsForMultipleConnectionIdsPerConnection) {
429 connection_id_ = TestConnectionId(7);
430 const size_t kConnectionCloseLength = 100;
431 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
432 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
433 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
434 termination_packets.push_back(
435 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
436 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
437
438 // Add a CONNECTION_CLOSE termination packet.
439 std::vector<QuicConnectionId> active_connection_ids{connection_id_,
440 TestConnectionId(8)};
441 time_wait_list_manager_.AddConnectionIdToTimeWait(
442 QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
443 TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
444 active_connection_ids, QuicTime::Delta::Zero()));
445
446 EXPECT_TRUE(
447 time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
448 EXPECT_TRUE(
449 time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
450
451 // Remove these IDs.
452 const QuicTime::Delta time_wait_period =
453 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
454 clock_.AdvanceTime(time_wait_period);
455 time_wait_list_manager_.CleanUpOldConnectionIds();
456
457 EXPECT_FALSE(
458 time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(7)));
459 EXPECT_FALSE(
460 time_wait_list_manager_.IsConnectionIdInTimeWait(TestConnectionId(8)));
461 }
462
TEST_F(QuicTimeWaitListManagerTest,SendQueuedPackets)463 TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
464 QuicConnectionId connection_id = TestConnectionId(1);
465 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
466 AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
467 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
468 connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
469 // Let first write through.
470 EXPECT_CALL(writer_,
471 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
472 .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
473 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
474 ProcessPacket(connection_id);
475
476 // write block for the next packet.
477 EXPECT_CALL(writer_,
478 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
479 .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
480 .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
481 Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
482 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
483 ProcessPacket(connection_id);
484 // 3rd packet. No public reset should be sent;
485 ProcessPacket(connection_id);
486
487 // write packet should not be called since we are write blocked but the
488 // should be queued.
489 QuicConnectionId other_connection_id = TestConnectionId(2);
490 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
491 AddConnectionId(other_connection_id,
492 QuicTimeWaitListManager::SEND_STATELESS_RESET);
493 std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
494 other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
495 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)).Times(0);
496 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
497 ProcessPacket(other_connection_id);
498 EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
499
500 // Now expect all the write blocked public reset packets to be sent again.
501 writer_is_blocked_ = false;
502 EXPECT_CALL(writer_,
503 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
504 .With(Args<0, 1>(PublicResetPacketEq(connection_id)))
505 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
506 EXPECT_CALL(writer_,
507 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
508 .With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
509 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
510 time_wait_list_manager_.OnBlockedWriterCanWrite();
511 }
512
TEST_F(QuicTimeWaitListManagerTest,AddConnectionIdTwice)513 TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
514 // Add connection_ids such that their expiry time is time_wait_period_.
515 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
516 AddConnectionId(connection_id_, QuicTimeWaitListManager::DO_NOTHING);
517 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
518 const size_t kConnectionCloseLength = 100;
519 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
520 termination_packets.push_back(
521 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
522 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
523 AddConnectionId(connection_id_,
524 QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
525 &termination_packets);
526 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
527 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
528
529 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
530 self_address_.host(), peer_address_, _, _))
531 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
532
533 ProcessPacket(connection_id_);
534
535 const QuicTime::Delta time_wait_period =
536 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
537
538 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
539 clock_.AdvanceTime(offset + time_wait_period);
540 // Now set the current time as time_wait_period + offset usecs.
541 QuicTime next_alarm_time = clock_.Now() + time_wait_period;
542 EXPECT_CALL(alarm_factory_, OnAlarmSet(_, next_alarm_time));
543
544 time_wait_list_manager_.CleanUpOldConnectionIds();
545 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
546 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
547 }
548
TEST_F(QuicTimeWaitListManagerTest,ConnectionIdsOrderedByTime)549 TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
550 // Simple randomization: the values of connection_ids are randomly swapped.
551 // If the container is broken, the test will be 50% flaky.
552 const uint64_t conn_id1 = QuicRandom::GetInstance()->RandUint64() % 2;
553 const QuicConnectionId connection_id1 = TestConnectionId(conn_id1);
554 const QuicConnectionId connection_id2 = TestConnectionId(1 - conn_id1);
555
556 // 1 will hash lower than 2, but we add it later. They should come out in the
557 // add order, not hash order.
558 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
559 AddConnectionId(connection_id1, QuicTimeWaitListManager::DO_NOTHING);
560 clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
561 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
562 AddConnectionId(connection_id2, QuicTimeWaitListManager::DO_NOTHING);
563 EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
564
565 const QuicTime::Delta time_wait_period =
566 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
567 clock_.AdvanceTime(time_wait_period - QuicTime::Delta::FromMicroseconds(9));
568
569 EXPECT_CALL(alarm_factory_, OnAlarmSet(_, _));
570
571 time_wait_list_manager_.CleanUpOldConnectionIds();
572 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
573 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
574 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
575 }
576
TEST_F(QuicTimeWaitListManagerTest,MaxConnectionsTest)577 TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
578 // Basically, shut off time-based eviction.
579 SetQuicFlag(quic_time_wait_list_seconds, 10000000000);
580 SetQuicFlag(quic_time_wait_list_max_connections, 5);
581
582 uint64_t current_conn_id = 0;
583 const int64_t kMaxConnections =
584 GetQuicFlag(quic_time_wait_list_max_connections);
585 // Add exactly the maximum number of connections
586 for (int64_t i = 0; i < kMaxConnections; ++i) {
587 ++current_conn_id;
588 QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
589 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
590 EXPECT_CALL(visitor_,
591 OnConnectionAddedToTimeWaitList(current_connection_id));
592 AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
593 EXPECT_EQ(current_conn_id, time_wait_list_manager_.num_connections());
594 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
595 }
596
597 // Now keep adding. Since we're already at the max, every new connection-id
598 // will evict the oldest one.
599 for (int64_t i = 0; i < kMaxConnections; ++i) {
600 ++current_conn_id;
601 QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
602 const QuicConnectionId id_to_evict =
603 TestConnectionId(current_conn_id - kMaxConnections);
604 EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
605 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
606 EXPECT_CALL(visitor_,
607 OnConnectionAddedToTimeWaitList(current_connection_id));
608 AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
609 EXPECT_EQ(static_cast<size_t>(kMaxConnections),
610 time_wait_list_manager_.num_connections());
611 EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
612 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
613 }
614 }
615
TEST_F(QuicTimeWaitListManagerTest,ZeroMaxConnections)616 TEST_F(QuicTimeWaitListManagerTest, ZeroMaxConnections) {
617 // Basically, shut off time-based eviction.
618 SetQuicFlag(quic_time_wait_list_seconds, 10000000000);
619 // Keep time wait list empty.
620 SetQuicFlag(quic_time_wait_list_max_connections, 0);
621
622 uint64_t current_conn_id = 0;
623 // Add exactly the maximum number of connections
624 for (int64_t i = 0; i < 10; ++i) {
625 ++current_conn_id;
626 QuicConnectionId current_connection_id = TestConnectionId(current_conn_id);
627 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
628 EXPECT_CALL(visitor_,
629 OnConnectionAddedToTimeWaitList(current_connection_id));
630 AddConnectionId(current_connection_id, QuicTimeWaitListManager::DO_NOTHING);
631 // Verify time wait list always has 1 connection.
632 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
633 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
634 }
635 }
636
637 // Regression test for b/116200989.
TEST_F(QuicTimeWaitListManagerTest,SendStatelessResetInResponseToShortHeaders)638 TEST_F(QuicTimeWaitListManagerTest,
639 SendStatelessResetInResponseToShortHeaders) {
640 // This test mimics a scenario where an ENCRYPTION_INITIAL connection close is
641 // added as termination packet for an IETF connection ID. However, a short
642 // header packet is received later.
643 const size_t kConnectionCloseLength = 100;
644 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
645 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
646 termination_packets.push_back(
647 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
648 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
649 time_wait_list_manager_.AddConnectionIdToTimeWait(
650 QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
651 TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
652 {connection_id_}));
653
654 // Termination packet is not encrypted, instead, send stateless reset.
655 EXPECT_CALL(writer_,
656 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
657 .With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
658 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
659 // Processes IETF short header packet.
660 time_wait_list_manager_.ProcessPacket(
661 self_address_, peer_address_, connection_id_,
662 IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
663 std::make_unique<QuicPerPacketContext>());
664 }
665
TEST_F(QuicTimeWaitListManagerTest,SendConnectionClosePacketsInResponseToShortHeaders)666 TEST_F(QuicTimeWaitListManagerTest,
667 SendConnectionClosePacketsInResponseToShortHeaders) {
668 const size_t kConnectionCloseLength = 100;
669 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
670 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
671 termination_packets.push_back(
672 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
673 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
674 // Add a CONNECTION_CLOSE termination packet.
675 time_wait_list_manager_.AddConnectionIdToTimeWait(
676 QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
677 TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
678 {connection_id_}));
679 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
680 self_address_.host(), peer_address_, _, _))
681 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
682
683 // Processes IETF short header packet.
684 time_wait_list_manager_.ProcessPacket(
685 self_address_, peer_address_, connection_id_,
686 IETF_QUIC_SHORT_HEADER_PACKET, kTestPacketSize,
687 std::make_unique<QuicPerPacketContext>());
688 }
689
TEST_F(QuicTimeWaitListManagerTest,SendConnectionClosePacketsForMultipleConnectionIds)690 TEST_F(QuicTimeWaitListManagerTest,
691 SendConnectionClosePacketsForMultipleConnectionIds) {
692 connection_id_ = TestConnectionId(7);
693 const size_t kConnectionCloseLength = 100;
694 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
695 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(TestConnectionId(8)));
696 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
697 termination_packets.push_back(
698 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
699 new char[kConnectionCloseLength], kConnectionCloseLength, true)));
700
701 // Add a CONNECTION_CLOSE termination packet.
702 std::vector<QuicConnectionId> active_connection_ids{connection_id_,
703 TestConnectionId(8)};
704 time_wait_list_manager_.AddConnectionIdToTimeWait(
705 QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
706 TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
707 active_connection_ids, QuicTime::Delta::Zero()));
708
709 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
710 self_address_.host(), peer_address_, _, _))
711 .Times(2)
712 .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
713 // Processes IETF short header packet.
714 for (auto const& cid : active_connection_ids) {
715 time_wait_list_manager_.ProcessPacket(
716 self_address_, peer_address_, cid, IETF_QUIC_SHORT_HEADER_PACKET,
717 kTestPacketSize, std::make_unique<QuicPerPacketContext>());
718 }
719 }
720
721 // Regression test for b/184053898.
TEST_F(QuicTimeWaitListManagerTest,DonotCrashOnNullStatelessReset)722 TEST_F(QuicTimeWaitListManagerTest, DonotCrashOnNullStatelessReset) {
723 // Received a packet with length <
724 // QuicFramer::GetMinStatelessResetPacketLength(), and this will result in a
725 // null stateless reset.
726 time_wait_list_manager_.SendPublicReset(
727 self_address_, peer_address_, TestConnectionId(1),
728 /*ietf_quic=*/true,
729 /*received_packet_length=*/
730 QuicFramer::GetMinStatelessResetPacketLength() - 1,
731 /*packet_context=*/nullptr);
732 }
733
TEST_F(QuicTimeWaitListManagerTest,SendOrQueueNullPacket)734 TEST_F(QuicTimeWaitListManagerTest, SendOrQueueNullPacket) {
735 QuicTimeWaitListManagerPeer::SendOrQueuePacket(&time_wait_list_manager_,
736 nullptr, nullptr);
737 }
738
TEST_F(QuicTimeWaitListManagerTest,TooManyPendingPackets)739 TEST_F(QuicTimeWaitListManagerTest, TooManyPendingPackets) {
740 SetQuicFlag(quic_time_wait_list_max_pending_packets, 5);
741 const size_t kNumOfUnProcessablePackets = 2048;
742 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_))
743 .Times(testing::AnyNumber());
744 // Write block for the next packets.
745 EXPECT_CALL(writer_,
746 WritePacket(_, _, self_address_.host(), peer_address_, _, _))
747 .With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
748 .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
749 Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
750 for (size_t i = 0; i < kNumOfUnProcessablePackets; ++i) {
751 time_wait_list_manager_.SendPublicReset(
752 self_address_, peer_address_, TestConnectionId(1),
753 /*ietf_quic=*/true,
754 /*received_packet_length=*/
755 QuicFramer::GetMinStatelessResetPacketLength() + 1,
756 /*packet_context=*/nullptr);
757 }
758 // Verify pending packet queue size is limited.
759 EXPECT_EQ(5u, QuicTimeWaitListManagerPeer::PendingPacketsQueueSize(
760 &time_wait_list_manager_));
761 }
762
763 } // namespace
764 } // namespace test
765 } // namespace quic
766