Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 // The maxiumum number of packets we'd like to queue. We may end up queueing | 51 // The maxiumum number of packets we'd like to queue. We may end up queueing |
| 52 // more in the case of many control frames. | 52 // more in the case of many control frames. |
| 53 // 6 is arbitrary. | 53 // 6 is arbitrary. |
| 54 const int kMaxPacketsToSerializeAtOnce = 6; | 54 const int kMaxPacketsToSerializeAtOnce = 6; |
| 55 | 55 |
| 56 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 56 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
| 57 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 57 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
| 58 return delta <= kMaxPacketGap; | 58 return delta <= kMaxPacketGap; |
| 59 } | 59 } |
| 60 | 60 |
| 61 QuicConnection::UnackedPacket::UnackedPacket(QuicFrames unacked_frames) | |
| 62 : frames(unacked_frames), | |
| 63 number_nacks(0) { | |
| 64 } | |
| 65 | |
| 66 QuicConnection::UnackedPacket::UnackedPacket(QuicFrames unacked_frames, | |
| 67 std::string data) | |
| 68 : frames(unacked_frames), | |
| 69 number_nacks(0), | |
| 70 data(data) { | |
| 71 } | |
| 72 | |
| 73 QuicConnection::UnackedPacket::~UnackedPacket() { | |
| 74 } | |
| 75 | |
| 61 QuicConnection::QuicConnection(QuicGuid guid, | 76 QuicConnection::QuicConnection(QuicGuid guid, |
| 62 IPEndPoint address, | 77 IPEndPoint address, |
| 63 QuicConnectionHelperInterface* helper) | 78 QuicConnectionHelperInterface* helper) |
| 64 : helper_(helper), | 79 : helper_(helper), |
| 65 framer_(QuicDecrypter::Create(kNULL), QuicEncrypter::Create(kNULL)), | 80 framer_(QuicDecrypter::Create(kNULL), QuicEncrypter::Create(kNULL)), |
| 66 clock_(helper->GetClock()), | 81 clock_(helper->GetClock()), |
| 67 random_generator_(helper->GetRandomGenerator()), | 82 random_generator_(helper->GetRandomGenerator()), |
| 68 guid_(guid), | 83 guid_(guid), |
| 69 peer_address_(address), | 84 peer_address_(address), |
| 70 should_send_ack_(false), | 85 should_send_ack_(false), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 92 /* | 107 /* |
| 93 if (FLAGS_fake_packet_loss_percentage > 0) { | 108 if (FLAGS_fake_packet_loss_percentage > 0) { |
| 94 int32 seed = RandomBase::WeakSeed32(); | 109 int32 seed = RandomBase::WeakSeed32(); |
| 95 LOG(INFO) << "Seeding packet loss with " << seed; | 110 LOG(INFO) << "Seeding packet loss with " << seed; |
| 96 random_.reset(new MTRandom(seed)); | 111 random_.reset(new MTRandom(seed)); |
| 97 } | 112 } |
| 98 */ | 113 */ |
| 99 } | 114 } |
| 100 | 115 |
| 101 QuicConnection::~QuicConnection() { | 116 QuicConnection::~QuicConnection() { |
| 102 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); | 117 for (UnackedPacketMap::iterator u = unacked_packets_.begin(); |
|
jar (doing other things)
2013/01/16 23:59:11
nit: avoid single letter variable names. Use of "
Ian Swett
2013/01/17 15:33:27
Agreed, that is a terrible name. I have no idea w
| |
| 103 it != unacked_packets_.end(); ++it) { | 118 u != unacked_packets_.end(); ++u) { |
| 104 delete it->second.packet; | 119 DeleteUnackedPacket(u->second); |
| 105 } | 120 } |
| 121 STLDeleteValues(&unacked_packets_); | |
|
jar (doing other things)
2013/01/16 23:59:11
nit: It seems strange to iterate over the map star
Ian Swett
2013/01/17 15:33:27
I hated writing it. I actually made a destructor,
jar (doing other things)
2013/01/17 16:14:33
+1 That would certainly help IMO.
| |
| 106 STLDeleteValues(&group_map_); | 122 STLDeleteValues(&group_map_); |
| 107 // Queued packets that are not to be resent are owned | |
| 108 // by the packet queue. | |
| 109 for (QueuedPacketList::iterator q = queued_packets_.begin(); | 123 for (QueuedPacketList::iterator q = queued_packets_.begin(); |
|
jar (doing other things)
2013/01/16 23:59:11
nit: "q" should be a better name (...yeah... ya'
Ian Swett
2013/01/17 15:33:27
Done.
| |
| 110 q != queued_packets_.end(); ++q) { | 124 q != queued_packets_.end(); ++q) { |
| 111 if (!q->resend) delete q->packet; | 125 delete q->packet; |
| 112 } | 126 } |
| 113 } | 127 } |
| 114 | 128 |
| 129 void QuicConnection::DeleteEnclosedFrame(QuicFrame* frame) { | |
| 130 switch (frame->type) { | |
| 131 case STREAM_FRAME: | |
| 132 delete frame->stream_frame; | |
| 133 break; | |
| 134 case ACK_FRAME: | |
| 135 delete frame->ack_frame; | |
| 136 break; | |
| 137 case CONGESTION_FEEDBACK_FRAME: | |
| 138 delete frame->congestion_feedback_frame; | |
| 139 break; | |
| 140 case RST_STREAM_FRAME: | |
| 141 delete frame->rst_stream_frame; | |
| 142 break; | |
| 143 case CONNECTION_CLOSE_FRAME: | |
| 144 delete frame->connection_close_frame; | |
| 145 break; | |
| 146 case PDU_FRAME: // Fall through. | |
| 147 case NUM_FRAME_TYPES: | |
| 148 DCHECK(false) << "Cannot delete type: " << frame->type; | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 void QuicConnection::DeleteUnackedPacket(UnackedPacket* unacked) { | |
| 153 for (QuicFrames::iterator it = unacked->frames.begin(); | |
| 154 it != unacked->frames.end(); ++it) { | |
| 155 DCHECK(ShouldResend(*it)); | |
| 156 DeleteEnclosedFrame(&(*it)); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 bool QuicConnection::ShouldResend(const QuicFrame& frame) { | |
| 161 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME; | |
| 162 } | |
| 163 | |
| 115 void QuicConnection::OnError(QuicFramer* framer) { | 164 void QuicConnection::OnError(QuicFramer* framer) { |
| 116 SendConnectionClose(framer->error()); | 165 SendConnectionClose(framer->error()); |
| 117 } | 166 } |
| 118 | 167 |
| 119 void QuicConnection::OnPacket(const IPEndPoint& self_address, | 168 void QuicConnection::OnPacket(const IPEndPoint& self_address, |
| 120 const IPEndPoint& peer_address) { | 169 const IPEndPoint& peer_address) { |
| 121 time_of_last_packet_ = clock_->Now(); | 170 time_of_last_packet_ = clock_->Now(); |
| 122 DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds(); | 171 DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds(); |
| 123 | 172 |
| 124 // TODO(alyssar, rch) handle migration! | 173 // TODO(alyssar, rch) handle migration! |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 int resent_packets = 0; | 312 int resent_packets = 0; |
| 264 | 313 |
| 265 // Go through the packets we have not received an ack for and see if this | 314 // Go through the packets we have not received an ack for and see if this |
| 266 // incoming_ack shows they've been seen by the peer. | 315 // incoming_ack shows they've been seen by the peer. |
| 267 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 316 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 268 while (it != unacked_packets_.end()) { | 317 while (it != unacked_packets_.end()) { |
| 269 if (!incoming_ack.received_info.IsAwaitingPacket(it->first)) { | 318 if (!incoming_ack.received_info.IsAwaitingPacket(it->first)) { |
| 270 // Packet was acked, so remove it from our unacked packet list. | 319 // Packet was acked, so remove it from our unacked packet list. |
| 271 DVLOG(1) << "Got an ack for " << it->first; | 320 DVLOG(1) << "Got an ack for " << it->first; |
| 272 // TODO(rch): This is inefficient and should be sped up. | 321 // TODO(rch): This is inefficient and should be sped up. |
| 322 // TODO(ianswett): Ensure this inner loop is applicable now that we're | |
| 323 // always sending packets with new sequence numbers. I believe it may | |
| 324 // only be relevant for the first crypto connect packet, which doesn't | |
| 325 // get a new packet sequence number. | |
| 273 // The acked packet might be queued (if a resend had been attempted). | 326 // The acked packet might be queued (if a resend had been attempted). |
| 274 for (QueuedPacketList::iterator q = queued_packets_.begin(); | 327 for (QueuedPacketList::iterator q = queued_packets_.begin(); |
| 275 q != queued_packets_.end(); ++q) { | 328 q != queued_packets_.end(); ++q) { |
| 276 if (q->sequence_number == it->first) { | 329 if (q->sequence_number == it->first) { |
| 277 queued_packets_.erase(q); | 330 queued_packets_.erase(q); |
| 278 break; | 331 break; |
| 279 } | 332 } |
| 280 } | 333 } |
| 281 acked_packets.insert(it->first); | 334 acked_packets.insert(it->first); |
| 282 delete it->second.packet; | 335 DeleteUnackedPacket(it->second); |
| 336 delete it->second; | |
| 283 UnackedPacketMap::iterator it_tmp = it; | 337 UnackedPacketMap::iterator it_tmp = it; |
| 284 ++it; | 338 ++it; |
| 285 unacked_packets_.erase(it_tmp); | 339 unacked_packets_.erase(it_tmp); |
| 286 } else { | 340 } else { |
| 287 // This is a packet which we planned on resending and has not been | 341 // This is a packet which we planned on resending and has not been |
| 288 // seen at the time of this ack being sent out. See if it's our new | 342 // seen at the time of this ack being sent out. See if it's our new |
| 289 // lowest unacked packet. | 343 // lowest unacked packet. |
| 290 DVLOG(1) << "still missing " << it->first; | 344 DVLOG(1) << "still missing " << it->first; |
| 291 if (it->first < lowest_unacked) { | 345 if (it->first < lowest_unacked) { |
| 292 lowest_unacked = it->first; | 346 lowest_unacked = it->first; |
| 293 } | 347 } |
| 294 | 348 |
| 295 // Determine if this packet is being explicitly nacked and, if so, if it | 349 // Determine if this packet is being explicitly nacked and, if so, if it |
| 296 // is worth resending. | 350 // is worth resending. |
| 297 QuicPacketSequenceNumber resend_number = 0; | 351 QuicPacketSequenceNumber resend_number = 0; |
| 298 if (it->first < peer_largest_observed_packet_) { | 352 if (it->first < peer_largest_observed_packet_) { |
| 299 // The peer got packets after this sequence number. This is an explicit | 353 // The peer got packets after this sequence number. This is an explicit |
| 300 // nack. | 354 // nack. |
| 301 ++(it->second.number_nacks); | 355 ++(it->second->number_nacks); |
| 302 if (it->second.number_nacks >= kNumberOfNacksBeforeResend && | 356 if (it->second->number_nacks >= kNumberOfNacksBeforeResend && |
| 303 resent_packets < kMaxResendPerAck) { | 357 resent_packets < kMaxResendPerAck) { |
| 304 resend_number = it->first; | 358 resend_number = it->first; |
| 305 } | 359 } |
| 306 } | 360 } |
| 307 | 361 |
| 308 ++it; | 362 ++it; |
| 309 if (resend_number > 0) { | 363 if (resend_number > 0) { |
| 310 ++resent_packets; | 364 ++resent_packets; |
| 311 DVLOG(1) << "Trying to resend packet " << resend_number | 365 DVLOG(1) << "Trying to resend packet " << resend_number |
| 312 << " as it has been nacked 3 or more times."; | 366 << " as it has been nacked 3 or more times."; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 QuicStreamId id, | 471 QuicStreamId id, |
| 418 StringPiece data, | 472 StringPiece data, |
| 419 QuicStreamOffset offset, | 473 QuicStreamOffset offset, |
| 420 bool fin, | 474 bool fin, |
| 421 QuicPacketSequenceNumber* last_packet) { | 475 QuicPacketSequenceNumber* last_packet) { |
| 422 size_t total_bytes_consumed = 0; | 476 size_t total_bytes_consumed = 0; |
| 423 bool fin_consumed = false; | 477 bool fin_consumed = false; |
| 424 | 478 |
| 425 while (queued_packets_.empty()) { | 479 while (queued_packets_.empty()) { |
| 426 vector<PacketPair> packets; | 480 vector<PacketPair> packets; |
| 481 QuicFrames frames; | |
| 427 size_t bytes_consumed = | 482 size_t bytes_consumed = |
| 428 packet_creator_.DataToStream(id, data, offset, fin, &packets); | 483 packet_creator_.DataToStream(id, data, offset, fin, &packets, &frames); |
| 429 total_bytes_consumed += bytes_consumed; | 484 total_bytes_consumed += bytes_consumed; |
| 430 offset += bytes_consumed; | 485 offset += bytes_consumed; |
| 431 fin_consumed = fin && bytes_consumed == data.size(); | 486 fin_consumed = fin && bytes_consumed == data.size(); |
| 432 data.remove_prefix(bytes_consumed); | 487 data.remove_prefix(bytes_consumed); |
| 433 DCHECK_LT(0u, packets.size()); | 488 DCHECK_LT(0u, packets.size()); |
| 434 | 489 |
| 435 for (size_t i = 0; i < packets.size(); ++i) { | 490 for (size_t i = 0; i < packets.size(); ++i) { |
| 491 // Resend is false for FEC packets. | |
| 492 bool should_resend = !packets[i].second->IsFecPacket(); | |
| 436 SendPacket(packets[i].first, | 493 SendPacket(packets[i].first, |
| 437 packets[i].second, | 494 packets[i].second, |
| 438 // Resend is false for FEC packets. | 495 should_resend, |
| 439 !packets[i].second->IsFecPacket(), | |
| 440 false, | 496 false, |
| 441 false); | 497 false); |
| 442 unacked_packets_.insert(make_pair(packets[i].first, | 498 if (should_resend) { |
| 443 UnackedPacket(packets[i].second))); | 499 QuicFrames unacked_frames; |
| 500 unacked_frames.push_back(frames[i]); | |
| 501 UnackedPacket* unacked = new UnackedPacket( | |
| 502 unacked_frames, frames[i].stream_frame->data.as_string()); | |
| 503 // Ensure the string piece points to the owned copy of the data. | |
| 504 unacked->frames[0].stream_frame->data = StringPiece(unacked->data); | |
| 505 unacked_packets_.insert(make_pair(packets[i].first, unacked)); | |
| 506 } else { | |
| 507 DeleteEnclosedFrame(&frames[i]); | |
| 508 } | |
| 444 } | 509 } |
| 445 | 510 |
| 446 if (last_packet != NULL) { | 511 if (last_packet != NULL) { |
| 447 *last_packet = packets[packets.size() - 1].first; | 512 *last_packet = packets[packets.size() - 1].first; |
| 448 } | 513 } |
| 449 if (data.size() == 0) { | 514 if (data.size() == 0) { |
| 450 // We're done writing the data. Exit the loop. | 515 // We're done writing the data. Exit the loop. |
| 451 // We don't make this a precondition beacuse we could have 0 bytes of data | 516 // We don't make this a precondition beacuse we could have 0 bytes of data |
| 452 // if we're simply writing a fin. | 517 // if we're simply writing a fin. |
| 453 break; | 518 break; |
| 454 } | 519 } |
| 455 } | 520 } |
| 456 return QuicConsumedData(total_bytes_consumed, fin_consumed); | 521 return QuicConsumedData(total_bytes_consumed, fin_consumed); |
| 457 } | 522 } |
| 458 | 523 |
| 459 void QuicConnection::SendRstStream(QuicStreamId id, | 524 void QuicConnection::SendRstStream(QuicStreamId id, |
| 460 QuicErrorCode error, | 525 QuicErrorCode error, |
| 461 QuicStreamOffset offset) { | 526 QuicStreamOffset offset) { |
| 462 // TODO(ianswett): Queue the frame and use WriteData instead of SendPacket | 527 queued_control_frames_.push_back(QuicFrame( |
| 463 // once we support re-sending frames instead of packets. | 528 new QuicRstStreamFrame(id, offset, error))); |
| 464 PacketPair packetpair = packet_creator_.ResetStream(id, offset, error); | |
| 465 | 529 |
| 466 SendPacket(packetpair.first, packetpair.second, true, false, false); | 530 // Try to write immediately if possible. |
| 467 unacked_packets_.insert(make_pair(packetpair.first, | 531 if (CanWrite(false)) { |
| 468 UnackedPacket(packetpair.second))); | 532 WriteData(); |
| 533 } | |
| 469 } | 534 } |
| 470 | 535 |
| 471 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, | 536 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, |
| 472 const IPEndPoint& peer_address, | 537 const IPEndPoint& peer_address, |
| 473 const QuicEncryptedPacket& packet) { | 538 const QuicEncryptedPacket& packet) { |
| 474 last_packet_revived_ = false; | 539 last_packet_revived_ = false; |
| 475 last_size_ = packet.length(); | 540 last_size_ = packet.length(); |
| 476 framer_.ProcessPacket(self_address, peer_address, packet); | 541 framer_.ProcessPacket(self_address, peer_address, packet); |
| 477 | 542 |
| 478 MaybeProcessRevivedPacket(); | 543 MaybeProcessRevivedPacket(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 499 helper_->SetSendAlarm(QuicTime::Delta()); | 564 helper_->SetSendAlarm(QuicTime::Delta()); |
| 500 } | 565 } |
| 501 } | 566 } |
| 502 | 567 |
| 503 return !write_blocked_; | 568 return !write_blocked_; |
| 504 } | 569 } |
| 505 | 570 |
| 506 bool QuicConnection::WriteData() { | 571 bool QuicConnection::WriteData() { |
| 507 DCHECK_EQ(false, write_blocked_); | 572 DCHECK_EQ(false, write_blocked_); |
| 508 // Serialize the ack and congestion frames before draining the pending queue. | 573 // Serialize the ack and congestion frames before draining the pending queue. |
| 509 QuicFrames frames; | |
| 510 if (should_send_ack_) { | 574 if (should_send_ack_) { |
| 511 frames.push_back(QuicFrame(&outgoing_ack_)); | 575 queued_control_frames_.push_back(QuicFrame(&outgoing_ack_)); |
| 512 } | 576 } |
| 513 if (should_send_congestion_feedback_) { | 577 if (should_send_congestion_feedback_) { |
| 514 frames.push_back(QuicFrame(&outgoing_congestion_feedback_)); | 578 queued_control_frames_.push_back(QuicFrame(&outgoing_congestion_feedback_)); |
| 515 } | 579 } |
| 516 while (!frames.empty()) { | 580 while (!queued_control_frames_.empty()) { |
| 517 size_t num_serialized; | 581 size_t num_serialized; |
| 518 PacketPair pair = packet_creator_.SerializeFrames(frames, &num_serialized); | 582 PacketPair pair = packet_creator_.SerializeFrames( |
| 583 queued_control_frames_, &num_serialized); | |
| 584 // If any serialized frames need to be resent, add them to unacked_packets. | |
| 585 QuicFrames unacked_frames; | |
| 586 for (QuicFrames::const_iterator iter = queued_control_frames_.begin(); | |
| 587 iter != queued_control_frames_.begin() + num_serialized; ++iter) { | |
| 588 if (ShouldResend(*iter)) { | |
| 589 unacked_frames.push_back(*iter); | |
| 590 } | |
| 591 } | |
| 592 if (!unacked_frames.empty()) { | |
| 593 unacked_packets_.insert(make_pair(pair.first, | |
| 594 new UnackedPacket(unacked_frames))); | |
| 595 } | |
| 519 queued_packets_.push_back(QueuedPacket( | 596 queued_packets_.push_back(QueuedPacket( |
| 520 pair.first, pair.second, false, false)); | 597 pair.first, pair.second, !unacked_frames.empty(), false)); |
| 521 frames.erase(frames.begin(), frames.begin() + num_serialized); | 598 queued_control_frames_.erase( |
| 599 queued_control_frames_.begin(), | |
| 600 queued_control_frames_.begin() + num_serialized); | |
| 522 } | 601 } |
| 523 should_send_ack_ = false; | 602 should_send_ack_ = false; |
| 524 should_send_congestion_feedback_ = false; | 603 should_send_congestion_feedback_ = false; |
| 525 | 604 |
| 526 size_t num_queued_packets = queued_packets_.size() + 1; | 605 size_t num_queued_packets = queued_packets_.size() + 1; |
| 527 while (!write_blocked_ && !helper_->IsSendAlarmSet() && | 606 while (!write_blocked_ && !helper_->IsSendAlarmSet() && |
| 528 !queued_packets_.empty()) { | 607 !queued_packets_.empty()) { |
| 529 // Ensure that from one iteration of this loop to the next we | 608 // Ensure that from one iteration of this loop to the next we |
| 530 // succeeded in sending a packet so we don't infinitely loop. | 609 // succeeded in sending a packet so we don't infinitely loop. |
| 531 // TODO(rch): clean up and close the connection if we really hit this. | 610 // TODO(rch): clean up and close the connection if we really hit this. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 559 MaybeResendPacket(sequence_number); | 638 MaybeResendPacket(sequence_number); |
| 560 return true; | 639 return true; |
| 561 } | 640 } |
| 562 } | 641 } |
| 563 | 642 |
| 564 void QuicConnection::MaybeResendPacket( | 643 void QuicConnection::MaybeResendPacket( |
| 565 QuicPacketSequenceNumber sequence_number) { | 644 QuicPacketSequenceNumber sequence_number) { |
| 566 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 645 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 567 | 646 |
| 568 if (it != unacked_packets_.end()) { | 647 if (it != unacked_packets_.end()) { |
| 569 QuicPacket* packet = it->second.packet; | 648 UnackedPacket* unacked = it->second; |
| 649 // TODO(ianswett): Never change the sequence number of the connect packet. | |
| 570 unacked_packets_.erase(it); | 650 unacked_packets_.erase(it); |
| 571 // Re-frame the packet with a new sequence number for resend. | 651 // Re-packetize the frames with a new sequence number for resend. |
| 572 QuicPacketSequenceNumber new_sequence_number = | 652 // Resent data packets do not use FEC, even when it's enabled. |
| 573 packet_creator_.SetNewSequenceNumber(packet); | 653 PacketPair packetpair = packet_creator_.SerializeAllFrames(unacked->frames); |
| 574 DVLOG(1) << "Resending unacked packet " << sequence_number << " as " | 654 DVLOG(1) << "Resending unacked packet " << sequence_number << " as " |
| 575 << new_sequence_number; | 655 << packetpair.first; |
| 576 // Clear the FEC group. | 656 unacked_packets_.insert(make_pair(packetpair.first, unacked)); |
| 577 framer_.WriteFecGroup(0u, packet); | |
| 578 unacked_packets_.insert(make_pair(new_sequence_number, | |
| 579 UnackedPacket(packet))); | |
| 580 | 657 |
| 581 // Make sure if this was our least unacked packet, that we update our | 658 // Make sure if this was our least unacked packet, that we update our |
| 582 // outgoing ack. If this wasn't the least unacked, this is a no-op. | 659 // outgoing ack. If this wasn't the least unacked, this is a no-op. |
| 583 UpdateLeastUnacked(sequence_number); | 660 UpdateLeastUnacked(sequence_number); |
| 584 SendPacket(new_sequence_number, packet, true, false, true); | 661 SendPacket(packetpair.first, packetpair.second, true, false, true); |
| 585 } else { | 662 } else { |
| 586 DVLOG(2) << "alarm fired for " << sequence_number | 663 DVLOG(2) << "alarm fired for " << sequence_number |
| 587 << " but it has been acked"; | 664 << " but it has been acked"; |
| 588 } | 665 } |
| 589 } | 666 } |
| 590 | 667 |
| 591 bool QuicConnection::CanWrite(bool is_retransmit) { | 668 bool QuicConnection::CanWrite(bool is_retransmit) { |
| 592 // TODO(ianswett): If the packet is a retransmit, the current send alarm may | 669 // TODO(ianswett): If the packet is a retransmit, the current send alarm may |
| 593 // be too long. | 670 // be too long. |
| 594 if (write_blocked_ || helper_->IsSendAlarmSet()) { | 671 if (write_blocked_ || helper_->IsSendAlarmSet()) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 */ | 728 */ |
| 652 return false; | 729 return false; |
| 653 } | 730 } |
| 654 // TODO(wtc): is it correct to fall through to return true? | 731 // TODO(wtc): is it correct to fall through to return true? |
| 655 } | 732 } |
| 656 | 733 |
| 657 time_of_last_packet_ = clock_->Now(); | 734 time_of_last_packet_ = clock_->Now(); |
| 658 DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds(); | 735 DVLOG(1) << "last packet: " << time_of_last_packet_.ToMicroseconds(); |
| 659 | 736 |
| 660 scheduler_->SentPacket(sequence_number, packet->length(), is_retransmit); | 737 scheduler_->SentPacket(sequence_number, packet->length(), is_retransmit); |
| 661 if (!should_resend) delete packet; | 738 delete packet; |
| 662 return true; | 739 return true; |
| 663 } | 740 } |
| 664 | 741 |
| 665 bool QuicConnection::ShouldSimulateLostPacket() { | 742 bool QuicConnection::ShouldSimulateLostPacket() { |
| 666 // TODO(rch): enable this | 743 // TODO(rch): enable this |
| 667 return false; | 744 return false; |
| 668 /* | 745 /* |
| 669 return FLAGS_fake_packet_loss_percentage > 0 && | 746 return FLAGS_fake_packet_loss_percentage > 0 && |
| 670 random_->Rand32() % 100 < FLAGS_fake_packet_loss_percentage; | 747 random_->Rand32() % 100 < FLAGS_fake_packet_loss_percentage; |
| 671 */ | 748 */ |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 772 << " delta:" << delta.ToMicroseconds(); | 849 << " delta:" << delta.ToMicroseconds(); |
| 773 if (delta >= timeout_) { | 850 if (delta >= timeout_) { |
| 774 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 851 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
| 775 return true; | 852 return true; |
| 776 } | 853 } |
| 777 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 854 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); |
| 778 return false; | 855 return false; |
| 779 } | 856 } |
| 780 | 857 |
| 781 } // namespace net | 858 } // namespace net |
| OLD | NEW |