| 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 |