1 // Copyright (c) 2012 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/quic/quic_connection_helper.h" 6 7 #include <vector> 8 9 #include "net/base/net_errors.h" 10 #include "net/quic/crypto/quic_decrypter.h" 11 #include "net/quic/crypto/quic_encrypter.h" 12 #include "net/quic/test_tools/mock_clock.h" 13 #include "net/quic/test_tools/quic_connection_peer.h" 14 #include "net/quic/test_tools/quic_test_utils.h" 15 #include "net/quic/test_tools/test_task_runner.h" 16 #include "net/socket/socket_test_util.h" 17 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 using testing::_; 21 22 namespace net { 23 namespace test { 24 25 const char kData[] = "foo"; 26 const bool kFromPeer = true; 27 28 class TestDelegate : public QuicAlarm::Delegate { 29 public: 30 TestDelegate() : fired_(false) {} 31 32 virtual QuicTime OnAlarm() OVERRIDE { 33 fired_ = true; 34 return QuicTime::Zero(); 35 } 36 37 bool fired() const { return fired_; } 38 39 private: 40 bool fired_; 41 }; 42 43 class TestConnection : public QuicConnection { 44 public: 45 TestConnection(QuicGuid guid, 46 IPEndPoint address, 47 QuicConnectionHelper* helper) 48 : QuicConnection(guid, address, helper, false, QuicVersionMax()) { 49 } 50 51 void SendAck() { 52 QuicConnectionPeer::SendAck(this); 53 } 54 55 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { 56 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); 57 } 58 59 using QuicConnection::SendOrQueuePacket; 60 }; 61 62 class QuicConnectionHelperTest : public ::testing::Test { 63 protected: 64 // Holds a packet to be written to the wire, and the IO mode that should 65 // be used by the mock socket when performing the write. 66 struct PacketToWrite { 67 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) 68 : mode(mode), 69 packet(packet) { 70 } 71 IoMode mode; 72 QuicEncryptedPacket* packet; 73 }; 74 75 QuicConnectionHelperTest() 76 : guid_(2), 77 framer_(QuicVersionMax(), QuicTime::Zero(), false), 78 net_log_(BoundNetLog()), 79 frame_(1, false, 0, kData) { 80 Initialize(); 81 } 82 83 ~QuicConnectionHelperTest() { 84 for (size_t i = 0; i < writes_.size(); i++) { 85 delete writes_[i].packet; 86 } 87 } 88 89 // Adds a packet to the list of expected writes. 90 void AddWrite(IoMode mode, QuicEncryptedPacket* packet) { 91 writes_.push_back(PacketToWrite(mode, packet)); 92 } 93 94 // Returns the packet to be written at position |pos|. 95 QuicEncryptedPacket* GetWrite(size_t pos) { 96 return writes_[pos].packet; 97 } 98 99 bool AtEof() { 100 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); 101 } 102 103 // Configures the test fixture to use the list of expected writes. 104 void Initialize() { 105 mock_writes_.reset(new MockWrite[writes_.size()]); 106 for (size_t i = 0; i < writes_.size(); i++) { 107 mock_writes_[i] = MockWrite(writes_[i].mode, 108 writes_[i].packet->data(), 109 writes_[i].packet->length()); 110 }; 111 112 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), 113 writes_.size())); 114 115 socket_.reset(new MockUDPClientSocket(socket_data_.get(), 116 net_log_.net_log())); 117 socket_->Connect(IPEndPoint()); 118 runner_ = new TestTaskRunner(&clock_); 119 helper_ = new QuicConnectionHelper(runner_.get(), &clock_, 120 &random_generator_, socket_.get()); 121 send_algorithm_ = new testing::StrictMock<MockSendAlgorithm>(); 122 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). 123 WillRepeatedly(testing::Return(QuicTime::Delta::Zero())); 124 connection_.reset(new TestConnection(guid_, IPEndPoint(), helper_)); 125 connection_->set_visitor(&visitor_); 126 connection_->SetSendAlgorithm(send_algorithm_); 127 } 128 129 // Returns a newly created packet to send kData on stream 1. 130 QuicEncryptedPacket* ConstructDataPacket( 131 QuicPacketSequenceNumber sequence_number) { 132 InitializeHeader(sequence_number); 133 134 return ConstructPacket(header_, QuicFrame(&frame_)); 135 } 136 137 // Returns a newly created packet to send kData on stream 1. 138 QuicPacket* ConstructRawDataPacket( 139 QuicPacketSequenceNumber sequence_number) { 140 InitializeHeader(sequence_number); 141 142 QuicFrames frames; 143 frames.push_back(QuicFrame(&frame_)); 144 return framer_.BuildUnsizedDataPacket(header_, frames).packet; 145 } 146 147 // Returns a newly created packet to send ack data. 148 QuicEncryptedPacket* ConstructAckPacket( 149 QuicPacketSequenceNumber sequence_number) { 150 InitializeHeader(sequence_number); 151 152 QuicAckFrame ack(0, QuicTime::Zero(), sequence_number); 153 ack.sent_info.entropy_hash = 0; 154 ack.received_info.entropy_hash = 0; 155 156 QuicCongestionFeedbackFrame feedback; 157 feedback.type = kTCP; 158 feedback.tcp.accumulated_number_of_lost_packets = 0; 159 feedback.tcp.receive_window = 16000 << 4; 160 161 QuicFrames frames; 162 frames.push_back(QuicFrame(&ack)); 163 frames.push_back(QuicFrame(&feedback)); 164 scoped_ptr<QuicPacket> packet( 165 framer_.BuildUnsizedDataPacket(header_, frames).packet); 166 return framer_.EncryptPacket( 167 ENCRYPTION_NONE, header_.packet_sequence_number, *packet); 168 } 169 170 // Returns a newly created packet to send a connection close frame. 171 QuicEncryptedPacket* ConstructClosePacket( 172 QuicPacketSequenceNumber sequence_number, 173 QuicPacketSequenceNumber least_waiting) { 174 InitializeHeader(sequence_number); 175 176 QuicFrames frames; 177 QuicAckFrame ack(0, QuicTime::Zero(), least_waiting + 1); 178 ack.sent_info.entropy_hash = 0; 179 ack.received_info.entropy_hash = 0; 180 QuicConnectionCloseFrame close; 181 close.error_code = QUIC_CONNECTION_TIMED_OUT; 182 close.ack_frame = ack; 183 184 return ConstructPacket(header_, QuicFrame(&close)); 185 } 186 187 testing::StrictMock<MockSendAlgorithm>* send_algorithm_; 188 scoped_refptr<TestTaskRunner> runner_; 189 QuicConnectionHelper* helper_; 190 scoped_ptr<MockUDPClientSocket> socket_; 191 scoped_ptr<MockWrite[]> mock_writes_; 192 MockClock clock_; 193 MockRandom random_generator_; 194 scoped_ptr<TestConnection> connection_; 195 testing::StrictMock<MockConnectionVisitor> visitor_; 196 197 private: 198 void InitializeHeader(QuicPacketSequenceNumber sequence_number) { 199 header_.public_header.guid = guid_; 200 header_.public_header.reset_flag = false; 201 header_.public_header.version_flag = true; 202 header_.packet_sequence_number = sequence_number; 203 header_.entropy_flag = false; 204 header_.fec_flag = false; 205 header_.is_in_fec_group = NOT_IN_FEC_GROUP; 206 header_.fec_group = 0; 207 } 208 209 QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header, 210 const QuicFrame& frame) { 211 QuicFrames frames; 212 frames.push_back(frame); 213 scoped_ptr<QuicPacket> packet( 214 framer_.BuildUnsizedDataPacket(header_, frames).packet); 215 return framer_.EncryptPacket( 216 ENCRYPTION_NONE, header_.packet_sequence_number, *packet); 217 } 218 219 QuicGuid guid_; 220 QuicFramer framer_; 221 QuicPacketHeader header_; 222 BoundNetLog net_log_; 223 QuicStreamFrame frame_; 224 scoped_ptr<StaticSocketDataProvider> socket_data_; 225 std::vector<PacketToWrite> writes_; 226 }; 227 228 TEST_F(QuicConnectionHelperTest, GetClock) { 229 EXPECT_EQ(&clock_, helper_->GetClock()); 230 } 231 232 TEST_F(QuicConnectionHelperTest, GetRandomGenerator) { 233 EXPECT_EQ(&random_generator_, helper_->GetRandomGenerator()); 234 } 235 236 TEST_F(QuicConnectionHelperTest, CreateAlarm) { 237 TestDelegate* delegate = new TestDelegate(); 238 scoped_ptr<QuicAlarm> alarm(helper_->CreateAlarm(delegate)); 239 240 // The timeout alarm task is always posted. 241 ASSERT_EQ(1u, runner_->GetPostedTasks().size()); 242 243 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); 244 alarm->Set(clock_.Now().Add(delta)); 245 246 // Verify that the alarm task has been posted. 247 ASSERT_EQ(2u, runner_->GetPostedTasks().size()); 248 EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()), 249 runner_->GetPostedTasks()[1].delay); 250 251 runner_->RunNextTask(); 252 EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now()); 253 EXPECT_TRUE(delegate->fired()); 254 } 255 256 TEST_F(QuicConnectionHelperTest, CreateAlarmAndCancel) { 257 TestDelegate* delegate = new TestDelegate(); 258 scoped_ptr<QuicAlarm> alarm(helper_->CreateAlarm(delegate)); 259 260 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); 261 alarm->Set(clock_.Now().Add(delta)); 262 alarm->Cancel(); 263 264 // The alarm task should still be posted. 265 ASSERT_EQ(2u, runner_->GetPostedTasks().size()); 266 EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()), 267 runner_->GetPostedTasks()[1].delay); 268 269 runner_->RunNextTask(); 270 EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now()); 271 EXPECT_FALSE(delegate->fired()); 272 } 273 274 TEST_F(QuicConnectionHelperTest, CreateAlarmAndReset) { 275 TestDelegate* delegate = new TestDelegate(); 276 scoped_ptr<QuicAlarm> alarm(helper_->CreateAlarm(delegate)); 277 278 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); 279 alarm->Set(clock_.Now().Add(delta)); 280 alarm->Cancel(); 281 QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3); 282 alarm->Set(clock_.Now().Add(new_delta)); 283 284 // The alarm task should still be posted. 285 ASSERT_EQ(2u, runner_->GetPostedTasks().size()); 286 EXPECT_EQ(base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()), 287 runner_->GetPostedTasks()[1].delay); 288 289 runner_->RunNextTask(); 290 EXPECT_EQ(QuicTime::Zero().Add(delta), clock_.Now()); 291 EXPECT_FALSE(delegate->fired()); 292 293 // The alarm task should be posted again. 294 ASSERT_EQ(2u, runner_->GetPostedTasks().size()); 295 296 runner_->RunNextTask(); 297 EXPECT_EQ(QuicTime::Zero().Add(new_delta), clock_.Now()); 298 EXPECT_TRUE(delegate->fired()); 299 } 300 301 TEST_F(QuicConnectionHelperTest, TestRetransmission) { 302 AddWrite(SYNCHRONOUS, ConstructDataPacket(1)); 303 AddWrite(SYNCHRONOUS, ConstructDataPacket(2)); 304 Initialize(); 305 306 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( 307 testing::Return(QuicTime::Delta::Zero())); 308 309 QuicTime::Delta kDefaultRetransmissionTime = 310 QuicTime::Delta::FromMilliseconds(500); 311 QuicTime start = clock_.ApproximateNow(); 312 313 EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION)); 314 EXPECT_CALL(*send_algorithm_, AbandoningPacket(1, _)); 315 // Send a packet. 316 connection_->SendStreamData(1, kData, 0, false); 317 EXPECT_CALL(*send_algorithm_, SentPacket(_, 2, _, IS_RETRANSMISSION)); 318 // Since no ack was received, the retransmission alarm will fire and 319 // retransmit it. 320 runner_->RunNextTask(); 321 322 EXPECT_EQ(kDefaultRetransmissionTime, 323 clock_.ApproximateNow().Subtract(start)); 324 EXPECT_TRUE(AtEof()); 325 } 326 327 TEST_F(QuicConnectionHelperTest, TestMultipleRetransmission) { 328 AddWrite(SYNCHRONOUS, ConstructDataPacket(1)); 329 AddWrite(SYNCHRONOUS, ConstructDataPacket(2)); 330 AddWrite(SYNCHRONOUS, ConstructDataPacket(3)); 331 Initialize(); 332 333 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( 334 testing::Return(QuicTime::Delta::Zero())); 335 336 QuicTime::Delta kDefaultRetransmissionTime = 337 QuicTime::Delta::FromMilliseconds(500); 338 QuicTime start = clock_.ApproximateNow(); 339 340 EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION)); 341 EXPECT_CALL(*send_algorithm_, AbandoningPacket(1, _)); 342 // Send a packet. 343 connection_->SendStreamData(1, kData, 0, false); 344 EXPECT_CALL(*send_algorithm_, SentPacket(_, 2, _, IS_RETRANSMISSION)); 345 // Since no ack was received, the retransmission alarm will fire and 346 // retransmit it. 347 runner_->RunNextTask(); 348 349 EXPECT_EQ(kDefaultRetransmissionTime, 350 clock_.ApproximateNow().Subtract(start)); 351 352 // Since no ack was received, the retransmission alarm will fire and 353 // retransmit it. 354 EXPECT_CALL(*send_algorithm_, SentPacket(_, 3, _, IS_RETRANSMISSION)); 355 EXPECT_CALL(*send_algorithm_, AbandoningPacket(2, _)); 356 runner_->RunNextTask(); 357 358 EXPECT_EQ(kDefaultRetransmissionTime.Add(kDefaultRetransmissionTime), 359 clock_.ApproximateNow().Subtract(start)); 360 361 EXPECT_TRUE(AtEof()); 362 } 363 364 TEST_F(QuicConnectionHelperTest, InitialTimeout) { 365 AddWrite(SYNCHRONOUS, ConstructClosePacket(1, 0)); 366 Initialize(); 367 368 // Verify that a single task was posted. 369 ASSERT_EQ(1u, runner_->GetPostedTasks().size()); 370 EXPECT_EQ(base::TimeDelta::FromSeconds(kDefaultInitialTimeoutSecs), 371 runner_->GetPostedTasks().front().delay); 372 373 EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION)); 374 // After we run the next task, we should close the connection. 375 EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, false)); 376 377 runner_->RunNextTask(); 378 EXPECT_EQ(QuicTime::Zero().Add(QuicTime::Delta::FromSeconds( 379 kDefaultInitialTimeoutSecs)), 380 clock_.ApproximateNow()); 381 EXPECT_FALSE(connection_->connected()); 382 EXPECT_TRUE(AtEof()); 383 } 384 385 TEST_F(QuicConnectionHelperTest, WritePacketToWire) { 386 AddWrite(SYNCHRONOUS, ConstructDataPacket(1)); 387 Initialize(); 388 389 int len = GetWrite(0)->length(); 390 int error = 0; 391 EXPECT_EQ(len, helper_->WritePacketToWire(*GetWrite(0), &error)); 392 EXPECT_EQ(0, error); 393 EXPECT_TRUE(AtEof()); 394 } 395 396 TEST_F(QuicConnectionHelperTest, WritePacketToWireAsync) { 397 AddWrite(ASYNC, ConstructClosePacket(1, 0)); 398 Initialize(); 399 400 EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(testing::Return(true)); 401 int error = 0; 402 EXPECT_EQ(-1, helper_->WritePacketToWire(*GetWrite(0), &error)); 403 EXPECT_EQ(ERR_IO_PENDING, error); 404 base::MessageLoop::current()->RunUntilIdle(); 405 EXPECT_TRUE(AtEof()); 406 } 407 408 TEST_F(QuicConnectionHelperTest, TimeoutAfterSend) { 409 AddWrite(SYNCHRONOUS, ConstructAckPacket(1)); 410 AddWrite(SYNCHRONOUS, ConstructClosePacket(2, 1)); 411 Initialize(); 412 413 EXPECT_TRUE(connection_->connected()); 414 QuicTime start = clock_.ApproximateNow(); 415 416 // When we send a packet, the timeout will change to 5000 + 417 // kDefaultInitialTimeoutSecs. 418 clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(5000)); 419 EXPECT_EQ(5000u, clock_.ApproximateNow().Subtract(start).ToMicroseconds()); 420 EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION)); 421 422 // Send an ack so we don't set the retransmission alarm. 423 connection_->SendAck(); 424 425 // The original alarm will fire. We should not time out because we had a 426 // network event at t=5000. The alarm will reregister. 427 runner_->RunNextTask(); 428 429 EXPECT_EQ(QuicTime::Zero().Add(QuicTime::Delta::FromSeconds( 430 kDefaultInitialTimeoutSecs)), 431 clock_.ApproximateNow()); 432 EXPECT_TRUE(connection_->connected()); 433 434 // This time, we should time out. 435 EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, !kFromPeer)); 436 EXPECT_CALL(*send_algorithm_, SentPacket(_, 2, _, NOT_RETRANSMISSION)); 437 runner_->RunNextTask(); 438 EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000 + 5000, 439 clock_.ApproximateNow().Subtract( 440 QuicTime::Zero()).ToMicroseconds()); 441 EXPECT_FALSE(connection_->connected()); 442 EXPECT_TRUE(AtEof()); 443 } 444 445 TEST_F(QuicConnectionHelperTest, SendSchedulerDelayThenSend) { 446 AddWrite(SYNCHRONOUS, ConstructDataPacket(1)); 447 Initialize(); 448 449 // Test that if we send a packet with a delay, it ends up queued. 450 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( 451 testing::Return(QuicTime::Delta::Zero())); 452 EXPECT_CALL( 453 *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce( 454 testing::Return(QuicTime::Delta::FromMicroseconds(1))); 455 456 QuicPacket* packet = ConstructRawDataPacket(1); 457 connection_->SendOrQueuePacket( 458 ENCRYPTION_NONE, 1, packet, 0, HAS_RETRANSMITTABLE_DATA); 459 EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION)); 460 EXPECT_EQ(1u, connection_->NumQueuedPackets()); 461 462 // Advance the clock to fire the alarm, and configure the scheduler 463 // to permit the packet to be sent. 464 EXPECT_CALL(*send_algorithm_, 465 TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillRepeatedly( 466 testing::Return(QuicTime::Delta::Zero())); 467 EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(testing::Return(true)); 468 runner_->RunNextTask(); 469 EXPECT_EQ(0u, connection_->NumQueuedPackets()); 470 EXPECT_TRUE(AtEof()); 471 } 472 473 } // namespace test 474 } // namespace net 475