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