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