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.
5 #include "net/tools/quic/quic_time_wait_list_manager.h"
9 #include "net/quic/crypto/crypto_protocol.h"
10 #include "net/quic/crypto/null_encrypter.h"
11 #include "net/quic/crypto/quic_decrypter.h"
12 #include "net/quic/crypto/quic_encrypter.h"
13 #include "net/quic/quic_connection_helper.h"
14 #include "net/quic/quic_data_reader.h"
15 #include "net/quic/quic_flags.h"
16 #include "net/quic/quic_framer.h"
17 #include "net/quic/quic_packet_writer.h"
18 #include "net/quic/quic_protocol.h"
19 #include "net/quic/quic_utils.h"
20 #include "net/quic/test_tools/quic_test_utils.h"
21 #include "net/tools/quic/quic_epoll_connection_helper.h"
22 #include "net/tools/quic/test_tools/mock_epoll_server.h"
23 #include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using net::test::kTestPort
;
28 using net::test::BuildUnsizedDataPacket
;
29 using net::test::NoOpFramerVisitor
;
30 using net::test::QuicVersionMax
;
31 using net::test::QuicVersionMin
;
32 using net::test::ValueRestore
;
33 using net::test::MockPacketWriter
;
36 using testing::Assign
;
38 using testing::Matcher
;
39 using testing::MatcherInterface
;
40 using testing::NiceMock
;
41 using testing::Return
;
42 using testing::ReturnPointee
;
43 using testing::SetArgPointee
;
44 using testing::StrictMock
;
52 class FramerVisitorCapturingPublicReset
: public NoOpFramerVisitor
{
54 FramerVisitorCapturingPublicReset() {}
55 ~FramerVisitorCapturingPublicReset() override
{}
57 void OnPublicResetPacket(const QuicPublicResetPacket
& public_reset
) override
{
58 public_reset_packet_
= public_reset
;
61 const QuicPublicResetPacket
public_reset_packet() {
62 return public_reset_packet_
;
66 QuicPublicResetPacket public_reset_packet_
;
69 class QuicTimeWaitListManagerPeer
{
71 static bool ShouldSendResponse(QuicTimeWaitListManager
* manager
,
72 int received_packet_count
) {
73 return manager
->ShouldSendResponse(received_packet_count
);
76 static QuicTime::Delta
time_wait_period(QuicTimeWaitListManager
* manager
) {
77 return manager
->time_wait_period_
;
80 static QuicVersion
GetQuicVersionFromConnectionId(
81 QuicTimeWaitListManager
* manager
,
82 QuicConnectionId connection_id
) {
83 return manager
->GetQuicVersionFromConnectionId(connection_id
);
89 class MockFakeTimeEpollServer
: public FakeTimeEpollServer
{
91 MOCK_METHOD2(RegisterAlarm
, void(int64 timeout_in_us
,
92 EpollAlarmCallbackInterface
* alarm
));
95 class QuicTimeWaitListManagerTest
: public ::testing::Test
{
97 QuicTimeWaitListManagerTest()
98 : helper_(&epoll_server_
),
99 time_wait_list_manager_(&writer_
,
102 QuicSupportedVersions()),
103 framer_(QuicSupportedVersions(),
105 Perspective::IS_SERVER
),
107 client_address_(net::test::TestPeerIPAddress(), kTestPort
),
108 writer_is_blocked_(false) {}
110 ~QuicTimeWaitListManagerTest() override
{}
112 void SetUp() override
{
113 EXPECT_CALL(writer_
, IsWriteBlocked())
114 .WillRepeatedly(ReturnPointee(&writer_is_blocked_
));
115 EXPECT_CALL(writer_
, IsWriteBlockedDataBuffered())
116 .WillRepeatedly(Return(false));
119 void AddConnectionId(QuicConnectionId connection_id
) {
120 AddConnectionId(connection_id
, QuicVersionMax(),
121 /*connection_rejected_statelessly=*/false, nullptr);
124 void AddStatelessConnectionId(QuicConnectionId connection_id
) {
125 time_wait_list_manager_
.AddConnectionIdToTimeWait(
126 connection_id
, QuicVersionMax(),
127 /*connection_rejected_statelessly=*/true, nullptr);
130 void AddConnectionId(QuicConnectionId connection_id
,
132 bool connection_rejected_statelessly
,
133 QuicEncryptedPacket
* packet
) {
134 time_wait_list_manager_
.AddConnectionIdToTimeWait(
135 connection_id
, version
, connection_rejected_statelessly
, packet
);
138 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id
) {
139 return time_wait_list_manager_
.IsConnectionIdInTimeWait(connection_id
);
142 void ProcessPacket(QuicConnectionId connection_id
,
143 QuicPacketNumber packet_number
) {
144 QuicEncryptedPacket
packet(nullptr, 0);
145 time_wait_list_manager_
.ProcessPacket(server_address_
, client_address_
,
146 connection_id
, packet_number
, packet
);
149 QuicEncryptedPacket
* ConstructEncryptedPacket(
150 EncryptionLevel level
,
151 QuicConnectionId connection_id
,
152 QuicPacketNumber packet_number
) {
153 QuicPacketHeader header
;
154 header
.public_header
.connection_id
= connection_id
;
155 header
.public_header
.connection_id_length
= PACKET_8BYTE_CONNECTION_ID
;
156 header
.public_header
.version_flag
= false;
157 header
.public_header
.reset_flag
= false;
158 header
.public_header
.packet_number_length
= PACKET_6BYTE_PACKET_NUMBER
;
159 header
.packet_packet_number
= packet_number
;
160 header
.entropy_flag
= false;
161 header
.entropy_hash
= 0;
162 header
.fec_flag
= false;
163 header
.is_in_fec_group
= NOT_IN_FEC_GROUP
;
164 header
.fec_group
= 0;
165 QuicStreamFrame
stream_frame(1, false, 0, StringPiece("data"));
166 QuicFrame
frame(&stream_frame
);
168 frames
.push_back(frame
);
169 scoped_ptr
<QuicPacket
> packet(
170 BuildUnsizedDataPacket(&framer_
, header
, frames
));
171 EXPECT_TRUE(packet
!= nullptr);
172 char buffer
[kMaxPacketSize
];
173 scoped_ptr
<QuicEncryptedPacket
> encrypted(framer_
.EncryptPayload(
174 ENCRYPTION_NONE
, packet_number
, *packet
, buffer
, kMaxPacketSize
));
175 EXPECT_TRUE(encrypted
!= nullptr);
176 return encrypted
->Clone();
179 NiceMock
<MockFakeTimeEpollServer
> epoll_server_
;
180 QuicEpollConnectionHelper helper_
;
181 StrictMock
<MockPacketWriter
> writer_
;
182 StrictMock
<MockQuicServerSessionVisitor
> visitor_
;
183 QuicTimeWaitListManager time_wait_list_manager_
;
185 QuicConnectionId connection_id_
;
186 IPEndPoint server_address_
;
187 IPEndPoint client_address_
;
188 bool writer_is_blocked_
;
191 class ValidatePublicResetPacketPredicate
192 : public MatcherInterface
<const std::tr1::tuple
<const char*, int> > {
194 explicit ValidatePublicResetPacketPredicate(QuicConnectionId connection_id
,
195 QuicPacketNumber number
)
196 : connection_id_(connection_id
), packet_number_(number
) {}
198 bool MatchAndExplain(
199 const std::tr1::tuple
<const char*, int> packet_buffer
,
200 testing::MatchResultListener
* /* listener */) const override
{
201 FramerVisitorCapturingPublicReset visitor
;
202 QuicFramer
framer(QuicSupportedVersions(), QuicTime::Zero(),
203 Perspective::IS_CLIENT
);
204 framer
.set_visitor(&visitor
);
205 QuicEncryptedPacket
encrypted(std::tr1::get
<0>(packet_buffer
),
206 std::tr1::get
<1>(packet_buffer
));
207 framer
.ProcessPacket(encrypted
);
208 QuicPublicResetPacket packet
= visitor
.public_reset_packet();
209 return connection_id_
== packet
.public_header
.connection_id
&&
210 packet
.public_header
.reset_flag
&&
211 !packet
.public_header
.version_flag
&&
212 packet_number_
== packet
.rejected_packet_number
&&
213 net::test::TestPeerIPAddress() == packet
.client_address
.address() &&
214 kTestPort
== packet
.client_address
.port();
217 void DescribeTo(::std::ostream
* os
) const override
{}
219 void DescribeNegationTo(::std::ostream
* os
) const override
{}
222 QuicConnectionId connection_id_
;
223 QuicPacketNumber packet_number_
;
226 Matcher
<const std::tr1::tuple
<const char*, int>> PublicResetPacketEq(
227 QuicConnectionId connection_id
,
228 QuicPacketNumber packet_number
) {
230 new ValidatePublicResetPacketPredicate(connection_id
, packet_number
));
233 TEST_F(QuicTimeWaitListManagerTest
, CheckConnectionIdInTimeWait
) {
234 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_
));
235 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
236 AddConnectionId(connection_id_
);
237 EXPECT_EQ(1u, time_wait_list_manager_
.num_connections());
238 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_
));
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_
));
249 TEST_F(QuicTimeWaitListManagerTest
, SendConnectionClose
) {
250 const size_t kConnectionCloseLength
= 100;
251 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
252 AddConnectionId(connection_id_
, QuicVersionMax(),
253 /*connection_rejected_statelessly=*/false,
254 new QuicEncryptedPacket(new char[kConnectionCloseLength
],
255 kConnectionCloseLength
, true));
256 const int kRandomSequenceNumber
= 1;
257 EXPECT_CALL(writer_
, WritePacket(_
, kConnectionCloseLength
,
258 server_address_
.address(),
260 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, 1)));
262 ProcessPacket(connection_id_
, kRandomSequenceNumber
);
265 TEST_F(QuicTimeWaitListManagerTest
, SendPublicReset
) {
266 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
267 AddConnectionId(connection_id_
);
268 const int kRandomSequenceNumber
= 1;
269 EXPECT_CALL(writer_
, WritePacket(_
, _
,
270 server_address_
.address(),
272 .With(Args
<0, 1>(PublicResetPacketEq(connection_id_
,
273 kRandomSequenceNumber
)))
274 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, 0)));
276 ProcessPacket(connection_id_
, kRandomSequenceNumber
);
279 TEST_F(QuicTimeWaitListManagerTest
, SendPublicResetWithExponentialBackOff
) {
280 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
281 AddConnectionId(connection_id_
);
282 EXPECT_EQ(1u, time_wait_list_manager_
.num_connections());
283 for (int packet_number
= 1; packet_number
< 101; ++packet_number
) {
284 if ((packet_number
& (packet_number
- 1)) == 0) {
285 EXPECT_CALL(writer_
, WritePacket(_
, _
, _
, _
))
286 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, 1)));
288 ProcessPacket(connection_id_
, packet_number
);
289 // Send public reset with exponential back off.
290 if ((packet_number
& (packet_number
- 1)) == 0) {
291 EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
292 &time_wait_list_manager_
, packet_number
));
294 EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
295 &time_wait_list_manager_
, packet_number
));
300 TEST_F(QuicTimeWaitListManagerTest
, NoPublicResetForStatelessConnections
) {
301 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
302 AddStatelessConnectionId(connection_id_
);
303 const int kRandomSequenceNumber
= 1;
304 ProcessPacket(connection_id_
, kRandomSequenceNumber
);
307 TEST_F(QuicTimeWaitListManagerTest
, CleanUpOldConnectionIds
) {
308 const size_t kConnectionIdCount
= 100;
309 const size_t kOldConnectionIdCount
= 31;
311 // Add connection_ids such that their expiry time is time_wait_period_.
312 epoll_server_
.set_now_in_usec(0);
313 for (size_t connection_id
= 1; connection_id
<= kOldConnectionIdCount
;
315 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id
));
316 AddConnectionId(connection_id
);
318 EXPECT_EQ(kOldConnectionIdCount
, time_wait_list_manager_
.num_connections());
320 // Add remaining connection_ids such that their add time is
321 // 2 * time_wait_period_.
322 const QuicTime::Delta time_wait_period
=
323 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_
);
324 epoll_server_
.set_now_in_usec(time_wait_period
.ToMicroseconds());
325 for (size_t connection_id
= kOldConnectionIdCount
+ 1;
326 connection_id
<= kConnectionIdCount
; ++connection_id
) {
327 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id
));
328 AddConnectionId(connection_id
);
330 EXPECT_EQ(kConnectionIdCount
, time_wait_list_manager_
.num_connections());
332 QuicTime::Delta offset
= QuicTime::Delta::FromMicroseconds(39);
333 // Now set the current time as time_wait_period + offset usecs.
334 epoll_server_
.set_now_in_usec(time_wait_period
.Add(offset
).ToMicroseconds());
335 // After all the old connection_ids are cleaned up, check the next alarm
337 int64 next_alarm_time
= epoll_server_
.ApproximateNowInUsec() +
338 time_wait_period
.Subtract(offset
).ToMicroseconds();
339 EXPECT_CALL(epoll_server_
, RegisterAlarm(next_alarm_time
, _
));
341 for (size_t connection_id
= 1; connection_id
<= kConnectionIdCount
;
343 if (connection_id
<= kOldConnectionIdCount
) {
344 EXPECT_CALL(visitor_
, OnConnectionRemovedFromTimeWaitList(connection_id
));
347 time_wait_list_manager_
.CleanUpOldConnectionIds();
348 for (size_t connection_id
= 1; connection_id
<= kConnectionIdCount
;
350 EXPECT_EQ(connection_id
> kOldConnectionIdCount
,
351 IsConnectionIdInTimeWait(connection_id
))
352 << "kOldConnectionIdCount: " << kOldConnectionIdCount
353 << " connection_id: " << connection_id
;
355 EXPECT_EQ(kConnectionIdCount
- kOldConnectionIdCount
,
356 time_wait_list_manager_
.num_connections());
359 TEST_F(QuicTimeWaitListManagerTest
, SendQueuedPackets
) {
360 QuicConnectionId connection_id
= 1;
361 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id
));
362 AddConnectionId(connection_id
);
363 QuicPacketNumber packet_number
= 234;
364 scoped_ptr
<QuicEncryptedPacket
> packet(
365 ConstructEncryptedPacket(ENCRYPTION_NONE
, connection_id
, packet_number
));
366 // Let first write through.
368 WritePacket(_
, _
, server_address_
.address(), client_address_
))
369 .With(Args
<0, 1>(PublicResetPacketEq(connection_id
, packet_number
)))
370 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, packet
->length())));
371 ProcessPacket(connection_id
, packet_number
);
373 // write block for the next packet.
375 WritePacket(_
, _
, server_address_
.address(), client_address_
))
376 .With(Args
<0, 1>(PublicResetPacketEq(connection_id
, packet_number
)))
377 .WillOnce(DoAll(Assign(&writer_is_blocked_
, true),
378 Return(WriteResult(WRITE_STATUS_BLOCKED
, EAGAIN
))));
379 EXPECT_CALL(visitor_
, OnWriteBlocked(&time_wait_list_manager_
));
380 ProcessPacket(connection_id
, packet_number
);
381 // 3rd packet. No public reset should be sent;
382 ProcessPacket(connection_id
, packet_number
);
384 // write packet should not be called since we are write blocked but the
386 QuicConnectionId other_connection_id
= 2;
387 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(other_connection_id
));
388 AddConnectionId(other_connection_id
);
389 QuicPacketNumber other_packet_number
= 23423;
390 scoped_ptr
<QuicEncryptedPacket
> other_packet(ConstructEncryptedPacket(
391 ENCRYPTION_NONE
, other_connection_id
, other_packet_number
));
392 EXPECT_CALL(writer_
, WritePacket(_
, _
, _
, _
))
394 EXPECT_CALL(visitor_
, OnWriteBlocked(&time_wait_list_manager_
));
395 ProcessPacket(other_connection_id
, other_packet_number
);
396 EXPECT_EQ(2u, time_wait_list_manager_
.num_connections());
398 // Now expect all the write blocked public reset packets to be sent again.
399 writer_is_blocked_
= false;
401 WritePacket(_
, _
, server_address_
.address(), client_address_
))
402 .With(Args
<0, 1>(PublicResetPacketEq(connection_id
, packet_number
)))
403 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, packet
->length())));
405 WritePacket(_
, _
, server_address_
.address(), client_address_
))
407 PublicResetPacketEq(other_connection_id
, other_packet_number
)))
408 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, other_packet
->length())));
409 time_wait_list_manager_
.OnCanWrite();
412 TEST_F(QuicTimeWaitListManagerTest
, GetQuicVersionFromMap
) {
413 const int kConnectionId1
= 123;
414 const int kConnectionId2
= 456;
415 const int kConnectionId3
= 789;
417 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(kConnectionId1
));
418 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(kConnectionId2
));
419 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(kConnectionId3
));
420 AddConnectionId(kConnectionId1
, QuicVersionMin(),
421 /*connection_rejected_statelessly=*/false, nullptr);
422 AddConnectionId(kConnectionId2
, QuicVersionMax(),
423 /*connection_rejected_statelessly=*/false, nullptr);
424 AddConnectionId(kConnectionId3
, QuicVersionMax(),
425 /*connection_rejected_statelessly=*/false, nullptr);
427 EXPECT_EQ(QuicVersionMin(),
428 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
429 &time_wait_list_manager_
, kConnectionId1
));
430 EXPECT_EQ(QuicVersionMax(),
431 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
432 &time_wait_list_manager_
, kConnectionId2
));
433 EXPECT_EQ(QuicVersionMax(),
434 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
435 &time_wait_list_manager_
, kConnectionId3
));
438 TEST_F(QuicTimeWaitListManagerTest
, AddConnectionIdTwice
) {
439 // Add connection_ids such that their expiry time is time_wait_period_.
440 epoll_server_
.set_now_in_usec(0);
441 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id_
));
442 AddConnectionId(connection_id_
);
443 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_
));
444 const size_t kConnectionCloseLength
= 100;
445 AddConnectionId(connection_id_
, QuicVersionMax(),
446 /*connection_rejected_statelessly=*/false,
447 new QuicEncryptedPacket(new char[kConnectionCloseLength
],
448 kConnectionCloseLength
, true));
449 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_
));
450 EXPECT_EQ(1u, time_wait_list_manager_
.num_connections());
452 EXPECT_CALL(writer_
, WritePacket(_
,
453 kConnectionCloseLength
,
454 server_address_
.address(),
456 .WillOnce(Return(WriteResult(WRITE_STATUS_OK
, 1)));
458 const int kRandomSequenceNumber
= 1;
459 ProcessPacket(connection_id_
, kRandomSequenceNumber
);
461 const QuicTime::Delta time_wait_period
=
462 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_
);
464 QuicTime::Delta offset
= QuicTime::Delta::FromMicroseconds(39);
465 // Now set the current time as time_wait_period + offset usecs.
466 epoll_server_
.set_now_in_usec(time_wait_period
.Add(offset
).ToMicroseconds());
467 // After the connection_ids are cleaned up, check the next alarm interval.
468 int64 next_alarm_time
= epoll_server_
.ApproximateNowInUsec() +
469 time_wait_period
.ToMicroseconds();
471 EXPECT_CALL(epoll_server_
, RegisterAlarm(next_alarm_time
, _
));
472 EXPECT_CALL(visitor_
, OnConnectionRemovedFromTimeWaitList(connection_id_
));
473 time_wait_list_manager_
.CleanUpOldConnectionIds();
474 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_
));
475 EXPECT_EQ(0u, time_wait_list_manager_
.num_connections());
478 TEST_F(QuicTimeWaitListManagerTest
, ConnectionIdsOrderedByTime
) {
479 // Simple randomization: the values of connection_ids are swapped based on the
480 // current seconds on the clock. If the container is broken, the test will be
482 int odd_second
= static_cast<int>(epoll_server_
.ApproximateNowInUsec()) % 2;
483 EXPECT_TRUE(odd_second
== 0 || odd_second
== 1);
484 const QuicConnectionId connection_id1
= odd_second
;
485 const QuicConnectionId connection_id2
= 1 - odd_second
;
487 // 1 will hash lower than 2, but we add it later. They should come out in the
488 // add order, not hash order.
489 epoll_server_
.set_now_in_usec(0);
490 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id1
));
491 AddConnectionId(connection_id1
);
492 epoll_server_
.set_now_in_usec(10);
493 EXPECT_CALL(visitor_
, OnConnectionAddedToTimeWaitList(connection_id2
));
494 AddConnectionId(connection_id2
);
495 EXPECT_EQ(2u, time_wait_list_manager_
.num_connections());
497 const QuicTime::Delta time_wait_period
=
498 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_
);
499 epoll_server_
.set_now_in_usec(time_wait_period
.ToMicroseconds() + 1);
501 EXPECT_CALL(epoll_server_
, RegisterAlarm(_
, _
));
503 EXPECT_CALL(visitor_
, OnConnectionRemovedFromTimeWaitList(connection_id1
));
504 time_wait_list_manager_
.CleanUpOldConnectionIds();
505 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1
));
506 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2
));
507 EXPECT_EQ(1u, time_wait_list_manager_
.num_connections());
510 TEST_F(QuicTimeWaitListManagerTest
, MaxConnectionsTest
) {
511 // Basically, shut off time-based eviction.
512 FLAGS_quic_time_wait_list_seconds
= 10000000000;
513 FLAGS_quic_time_wait_list_max_connections
= 5;
515 QuicConnectionId current_connection_id
= 0;
516 // Add exactly the maximum number of connections
517 for (int64 i
= 0; i
< FLAGS_quic_time_wait_list_max_connections
; ++i
) {
518 ++current_connection_id
;
519 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id
));
520 EXPECT_CALL(visitor_
,
521 OnConnectionAddedToTimeWaitList(current_connection_id
));
522 AddConnectionId(current_connection_id
);
523 EXPECT_EQ(current_connection_id
, time_wait_list_manager_
.num_connections());
524 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id
));
527 // Now keep adding. Since we're already at the max, every new connection-id
528 // will evict the oldest one.
529 for (int64 i
= 0; i
< FLAGS_quic_time_wait_list_max_connections
; ++i
) {
530 ++current_connection_id
;
531 const QuicConnectionId id_to_evict
=
532 current_connection_id
- FLAGS_quic_time_wait_list_max_connections
;
533 EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict
));
534 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id
));
535 EXPECT_CALL(visitor_
, OnConnectionRemovedFromTimeWaitList(id_to_evict
));
536 EXPECT_CALL(visitor_
,
537 OnConnectionAddedToTimeWaitList(current_connection_id
));
538 AddConnectionId(current_connection_id
);
539 EXPECT_EQ(static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections
),
540 time_wait_list_manager_
.num_connections());
541 EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict
));
542 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id
));