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