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