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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 */ | 118 */ |
119 } | 119 } |
120 | 120 |
121 QuicConnection::~QuicConnection() { | 121 QuicConnection::~QuicConnection() { |
122 STLDeleteValues(&unacked_packets_); | 122 STLDeleteValues(&unacked_packets_); |
123 STLDeleteValues(&group_map_); | 123 STLDeleteValues(&group_map_); |
124 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 124 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
125 it != queued_packets_.end(); ++it) { | 125 it != queued_packets_.end(); ++it) { |
126 delete it->packet; | 126 delete it->packet; |
127 } | 127 } |
128 LOG(ERROR) << "Quic connection " << write_blocked_; | 128 DLOG(INFO) << ENDPOINT << "write_blocked: " << write_blocked_; |
129 } | 129 } |
130 | 130 |
131 bool QuicConnection::SelectMutualVersion( | 131 bool QuicConnection::SelectMutualVersion( |
132 const QuicTagVector& available_versions) { | 132 const QuicTagVector& available_versions) { |
133 // TODO(satyamshekhar): Make this generic. | 133 // TODO(satyamshekhar): Make this generic. |
134 if (std::find(available_versions.begin(), available_versions.end(), | 134 if (std::find(available_versions.begin(), available_versions.end(), |
135 kQuicVersion1) == available_versions.end()) { | 135 kQuicVersion1) == available_versions.end()) { |
136 return false; | 136 return false; |
137 } | 137 } |
138 | 138 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 DLOG(WARNING) << ENDPOINT << "The server already supports our version. " | 235 DLOG(WARNING) << ENDPOINT << "The server already supports our version. " |
236 << "It should have accepted our connection."; | 236 << "It should have accepted our connection."; |
237 // Just drop the connection. | 237 // Just drop the connection. |
238 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); | 238 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false); |
239 return; | 239 return; |
240 } | 240 } |
241 | 241 |
242 if (!SelectMutualVersion(packet.versions)) { | 242 if (!SelectMutualVersion(packet.versions)) { |
243 SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, | 243 SendConnectionCloseWithDetails(QUIC_INVALID_VERSION, |
244 "no common version found"); | 244 "no common version found"); |
| 245 return; |
245 } | 246 } |
246 | 247 |
247 version_negotiation_state_ = NEGOTIATED_VERSION; | 248 version_negotiation_state_ = NEGOTIATED_VERSION; |
248 RetransmitUnackedPackets(ALL_PACKETS); | 249 RetransmitUnackedPackets(ALL_PACKETS); |
249 } | 250 } |
250 | 251 |
251 void QuicConnection::OnRevivedPacket() { | 252 void QuicConnection::OnRevivedPacket() { |
252 } | 253 } |
253 | 254 |
254 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { | 255 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 355 |
355 received_truncated_ack_ = | 356 received_truncated_ack_ = |
356 incoming_ack.received_info.missing_packets.size() >= | 357 incoming_ack.received_info.missing_packets.size() >= |
357 QuicFramer::GetMaxUnackedPackets(last_header_); | 358 QuicFramer::GetMaxUnackedPackets(last_header_); |
358 | 359 |
359 UpdatePacketInformationReceivedByPeer(incoming_ack); | 360 UpdatePacketInformationReceivedByPeer(incoming_ack); |
360 UpdatePacketInformationSentByPeer(incoming_ack); | 361 UpdatePacketInformationSentByPeer(incoming_ack); |
361 congestion_manager_.OnIncomingAckFrame(incoming_ack, | 362 congestion_manager_.OnIncomingAckFrame(incoming_ack, |
362 time_of_last_received_packet_); | 363 time_of_last_received_packet_); |
363 | 364 |
364 // Now the we have received an ack, we might be able to send queued packets. | 365 // Now the we have received an ack, we might be able to send packets which are |
365 if (!queued_packets_.empty()) { | 366 // queued locally, or drain streams which are blocked. |
366 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( | 367 QuicTime::Delta delay = congestion_manager_.TimeUntilSend( |
367 time_of_last_received_packet_, NOT_RETRANSMISSION, | 368 time_of_last_received_packet_, NOT_RETRANSMISSION, |
368 HAS_RETRANSMITTABLE_DATA); | 369 HAS_RETRANSMITTABLE_DATA); |
369 if (delay.IsZero()) { | 370 if (delay.IsZero()) { |
370 helper_->UnregisterSendAlarmIfRegistered(); | 371 helper_->UnregisterSendAlarmIfRegistered(); |
371 if (!write_blocked_) { | 372 if (!write_blocked_) { |
372 OnCanWrite(); | 373 OnCanWrite(); |
373 } | |
374 } else if (!delay.IsInfinite()) { | |
375 helper_->SetSendAlarm(time_of_last_received_packet_.Add(delay)); | |
376 } | 374 } |
| 375 } else if (!delay.IsInfinite()) { |
| 376 helper_->SetSendAlarm(time_of_last_received_packet_.Add(delay)); |
377 } | 377 } |
378 return connected_; | 378 return connected_; |
379 } | 379 } |
380 | 380 |
381 bool QuicConnection::OnCongestionFeedbackFrame( | 381 bool QuicConnection::OnCongestionFeedbackFrame( |
382 const QuicCongestionFeedbackFrame& feedback) { | 382 const QuicCongestionFeedbackFrame& feedback) { |
383 DCHECK(connected_); | 383 DCHECK(connected_); |
384 if (debug_visitor_) { | 384 if (debug_visitor_) { |
385 debug_visitor_->OnCongestionFeedbackFrame(feedback); | 385 debug_visitor_->OnCongestionFeedbackFrame(feedback); |
386 } | 386 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 incoming_ack.received_info.largest_observed, | 454 incoming_ack.received_info.largest_observed, |
455 incoming_ack.received_info.missing_packets, | 455 incoming_ack.received_info.missing_packets, |
456 incoming_ack.received_info.entropy_hash)) { | 456 incoming_ack.received_info.entropy_hash)) { |
457 DLOG(ERROR) << ENDPOINT << "Peer sent invalid entropy."; | 457 DLOG(ERROR) << ENDPOINT << "Peer sent invalid entropy."; |
458 return false; | 458 return false; |
459 } | 459 } |
460 | 460 |
461 return true; | 461 return true; |
462 } | 462 } |
463 | 463 |
464 void QuicConnection::UpdatePacketInformationReceivedByPeer( | 464 void QuicConnection::HandleAckForSentPackets(const QuicAckFrame& incoming_ack, |
465 const QuicAckFrame& incoming_ack) { | 465 SequenceNumberSet* acked_packets) { |
466 SequenceNumberSet acked_packets; | |
467 | |
468 // ValidateAck should fail if largest_observed ever shrinks. | |
469 DCHECK_LE(peer_largest_observed_packet_, | |
470 incoming_ack.received_info.largest_observed); | |
471 peer_largest_observed_packet_ = incoming_ack.received_info.largest_observed; | |
472 | |
473 if (incoming_ack.received_info.missing_packets.empty()) { | |
474 least_packet_awaited_by_peer_ = peer_largest_observed_packet_ + 1; | |
475 } else { | |
476 least_packet_awaited_by_peer_ = | |
477 *(incoming_ack.received_info.missing_packets.begin()); | |
478 } | |
479 | |
480 entropy_manager_.ClearSentEntropyBefore(least_packet_awaited_by_peer_ - 1); | |
481 | |
482 int retransmitted_packets = 0; | 466 int retransmitted_packets = 0; |
483 // Go through the packets we have not received an ack for and see if this | 467 // Go through the packets we have not received an ack for and see if this |
484 // incoming_ack shows they've been seen by the peer. | 468 // incoming_ack shows they've been seen by the peer. |
485 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 469 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
486 while (it != unacked_packets_.end()) { | 470 while (it != unacked_packets_.end()) { |
487 QuicPacketSequenceNumber sequence_number = it->first; | 471 QuicPacketSequenceNumber sequence_number = it->first; |
488 if (sequence_number > peer_largest_observed_packet_) { | 472 if (sequence_number > peer_largest_observed_packet_) { |
489 break; | 473 break; |
490 } | 474 } |
491 RetransmittableFrames* unacked = it->second; | 475 RetransmittableFrames* unacked = it->second; |
492 if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) { | 476 if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) { |
493 // Packet was acked, so remove it from our unacked packet list. | 477 // Packet was acked, so remove it from our unacked packet list. |
494 DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; | 478 DVLOG(1) << ENDPOINT <<"Got an ack for packet " << sequence_number; |
495 acked_packets.insert(sequence_number); | 479 acked_packets->insert(sequence_number); |
496 delete unacked; | 480 delete unacked; |
497 UnackedPacketMap::iterator it_tmp = it; | 481 unacked_packets_.erase(it++); |
498 ++it; | |
499 unacked_packets_.erase(it_tmp); | |
500 retransmission_map_.erase(sequence_number); | 482 retransmission_map_.erase(sequence_number); |
501 } else { | 483 } else { |
502 // This is a packet which we planned on retransmitting and has not been | 484 // This is a packet which we planned on retransmitting and has not been |
503 // seen at the time of this ack being sent out. See if it's our new | 485 // seen at the time of this ack being sent out. See if it's our new |
504 // lowest unacked packet. | 486 // lowest unacked packet. |
505 DVLOG(1) << ENDPOINT << "still missing packet " << sequence_number; | 487 DVLOG(1) << ENDPOINT << "still missing packet " << sequence_number; |
506 ++it; | 488 ++it; |
507 // The peer got packets after this sequence number. This is an explicit | 489 // The peer got packets after this sequence number. This is an explicit |
508 // nack. | 490 // nack. |
509 RetransmissionMap::iterator retransmission_it = | 491 RetransmissionMap::iterator retransmission_it = |
510 retransmission_map_.find(sequence_number); | 492 retransmission_map_.find(sequence_number); |
511 ++(retransmission_it->second.number_nacks); | 493 ++(retransmission_it->second.number_nacks); |
512 if (retransmission_it->second.number_nacks >= | 494 if (retransmission_it->second.number_nacks >= |
513 kNumberOfNacksBeforeRetransmission && | 495 kNumberOfNacksBeforeRetransmission && |
514 retransmitted_packets < kMaxRetransmissionsPerAck) { | 496 retransmitted_packets < kMaxRetransmissionsPerAck) { |
515 ++retransmitted_packets; | 497 ++retransmitted_packets; |
516 DVLOG(1) << ENDPOINT << "Trying to retransmit packet " | 498 DVLOG(1) << ENDPOINT << "Trying to retransmit packet " |
517 << sequence_number | 499 << sequence_number |
518 << " as it has been nacked 3 or more times."; | 500 << " as it has been nacked 3 or more times."; |
519 // TODO(satyamshekhar): save in a vector and retransmit after the | 501 // TODO(satyamshekhar): save in a vector and retransmit after the |
520 // loop. | 502 // loop. |
521 RetransmitPacket(sequence_number); | 503 RetransmitPacket(sequence_number); |
522 } | 504 } |
523 } | 505 } |
524 } | 506 } |
| 507 } |
| 508 |
| 509 void QuicConnection::HandleAckForSentFecPackets( |
| 510 const QuicAckFrame& incoming_ack, SequenceNumberSet* acked_packets) { |
| 511 UnackedPacketMap::iterator it = unacked_fec_packets_.begin(); |
| 512 while (it != unacked_fec_packets_.end()) { |
| 513 QuicPacketSequenceNumber sequence_number = it->first; |
| 514 if (sequence_number > peer_largest_observed_packet_) { |
| 515 break; |
| 516 } |
| 517 if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) { |
| 518 DVLOG(1) << ENDPOINT << "Got an ack for fec packet: " << sequence_number; |
| 519 acked_packets->insert(sequence_number); |
| 520 unacked_fec_packets_.erase(it++); |
| 521 } else { |
| 522 DVLOG(1) << ENDPOINT << "Still missing ack for fec packet: " |
| 523 << sequence_number; |
| 524 ++it; |
| 525 } |
| 526 } |
| 527 } |
| 528 |
| 529 void QuicConnection::UpdatePacketInformationReceivedByPeer( |
| 530 const QuicAckFrame& incoming_ack) { |
| 531 // ValidateAck should fail if largest_observed ever shrinks. |
| 532 DCHECK_LE(peer_largest_observed_packet_, |
| 533 incoming_ack.received_info.largest_observed); |
| 534 peer_largest_observed_packet_ = incoming_ack.received_info.largest_observed; |
| 535 |
| 536 if (incoming_ack.received_info.missing_packets.empty()) { |
| 537 least_packet_awaited_by_peer_ = peer_largest_observed_packet_ + 1; |
| 538 } else { |
| 539 least_packet_awaited_by_peer_ = |
| 540 *(incoming_ack.received_info.missing_packets.begin()); |
| 541 } |
| 542 |
| 543 entropy_manager_.ClearSentEntropyBefore(least_packet_awaited_by_peer_ - 1); |
| 544 |
| 545 SequenceNumberSet acked_packets; |
| 546 HandleAckForSentPackets(incoming_ack, &acked_packets); |
| 547 HandleAckForSentFecPackets(incoming_ack, &acked_packets); |
| 548 |
525 if (acked_packets.size() > 0) { | 549 if (acked_packets.size() > 0) { |
526 visitor_->OnAck(acked_packets); | 550 visitor_->OnAck(acked_packets); |
527 } | 551 } |
528 } | 552 } |
529 | 553 |
530 bool QuicConnection::DontWaitForPacketsBefore( | 554 bool QuicConnection::DontWaitForPacketsBefore( |
531 QuicPacketSequenceNumber least_unacked) { | 555 QuicPacketSequenceNumber least_unacked) { |
532 size_t missing_packets_count = | 556 size_t missing_packets_count = |
533 outgoing_ack_.received_info.missing_packets.size(); | 557 outgoing_ack_.received_info.missing_packets.size(); |
534 outgoing_ack_.received_info.missing_packets.erase( | 558 outgoing_ack_.received_info.missing_packets.erase( |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 | 742 |
719 address_migrating_ = false; | 743 address_migrating_ = false; |
720 | 744 |
721 if (peer_address_.address().empty()) { | 745 if (peer_address_.address().empty()) { |
722 peer_address_ = peer_address; | 746 peer_address_ = peer_address; |
723 } | 747 } |
724 if (self_address_.address().empty()) { | 748 if (self_address_.address().empty()) { |
725 self_address_ = self_address; | 749 self_address_ = self_address; |
726 } | 750 } |
727 | 751 |
728 if (!(peer_address == peer_address_) && (self_address == self_address_)) { | 752 if (!(peer_address == peer_address_ && self_address == self_address_)) { |
729 address_migrating_ = true; | 753 address_migrating_ = true; |
730 } | 754 } |
731 | 755 |
732 stats_.bytes_received += packet.length(); | 756 stats_.bytes_received += packet.length(); |
733 ++stats_.packets_received; | 757 ++stats_.packets_received; |
734 | 758 |
735 if (!framer_.ProcessPacket(packet)) { | 759 if (!framer_.ProcessPacket(packet)) { |
736 return; | 760 return; |
737 } | 761 } |
738 MaybeProcessRevivedPacket(); | 762 MaybeProcessRevivedPacket(); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 return true; | 977 return true; |
954 } | 978 } |
955 | 979 |
956 bool QuicConnection::IsRetransmission( | 980 bool QuicConnection::IsRetransmission( |
957 QuicPacketSequenceNumber sequence_number) { | 981 QuicPacketSequenceNumber sequence_number) { |
958 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); | 982 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); |
959 return it != retransmission_map_.end() && | 983 return it != retransmission_map_.end() && |
960 it->second.number_retransmissions > 0; | 984 it->second.number_retransmissions > 0; |
961 } | 985 } |
962 | 986 |
963 void QuicConnection::MaybeSetupRetransmission( | 987 void QuicConnection::SetupRetransmission( |
964 QuicPacketSequenceNumber sequence_number) { | 988 QuicPacketSequenceNumber sequence_number) { |
965 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); | 989 RetransmissionMap::iterator it = retransmission_map_.find(sequence_number); |
966 if (it == retransmission_map_.end()) { | 990 if (it == retransmission_map_.end()) { |
967 DVLOG(1) << ENDPOINT << "Will not retransmit packet " << sequence_number; | 991 DVLOG(1) << ENDPOINT << "Will not retransmit packet " << sequence_number; |
968 return; | 992 return; |
969 } | 993 } |
970 | 994 |
971 RetransmissionInfo retransmission_info = it->second; | 995 RetransmissionInfo retransmission_info = it->second; |
972 QuicTime::Delta retransmission_delay = | 996 QuicTime::Delta retransmission_delay = |
973 congestion_manager_.GetRetransmissionDelay( | 997 congestion_manager_.GetRetransmissionDelay( |
974 unacked_packets_.size(), | 998 unacked_packets_.size(), |
975 retransmission_info.number_retransmissions); | 999 retransmission_info.number_retransmissions); |
976 retransmission_info.scheduled_time = | 1000 |
977 clock_->ApproximateNow().Add(retransmission_delay); | 1001 retransmission_timeouts_.push(RetransmissionTime( |
978 retransmission_timeouts_.push(retransmission_info); | 1002 sequence_number, |
| 1003 clock_->ApproximateNow().Add(retransmission_delay), |
| 1004 false)); |
979 | 1005 |
980 // Do not set the retransmisson alarm if we're already handling the | 1006 // Do not set the retransmisson alarm if we're already handling the |
981 // retransmission alarm because the retransmission alarm will be reset when | 1007 // retransmission alarm because the retransmission alarm will be reset when |
982 // OnRetransmissionTimeout completes. | 1008 // OnRetransmissionTimeout completes. |
983 if (!handling_retransmission_timeout_) { | 1009 if (!handling_retransmission_timeout_) { |
984 helper_->SetRetransmissionAlarm(retransmission_delay); | 1010 helper_->SetRetransmissionAlarm(retransmission_delay); |
985 } | 1011 } |
986 // TODO(satyamshekhar): restore packet reordering with Ian's TODO in | 1012 // TODO(satyamshekhar): restore packet reordering with Ian's TODO in |
987 // SendStreamData(). | 1013 // SendStreamData(). |
988 } | 1014 } |
989 | 1015 |
| 1016 void QuicConnection::SetupAbandonFecTimer( |
| 1017 QuicPacketSequenceNumber sequence_number) { |
| 1018 DCHECK(ContainsKey(unacked_fec_packets_, sequence_number)); |
| 1019 QuicTime::Delta retransmission_delay = |
| 1020 QuicTime::Delta::FromMilliseconds( |
| 1021 congestion_manager_.DefaultRetransmissionTime().ToMilliseconds() * 3); |
| 1022 retransmission_timeouts_.push(RetransmissionTime( |
| 1023 sequence_number, |
| 1024 clock_->ApproximateNow().Add(retransmission_delay), |
| 1025 true)); |
| 1026 } |
| 1027 |
990 void QuicConnection::DropPacket(QuicPacketSequenceNumber sequence_number) { | 1028 void QuicConnection::DropPacket(QuicPacketSequenceNumber sequence_number) { |
991 UnackedPacketMap::iterator unacked_it = | 1029 UnackedPacketMap::iterator unacked_it = |
992 unacked_packets_.find(sequence_number); | 1030 unacked_packets_.find(sequence_number); |
993 // Packet was not meant to be retransmitted. | 1031 // Packet was not meant to be retransmitted. |
994 if (unacked_it == unacked_packets_.end()) { | 1032 if (unacked_it == unacked_packets_.end()) { |
995 DCHECK(!ContainsKey(retransmission_map_, sequence_number)); | 1033 DCHECK(!ContainsKey(retransmission_map_, sequence_number)); |
996 return; | 1034 return; |
997 } | 1035 } |
998 // Delete the unacked packet. | 1036 // Delete the unacked packet. |
999 delete unacked_it->second; | 1037 delete unacked_it->second; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 } | 1108 } |
1071 if (!retransmission) { | 1109 if (!retransmission) { |
1072 time_of_last_sent_packet_ = now; | 1110 time_of_last_sent_packet_ = now; |
1073 } | 1111 } |
1074 DVLOG(1) << ENDPOINT << "time of last sent packet: " | 1112 DVLOG(1) << ENDPOINT << "time of last sent packet: " |
1075 << now.ToDebuggingValue(); | 1113 << now.ToDebuggingValue(); |
1076 | 1114 |
1077 // Set the retransmit alarm only when we have sent the packet to the client | 1115 // Set the retransmit alarm only when we have sent the packet to the client |
1078 // and not when it goes to the pending queue, otherwise we will end up adding | 1116 // and not when it goes to the pending queue, otherwise we will end up adding |
1079 // an entry to retransmission_timeout_ every time we attempt a write. | 1117 // an entry to retransmission_timeout_ every time we attempt a write. |
1080 MaybeSetupRetransmission(sequence_number); | 1118 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
| 1119 SetupRetransmission(sequence_number); |
| 1120 } else if (packet->is_fec_packet()) { |
| 1121 SetupAbandonFecTimer(sequence_number); |
| 1122 } |
1081 | 1123 |
1082 congestion_manager_.SentPacket(sequence_number, now, packet->length(), | 1124 congestion_manager_.SentPacket(sequence_number, now, packet->length(), |
1083 retransmission); | 1125 retransmission); |
1084 | 1126 |
1085 stats_.bytes_sent += encrypted->length(); | 1127 stats_.bytes_sent += encrypted->length(); |
1086 ++stats_.packets_sent; | 1128 ++stats_.packets_sent; |
1087 | 1129 |
1088 if (retransmission == IS_RETRANSMISSION) { | 1130 if (retransmission == IS_RETRANSMISSION) { |
1089 stats_.bytes_retransmitted += encrypted->length(); | 1131 stats_.bytes_retransmitted += encrypted->length(); |
1090 ++stats_.packets_retransmitted; | 1132 ++stats_.packets_retransmitted; |
(...skipping 13 matching lines...) Expand all Loading... |
1104 // original. | 1146 // original. |
1105 serialized_packet.retransmittable_frames->set_encryption_level( | 1147 serialized_packet.retransmittable_frames->set_encryption_level( |
1106 encryption_level_); | 1148 encryption_level_); |
1107 unacked_packets_.insert( | 1149 unacked_packets_.insert( |
1108 make_pair(serialized_packet.sequence_number, | 1150 make_pair(serialized_packet.sequence_number, |
1109 serialized_packet.retransmittable_frames)); | 1151 serialized_packet.retransmittable_frames)); |
1110 // All unacked packets might be retransmitted. | 1152 // All unacked packets might be retransmitted. |
1111 retransmission_map_.insert( | 1153 retransmission_map_.insert( |
1112 make_pair(serialized_packet.sequence_number, | 1154 make_pair(serialized_packet.sequence_number, |
1113 RetransmissionInfo(serialized_packet.sequence_number))); | 1155 RetransmissionInfo(serialized_packet.sequence_number))); |
| 1156 } else if (serialized_packet.packet->is_fec_packet()) { |
| 1157 unacked_fec_packets_.insert(make_pair( |
| 1158 serialized_packet.sequence_number, |
| 1159 serialized_packet.retransmittable_frames)); |
1114 } | 1160 } |
1115 return SendOrQueuePacket(encryption_level_, | 1161 return SendOrQueuePacket(encryption_level_, |
1116 serialized_packet.sequence_number, | 1162 serialized_packet.sequence_number, |
1117 serialized_packet.packet, | 1163 serialized_packet.packet, |
1118 serialized_packet.entropy_hash, | 1164 serialized_packet.entropy_hash, |
1119 serialized_packet.retransmittable_frames != NULL ? | 1165 serialized_packet.retransmittable_frames != NULL ? |
1120 HAS_RETRANSMITTABLE_DATA : | 1166 HAS_RETRANSMITTABLE_DATA : |
1121 NO_RETRANSMITTABLE_DATA); | 1167 NO_RETRANSMITTABLE_DATA); |
1122 } | 1168 } |
1123 | 1169 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 if (congestion_manager_.GenerateCongestionFeedback( | 1219 if (congestion_manager_.GenerateCongestionFeedback( |
1174 &outgoing_congestion_feedback_)) { | 1220 &outgoing_congestion_feedback_)) { |
1175 DVLOG(1) << ENDPOINT << "Sending feedback " | 1221 DVLOG(1) << ENDPOINT << "Sending feedback " |
1176 << outgoing_congestion_feedback_; | 1222 << outgoing_congestion_feedback_; |
1177 send_feedback = true; | 1223 send_feedback = true; |
1178 } | 1224 } |
1179 | 1225 |
1180 packet_generator_.SetShouldSendAck(send_feedback); | 1226 packet_generator_.SetShouldSendAck(send_feedback); |
1181 } | 1227 } |
1182 | 1228 |
| 1229 void QuicConnection::MaybeAbandonFecPacket( |
| 1230 QuicPacketSequenceNumber sequence_number) { |
| 1231 if (!ContainsKey(unacked_fec_packets_, sequence_number)) { |
| 1232 DVLOG(2) << ENDPOINT << "no need to abandon fec packet: " |
| 1233 << sequence_number << "; it's already acked'"; |
| 1234 return; |
| 1235 } |
| 1236 congestion_manager_.AbandoningPacket(sequence_number); |
| 1237 // TODO(satyashekhar): Should this decrease the congestion window? |
| 1238 } |
| 1239 |
1183 QuicTime QuicConnection::OnRetransmissionTimeout() { | 1240 QuicTime QuicConnection::OnRetransmissionTimeout() { |
1184 // This guards against registering the alarm later than we should. | 1241 // This guards against registering the alarm later than we should. |
1185 // | 1242 // |
1186 // If we have packet A and B in the list and we call | 1243 // If we have packet A and B in the list and we call |
1187 // MaybeRetransmitPacketForRTO on A, that may trigger a call to | 1244 // MaybeRetransmitPacketForRTO on A, that may trigger a call to |
1188 // SetRetransmissionAlarm if A is retransmitted as C. In that case we | 1245 // SetRetransmissionAlarm if A is retransmitted as C. In that case we |
1189 // don't want to register the alarm under SetRetransmissionAlarm; we | 1246 // don't want to register the alarm under SetRetransmissionAlarm; we |
1190 // want to set it to the RTO of B when we return from this function. | 1247 // want to set it to the RTO of B when we return from this function. |
1191 handling_retransmission_timeout_ = true; | 1248 handling_retransmission_timeout_ = true; |
1192 | 1249 |
1193 for (size_t i = 0; i < max_packets_per_retransmission_alarm_ && | 1250 for (size_t i = 0; i < max_packets_per_retransmission_alarm_ && |
1194 !retransmission_timeouts_.empty(); ++i) { | 1251 !retransmission_timeouts_.empty(); ++i) { |
1195 RetransmissionInfo retransmission_info = retransmission_timeouts_.top(); | 1252 RetransmissionTime retransmission_time = retransmission_timeouts_.top(); |
1196 DCHECK(retransmission_info.scheduled_time.IsInitialized()); | 1253 DCHECK(retransmission_time.scheduled_time.IsInitialized()); |
1197 if (retransmission_info.scheduled_time > clock_->ApproximateNow()) { | 1254 if (retransmission_time.scheduled_time > clock_->ApproximateNow()) { |
1198 break; | 1255 break; |
1199 } | 1256 } |
1200 retransmission_timeouts_.pop(); | 1257 retransmission_timeouts_.pop(); |
1201 if (!MaybeRetransmitPacketForRTO(retransmission_info.sequence_number)) { | 1258 |
| 1259 if (retransmission_time.for_fec) { |
| 1260 MaybeAbandonFecPacket(retransmission_time.sequence_number); |
| 1261 continue; |
| 1262 } else if ( |
| 1263 !MaybeRetransmitPacketForRTO(retransmission_time.sequence_number)) { |
1202 DLOG(INFO) << ENDPOINT << "MaybeRetransmitPacketForRTO failed: " | 1264 DLOG(INFO) << ENDPOINT << "MaybeRetransmitPacketForRTO failed: " |
1203 << "adding an extra delay for " | 1265 << "adding an extra delay for " |
1204 << retransmission_info.sequence_number; | 1266 << retransmission_time.sequence_number; |
1205 retransmission_info.scheduled_time = clock_->ApproximateNow().Add( | 1267 retransmission_time.scheduled_time = clock_->ApproximateNow().Add( |
1206 congestion_manager_.DefaultRetransmissionTime()); | 1268 congestion_manager_.DefaultRetransmissionTime()); |
1207 retransmission_timeouts_.push(retransmission_info); | 1269 retransmission_timeouts_.push(retransmission_time); |
1208 } | 1270 } |
1209 } | 1271 } |
1210 | 1272 |
1211 handling_retransmission_timeout_ = false; | 1273 handling_retransmission_timeout_ = false; |
1212 | 1274 |
1213 if (retransmission_timeouts_.empty()) { | 1275 if (retransmission_timeouts_.empty()) { |
1214 return QuicTime::Zero(); | 1276 return QuicTime::Zero(); |
1215 } | 1277 } |
1216 | 1278 |
1217 // We have packets remaining. Return the absolute RTO of the oldest packet | 1279 // We have packets remaining. Return the absolute RTO of the oldest packet |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 delete fec_group; | 1432 delete fec_group; |
1371 it = next; | 1433 it = next; |
1372 } | 1434 } |
1373 } | 1435 } |
1374 | 1436 |
1375 bool QuicConnection::HasQueuedData() const { | 1437 bool QuicConnection::HasQueuedData() const { |
1376 return !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); | 1438 return !queued_packets_.empty() || packet_generator_.HasQueuedFrames(); |
1377 } | 1439 } |
1378 | 1440 |
1379 void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { | 1441 void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { |
1380 // if (timeout < idle_network_timeout_) { | 1442 if (timeout < idle_network_timeout_) { |
1381 idle_network_timeout_ = timeout; | 1443 idle_network_timeout_ = timeout; |
1382 CheckForTimeout(); | 1444 CheckForTimeout(); |
1383 // } else { | 1445 } else { |
1384 // idle_network_timeout_ = timeout; | 1446 idle_network_timeout_ = timeout; |
1385 // } | 1447 } |
1386 } | 1448 } |
1387 | 1449 |
1388 void QuicConnection::SetOverallConnectionTimeout(QuicTime::Delta timeout) { | 1450 void QuicConnection::SetOverallConnectionTimeout(QuicTime::Delta timeout) { |
1389 // if (timeout < overall_connection_timeout_) { | 1451 if (timeout < overall_connection_timeout_) { |
1390 overall_connection_timeout_ = timeout; | 1452 overall_connection_timeout_ = timeout; |
1391 CheckForTimeout(); | 1453 CheckForTimeout(); |
1392 // } else { | 1454 } else { |
1393 // overall_connection_timeout_ = timeout; | 1455 overall_connection_timeout_ = timeout; |
1394 // } | 1456 } |
1395 } | 1457 } |
1396 | 1458 |
1397 bool QuicConnection::CheckForTimeout() { | 1459 bool QuicConnection::CheckForTimeout() { |
1398 QuicTime now = clock_->ApproximateNow(); | 1460 QuicTime now = clock_->ApproximateNow(); |
1399 QuicTime time_of_last_packet = std::max(time_of_last_received_packet_, | 1461 QuicTime time_of_last_packet = std::max(time_of_last_received_packet_, |
1400 time_of_last_sent_packet_); | 1462 time_of_last_sent_packet_); |
1401 | 1463 |
| 1464 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| |
| 1465 // is accurate time. However, this should not change the behavior of |
| 1466 // timeout handling. |
1402 QuicTime::Delta delta = now.Subtract(time_of_last_packet); | 1467 QuicTime::Delta delta = now.Subtract(time_of_last_packet); |
1403 DVLOG(1) << ENDPOINT << "last packet " | 1468 DVLOG(1) << ENDPOINT << "last packet " |
1404 << time_of_last_packet.ToDebuggingValue() | 1469 << time_of_last_packet.ToDebuggingValue() |
1405 << " now:" << now.ToDebuggingValue() | 1470 << " now:" << now.ToDebuggingValue() |
1406 << " delta:" << delta.ToMicroseconds() | 1471 << " delta:" << delta.ToMicroseconds() |
1407 << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); | 1472 << " network_timeout: " << idle_network_timeout_.ToMicroseconds(); |
1408 if (delta >= idle_network_timeout_) { | 1473 if (delta >= idle_network_timeout_) { |
1409 DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; | 1474 DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; |
1410 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 1475 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
1411 return true; | 1476 return true; |
(...skipping 20 matching lines...) Expand all Loading... |
1432 if (connection_timeout < timeout) { | 1497 if (connection_timeout < timeout) { |
1433 timeout = connection_timeout; | 1498 timeout = connection_timeout; |
1434 } | 1499 } |
1435 } | 1500 } |
1436 | 1501 |
1437 helper_->SetTimeoutAlarm(timeout); | 1502 helper_->SetTimeoutAlarm(timeout); |
1438 return false; | 1503 return false; |
1439 } | 1504 } |
1440 | 1505 |
1441 } // namespace net | 1506 } // namespace net |
OLD | NEW |