OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_time_wait_list_manager.h" | 5 #include "net/tools/quic/quic_time_wait_list_manager.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <memory> | 8 #include <memory> |
9 #include <ostream> | 9 #include <ostream> |
10 | 10 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 bool connection_rejected_statelessly, | 107 bool connection_rejected_statelessly, |
108 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) { | 108 std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) { |
109 time_wait_list_manager_.AddConnectionIdToTimeWait( | 109 time_wait_list_manager_.AddConnectionIdToTimeWait( |
110 connection_id, version, connection_rejected_statelessly, packets); | 110 connection_id, version, connection_rejected_statelessly, packets); |
111 } | 111 } |
112 | 112 |
113 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) { | 113 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) { |
114 return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id); | 114 return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id); |
115 } | 115 } |
116 | 116 |
117 void ProcessPacket(QuicConnectionId connection_id, | 117 void ProcessPacket(QuicConnectionId connection_id) { |
118 QuicPacketNumber packet_number) { | |
119 QuicEncryptedPacket packet(nullptr, 0); | 118 QuicEncryptedPacket packet(nullptr, 0); |
120 time_wait_list_manager_.ProcessPacket(server_address_, client_address_, | 119 time_wait_list_manager_.ProcessPacket(server_address_, client_address_, |
121 connection_id, packet_number, packet); | 120 connection_id, packet); |
122 } | 121 } |
123 | 122 |
124 QuicEncryptedPacket* ConstructEncryptedPacket( | 123 QuicEncryptedPacket* ConstructEncryptedPacket( |
125 QuicConnectionId connection_id, | 124 QuicConnectionId connection_id, |
126 QuicPacketNumber packet_number) { | 125 QuicPacketNumber packet_number) { |
127 return net::test::ConstructEncryptedPacket(connection_id, false, false, | 126 return net::test::ConstructEncryptedPacket(connection_id, false, false, |
128 packet_number, "data"); | 127 packet_number, "data"); |
129 } | 128 } |
130 | 129 |
131 QuicFlagSaver flags_; // Save/restore all QUIC flag values. | 130 QuicFlagSaver flags_; // Save/restore all QUIC flag values. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) { | 210 TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) { |
212 const size_t kConnectionCloseLength = 100; | 211 const size_t kConnectionCloseLength = 100; |
213 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); | 212 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); |
214 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; | 213 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; |
215 termination_packets.push_back( | 214 termination_packets.push_back( |
216 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( | 215 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( |
217 new char[kConnectionCloseLength], kConnectionCloseLength, true))); | 216 new char[kConnectionCloseLength], kConnectionCloseLength, true))); |
218 AddConnectionId(connection_id_, QuicVersionMax(), | 217 AddConnectionId(connection_id_, QuicVersionMax(), |
219 /*connection_rejected_statelessly=*/false, | 218 /*connection_rejected_statelessly=*/false, |
220 &termination_packets); | 219 &termination_packets); |
221 const int kRandomSequenceNumber = 1; | |
222 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, | 220 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, |
223 server_address_.host(), client_address_, _)) | 221 server_address_.host(), client_address_, _)) |
224 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); | 222 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); |
225 | 223 |
226 ProcessPacket(connection_id_, kRandomSequenceNumber); | 224 ProcessPacket(connection_id_); |
227 } | 225 } |
228 | 226 |
229 TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) { | 227 TEST_F(QuicTimeWaitListManagerTest, SendTwoConnectionCloses) { |
230 const size_t kConnectionCloseLength = 100; | 228 const size_t kConnectionCloseLength = 100; |
231 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); | 229 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); |
232 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; | 230 std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets; |
233 termination_packets.push_back( | 231 termination_packets.push_back( |
234 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( | 232 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( |
235 new char[kConnectionCloseLength], kConnectionCloseLength, true))); | 233 new char[kConnectionCloseLength], kConnectionCloseLength, true))); |
236 termination_packets.push_back( | 234 termination_packets.push_back( |
237 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( | 235 std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket( |
238 new char[kConnectionCloseLength], kConnectionCloseLength, true))); | 236 new char[kConnectionCloseLength], kConnectionCloseLength, true))); |
239 AddConnectionId(connection_id_, QuicVersionMax(), | 237 AddConnectionId(connection_id_, QuicVersionMax(), |
240 /*connection_rejected_statelessly=*/false, | 238 /*connection_rejected_statelessly=*/false, |
241 &termination_packets); | 239 &termination_packets); |
242 const int kRandomSequenceNumber = 1; | |
243 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, | 240 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, |
244 server_address_.host(), client_address_, _)) | 241 server_address_.host(), client_address_, _)) |
245 .Times(2) | 242 .Times(2) |
246 .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1))); | 243 .WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1))); |
247 | 244 |
248 ProcessPacket(connection_id_, kRandomSequenceNumber); | 245 ProcessPacket(connection_id_); |
249 } | 246 } |
250 | 247 |
251 TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) { | 248 TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) { |
252 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); | 249 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); |
253 AddConnectionId(connection_id_); | 250 AddConnectionId(connection_id_); |
254 const int kRandomSequenceNumber = 1; | |
255 EXPECT_CALL(writer_, | 251 EXPECT_CALL(writer_, |
256 WritePacket(_, _, server_address_.host(), client_address_, _)) | 252 WritePacket(_, _, server_address_.host(), client_address_, _)) |
257 .With(Args<0, 1>(PublicResetPacketEq(connection_id_))) | 253 .With(Args<0, 1>(PublicResetPacketEq(connection_id_))) |
258 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); | 254 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); |
259 | 255 |
260 ProcessPacket(connection_id_, kRandomSequenceNumber); | 256 ProcessPacket(connection_id_); |
261 } | 257 } |
262 | 258 |
263 TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) { | 259 TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) { |
264 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); | 260 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); |
265 AddConnectionId(connection_id_); | 261 AddConnectionId(connection_id_); |
266 EXPECT_EQ(1u, time_wait_list_manager_.num_connections()); | 262 EXPECT_EQ(1u, time_wait_list_manager_.num_connections()); |
267 for (int packet_number = 1; packet_number < 101; ++packet_number) { | 263 for (int packet_number = 1; packet_number < 101; ++packet_number) { |
268 if ((packet_number & (packet_number - 1)) == 0) { | 264 if ((packet_number & (packet_number - 1)) == 0) { |
269 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) | 265 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)) |
270 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); | 266 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); |
271 } | 267 } |
272 ProcessPacket(connection_id_, packet_number); | 268 ProcessPacket(connection_id_); |
273 // Send public reset with exponential back off. | 269 // Send public reset with exponential back off. |
274 if ((packet_number & (packet_number - 1)) == 0) { | 270 if ((packet_number & (packet_number - 1)) == 0) { |
275 EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse( | 271 EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse( |
276 &time_wait_list_manager_, packet_number)); | 272 &time_wait_list_manager_, packet_number)); |
277 } else { | 273 } else { |
278 EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse( | 274 EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse( |
279 &time_wait_list_manager_, packet_number)); | 275 &time_wait_list_manager_, packet_number)); |
280 } | 276 } |
281 } | 277 } |
282 } | 278 } |
283 | 279 |
284 TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) { | 280 TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) { |
285 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); | 281 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_)); |
286 AddStatelessConnectionId(connection_id_); | 282 AddStatelessConnectionId(connection_id_); |
287 const int kRandomSequenceNumber = 1; | |
288 | 283 |
289 EXPECT_CALL(writer_, | 284 EXPECT_CALL(writer_, |
290 WritePacket(_, _, server_address_.host(), client_address_, _)) | 285 WritePacket(_, _, server_address_.host(), client_address_, _)) |
291 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); | 286 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); |
292 | 287 |
293 ProcessPacket(connection_id_, kRandomSequenceNumber); | 288 ProcessPacket(connection_id_); |
294 } | 289 } |
295 | 290 |
296 TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) { | 291 TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) { |
297 const size_t kConnectionIdCount = 100; | 292 const size_t kConnectionIdCount = 100; |
298 const size_t kOldConnectionIdCount = 31; | 293 const size_t kOldConnectionIdCount = 31; |
299 | 294 |
300 // Add connection_ids such that their expiry time is time_wait_period_. | 295 // Add connection_ids such that their expiry time is time_wait_period_. |
301 epoll_server_.set_now_in_usec(0); | 296 epoll_server_.set_now_in_usec(0); |
302 for (size_t connection_id = 1; connection_id <= kOldConnectionIdCount; | 297 for (size_t connection_id = 1; connection_id <= kOldConnectionIdCount; |
303 ++connection_id) { | 298 ++connection_id) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id)); | 339 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id)); |
345 AddConnectionId(connection_id); | 340 AddConnectionId(connection_id); |
346 QuicPacketNumber packet_number = 234; | 341 QuicPacketNumber packet_number = 234; |
347 std::unique_ptr<QuicEncryptedPacket> packet( | 342 std::unique_ptr<QuicEncryptedPacket> packet( |
348 ConstructEncryptedPacket(connection_id, packet_number)); | 343 ConstructEncryptedPacket(connection_id, packet_number)); |
349 // Let first write through. | 344 // Let first write through. |
350 EXPECT_CALL(writer_, | 345 EXPECT_CALL(writer_, |
351 WritePacket(_, _, server_address_.host(), client_address_, _)) | 346 WritePacket(_, _, server_address_.host(), client_address_, _)) |
352 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) | 347 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) |
353 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); | 348 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); |
354 ProcessPacket(connection_id, packet_number); | 349 ProcessPacket(connection_id); |
355 | 350 |
356 // write block for the next packet. | 351 // write block for the next packet. |
357 EXPECT_CALL(writer_, | 352 EXPECT_CALL(writer_, |
358 WritePacket(_, _, server_address_.host(), client_address_, _)) | 353 WritePacket(_, _, server_address_.host(), client_address_, _)) |
359 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) | 354 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) |
360 .WillOnce(DoAll(Assign(&writer_is_blocked_, true), | 355 .WillOnce(DoAll(Assign(&writer_is_blocked_, true), |
361 Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN)))); | 356 Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN)))); |
362 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_)); | 357 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_)); |
363 ProcessPacket(connection_id, packet_number); | 358 ProcessPacket(connection_id); |
364 // 3rd packet. No public reset should be sent; | 359 // 3rd packet. No public reset should be sent; |
365 ProcessPacket(connection_id, packet_number); | 360 ProcessPacket(connection_id); |
366 | 361 |
367 // write packet should not be called since we are write blocked but the | 362 // write packet should not be called since we are write blocked but the |
368 // should be queued. | 363 // should be queued. |
369 QuicConnectionId other_connection_id = 2; | 364 QuicConnectionId other_connection_id = 2; |
370 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id)); | 365 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id)); |
371 AddConnectionId(other_connection_id); | 366 AddConnectionId(other_connection_id); |
372 QuicPacketNumber other_packet_number = 23423; | 367 QuicPacketNumber other_packet_number = 23423; |
373 std::unique_ptr<QuicEncryptedPacket> other_packet( | 368 std::unique_ptr<QuicEncryptedPacket> other_packet( |
374 ConstructEncryptedPacket(other_connection_id, other_packet_number)); | 369 ConstructEncryptedPacket(other_connection_id, other_packet_number)); |
375 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0); | 370 EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0); |
376 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_)); | 371 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_)); |
377 ProcessPacket(other_connection_id, other_packet_number); | 372 ProcessPacket(other_connection_id); |
378 EXPECT_EQ(2u, time_wait_list_manager_.num_connections()); | 373 EXPECT_EQ(2u, time_wait_list_manager_.num_connections()); |
379 | 374 |
380 // Now expect all the write blocked public reset packets to be sent again. | 375 // Now expect all the write blocked public reset packets to be sent again. |
381 writer_is_blocked_ = false; | 376 writer_is_blocked_ = false; |
382 EXPECT_CALL(writer_, | 377 EXPECT_CALL(writer_, |
383 WritePacket(_, _, server_address_.host(), client_address_, _)) | 378 WritePacket(_, _, server_address_.host(), client_address_, _)) |
384 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) | 379 .With(Args<0, 1>(PublicResetPacketEq(connection_id))) |
385 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); | 380 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length()))); |
386 EXPECT_CALL(writer_, | 381 EXPECT_CALL(writer_, |
387 WritePacket(_, _, server_address_.host(), client_address_, _)) | 382 WritePacket(_, _, server_address_.host(), client_address_, _)) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 AddConnectionId(connection_id_, QuicVersionMax(), | 425 AddConnectionId(connection_id_, QuicVersionMax(), |
431 /*connection_rejected_statelessly=*/false, | 426 /*connection_rejected_statelessly=*/false, |
432 &termination_packets); | 427 &termination_packets); |
433 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_)); | 428 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_)); |
434 EXPECT_EQ(1u, time_wait_list_manager_.num_connections()); | 429 EXPECT_EQ(1u, time_wait_list_manager_.num_connections()); |
435 | 430 |
436 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, | 431 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength, |
437 server_address_.host(), client_address_, _)) | 432 server_address_.host(), client_address_, _)) |
438 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); | 433 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); |
439 | 434 |
440 const int kRandomSequenceNumber = 1; | 435 ProcessPacket(connection_id_); |
441 ProcessPacket(connection_id_, kRandomSequenceNumber); | |
442 | 436 |
443 const QuicTime::Delta time_wait_period = | 437 const QuicTime::Delta time_wait_period = |
444 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_); | 438 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_); |
445 | 439 |
446 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39); | 440 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39); |
447 // Now set the current time as time_wait_period + offset usecs. | 441 // Now set the current time as time_wait_period + offset usecs. |
448 epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds()); | 442 epoll_server_.set_now_in_usec((time_wait_period + offset).ToMicroseconds()); |
449 // After the connection_ids are cleaned up, check the next alarm interval. | 443 // After the connection_ids are cleaned up, check the next alarm interval. |
450 int64_t next_alarm_time = | 444 int64_t next_alarm_time = |
451 epoll_server_.ApproximateNowInUsec() + time_wait_period.ToMicroseconds(); | 445 epoll_server_.ApproximateNowInUsec() + time_wait_period.ToMicroseconds(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 EXPECT_EQ(static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections), | 512 EXPECT_EQ(static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections), |
519 time_wait_list_manager_.num_connections()); | 513 time_wait_list_manager_.num_connections()); |
520 EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict)); | 514 EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict)); |
521 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id)); | 515 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id)); |
522 } | 516 } |
523 } | 517 } |
524 | 518 |
525 } // namespace | 519 } // namespace |
526 } // namespace test | 520 } // namespace test |
527 } // namespace net | 521 } // namespace net |
OLD | NEW |