| 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" |
| 11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 12 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h" | 12 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h" |
| 13 #include "net/quic/congestion_control/quic_send_scheduler.h" | 13 #include "net/quic/congestion_control/quic_send_scheduler.h" |
| 14 #include "net/quic/quic_utils.h" | 14 #include "net/quic/quic_utils.h" |
| 15 | 15 |
| 16 using base::hash_map; | 16 using base::hash_map; |
| 17 using base::hash_set; | 17 using base::hash_set; |
| 18 using base::StringPiece; | 18 using base::StringPiece; |
| 19 using std::list; | 19 using std::list; |
| 20 using std::min; | 20 using std::min; |
| 21 using std::vector; | 21 using std::vector; |
| 22 using std::set; | 22 using std::set; |
| 23 | 23 |
| 24 namespace net { | 24 namespace net { |
| 25 | 25 |
| 26 // An arbitrary number we'll probably want to tune. | 26 // An arbitrary number we'll probably want to tune. |
| 27 const QuicPacketSequenceNumber kMaxUnackedPackets = 5000u; | 27 const QuicPacketSequenceNumber kMaxAckedPackets = 5000u; |
| 28 | 28 |
| 29 // The amount of time we wait before resending a packet. | 29 // The amount of time we wait before resending a packet. |
| 30 const int64 kDefaultResendTimeMs = 500; | 30 const int64 kDefaultResendTimeMs = 500; |
| 31 | 31 |
| 32 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 32 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
| 33 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 33 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
| 34 return delta <= kMaxUnackedPackets; | 34 return delta <= kMaxAckedPackets; |
| 35 } | 35 } |
| 36 | 36 |
| 37 QuicConnection::QuicConnection(QuicGuid guid, | 37 QuicConnection::QuicConnection(QuicGuid guid, |
| 38 IPEndPoint address, | 38 IPEndPoint address, |
| 39 QuicConnectionHelperInterface* helper) | 39 QuicConnectionHelperInterface* helper) |
| 40 : helper_(helper), | 40 : helper_(helper), |
| 41 framer_(QuicDecrypter::Create(kNULL), QuicEncrypter::Create(kNULL)), | 41 framer_(QuicDecrypter::Create(kNULL), QuicEncrypter::Create(kNULL)), |
| 42 clock_(helper->GetClock()), | 42 clock_(helper->GetClock()), |
| 43 guid_(guid), | 43 guid_(guid), |
| 44 peer_address_(address), | 44 peer_address_(address), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { | 98 bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) { |
| 99 if (!Near(header.packet_sequence_number, | 99 if (!Near(header.packet_sequence_number, |
| 100 last_header_.packet_sequence_number)) { | 100 last_header_.packet_sequence_number)) { |
| 101 DLOG(INFO) << "Packet out of bounds. Discarding"; | 101 DLOG(INFO) << "Packet out of bounds. Discarding"; |
| 102 return false; | 102 return false; |
| 103 } | 103 } |
| 104 | 104 |
| 105 ReceivedPacketInfo info = outgoing_ack_.received_info; | 105 ReceivedPacketInfo info = outgoing_ack_.received_info; |
| 106 // If this packet has already been seen, or that the sender | 106 // If this packet has already been seen, or that the sender |
| 107 // has told us will not be resent, then stop processing the packet. | 107 // has told us will not be resent, then stop processing the packet. |
| 108 if (header.packet_sequence_number <= info.largest_received && | 108 if (info.ContainsAck(header.packet_sequence_number)) { |
| 109 info.missing_packets.count(header.packet_sequence_number) != 1) { | |
| 110 return false; | 109 return false; |
| 111 } | 110 } |
| 112 | 111 |
| 113 last_header_ = header; | 112 last_header_ = header; |
| 114 return true; | 113 return true; |
| 115 } | 114 } |
| 116 | 115 |
| 117 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { | 116 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { |
| 118 DCHECK_NE(0, last_header_.fec_group); | 117 DCHECK_NE(0, last_header_.fec_group); |
| 119 QuicFecGroup* group = GetFecGroup(); | 118 QuicFecGroup* group = GetFecGroup(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { | 160 bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { |
| 162 if (incoming_ack.received_info.largest_received > | 161 if (incoming_ack.received_info.largest_received > |
| 163 packet_creator_.sequence_number()) { | 162 packet_creator_.sequence_number()) { |
| 164 DLOG(ERROR) << "Client acked unsent packet:" | 163 DLOG(ERROR) << "Client acked unsent packet:" |
| 165 << incoming_ack.received_info.largest_received << " vs " | 164 << incoming_ack.received_info.largest_received << " vs " |
| 166 << packet_creator_.sequence_number(); | 165 << packet_creator_.sequence_number(); |
| 167 // We got an error for data we have not sent. Error out. | 166 // We got an error for data we have not sent. Error out. |
| 168 return false; | 167 return false; |
| 169 } | 168 } |
| 170 | 169 |
| 171 // We can't have too many missing or retransmitting packets, or our ack | 170 // We can't have too many acked packets, or our ack frames go over |
| 172 // frames go over kMaxPacketSize. | 171 // kMaxPacketSize. |
| 173 DCHECK_LT(incoming_ack.received_info.missing_packets.size(), | 172 DCHECK_LT(incoming_ack.received_info.received_packet_times.size(), |
| 174 kMaxUnackedPackets); | 173 kMaxAckedPackets); |
| 175 DCHECK_LT(incoming_ack.sent_info.non_retransmiting.size(), | |
| 176 kMaxUnackedPackets); | |
| 177 | 174 |
| 178 if (incoming_ack.sent_info.least_unacked != 0 && | 175 if (incoming_ack.sent_info.least_unacked != 0 && |
| 179 incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { | 176 incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { |
| 180 DLOG(INFO) << "Client sent low least_unacked"; | 177 DLOG(INFO) << "Client sent low least_unacked"; |
| 181 // We never process old ack frames, so this number should only increase. | 178 // We never process old ack frames, so this number should only increase. |
| 182 return false; | 179 return false; |
| 183 } | 180 } |
| 184 | 181 |
| 185 return true; | 182 return true; |
| 186 } | 183 } |
| 187 | 184 |
| 188 void QuicConnection::UpdatePacketInformationReceivedByPeer( | 185 void QuicConnection::UpdatePacketInformationReceivedByPeer( |
| 189 const QuicAckFrame& incoming_ack) { | 186 const QuicAckFrame& incoming_ack) { |
| 190 QuicConnectionVisitorInterface::AckedPackets acked_packets; | 187 QuicConnectionVisitorInterface::AckedPackets acked_packets; |
| 191 | 188 |
| 192 // Initialize the lowest unacked packet to the lower of the next outgoing | 189 // Initialize the lowest unacked packet to the lower of the next outgoing |
| 193 // sequence number and the largest received packed in the incoming ack. | 190 // sequence number and the largest received packed in the incoming ack. |
| 194 QuicPacketSequenceNumber lowest_unacked = min( | 191 QuicPacketSequenceNumber lowest_unacked = min( |
| 195 packet_creator_.sequence_number() + 1, | 192 packet_creator_.sequence_number() + 1, |
| 196 incoming_ack.received_info.largest_received + 1); | 193 incoming_ack.received_info.largest_received + 1); |
| 197 | 194 |
| 198 // Go through the packets we have not received an ack for and see if this | 195 // Go through the packets we have not received an ack for and see if this |
| 199 // incoming_ack shows they've been seen by the peer. | 196 // incoming_ack shows they've been seen by the peer. |
| 200 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 197 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 201 while (it != unacked_packets_.end()) { | 198 while (it != unacked_packets_.end()) { |
| 202 if ((it->first < incoming_ack.received_info.largest_received && | 199 if (incoming_ack.received_info.ContainsAck(it->first)) { |
| 203 !ContainsKey(incoming_ack.received_info.missing_packets, it->first)) || | |
| 204 it->first == incoming_ack.received_info.largest_received) { | |
| 205 // Packet was acked, so remove it from our unacked packet list. | 200 // Packet was acked, so remove it from our unacked packet list. |
| 206 DVLOG(1) << "Got an ack for " << it->first; | 201 DVLOG(1) << "Got an ack for " << it->first; |
| 207 // TODO(rch): This is inefficient and should be sped up. | 202 // TODO(rch): This is inefficient and should be sped up. |
| 208 // The acked packet might be queued (if a resend had been attempted). | 203 // The acked packet might be queued (if a resend had been attempted). |
| 209 for (QueuedPacketList::iterator q = queued_packets_.begin(); | 204 for (QueuedPacketList::iterator q = queued_packets_.begin(); |
| 210 q != queued_packets_.end(); ++q) { | 205 q != queued_packets_.end(); ++q) { |
| 211 if (q->sequence_number == it->first) { | 206 if (q->sequence_number == it->first) { |
| 212 queued_packets_.erase(q); | 207 queued_packets_.erase(q); |
| 213 break; | 208 break; |
| 214 } | 209 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 229 ++it; | 224 ++it; |
| 230 } | 225 } |
| 231 } | 226 } |
| 232 if (acked_packets.size() > 0) { | 227 if (acked_packets.size() > 0) { |
| 233 visitor_->OnAck(acked_packets); | 228 visitor_->OnAck(acked_packets); |
| 234 } | 229 } |
| 235 | 230 |
| 236 // If we've gotten an ack for the lowest packet we were waiting on, | 231 // If we've gotten an ack for the lowest packet we were waiting on, |
| 237 // update that and the list of packets we advertise we will not resend. | 232 // update that and the list of packets we advertise we will not resend. |
| 238 if (lowest_unacked > outgoing_ack_.sent_info.least_unacked) { | 233 if (lowest_unacked > outgoing_ack_.sent_info.least_unacked) { |
| 239 SequenceSet* non_retrans = &outgoing_ack_.sent_info.non_retransmiting; | |
| 240 // We don't need to advertise not-resending packets between the old | |
| 241 // and new values. | |
| 242 for (QuicPacketSequenceNumber i = outgoing_ack_.sent_info.least_unacked; | |
| 243 i < lowest_unacked; ++i) { | |
| 244 non_retrans->erase(i); | |
| 245 } | |
| 246 // If all packets we sent have been acked, use the special value of 0 | 234 // If all packets we sent have been acked, use the special value of 0 |
| 247 if (lowest_unacked > packet_creator_.sequence_number()) { | 235 if (lowest_unacked > packet_creator_.sequence_number()) { |
| 248 lowest_unacked = 0; | 236 lowest_unacked = 0; |
| 249 DCHECK_EQ(0u, non_retrans->size()); | |
| 250 } | 237 } |
| 251 outgoing_ack_.sent_info.least_unacked = lowest_unacked; | 238 outgoing_ack_.sent_info.least_unacked = lowest_unacked; |
| 252 } | 239 } |
| 253 } | 240 } |
| 254 | 241 |
| 255 void QuicConnection::UpdatePacketInformationSentByPeer( | 242 void QuicConnection::UpdatePacketInformationSentByPeer( |
| 256 const QuicAckFrame& incoming_ack) { | 243 const QuicAckFrame& incoming_ack) { |
| 257 // Iteratate through the packets which will the peer will not resend and | 244 // Make sure we also don't ack any packets lower than the peer's |
| 258 // remove them from our missing list. | |
| 259 for (SequenceSet::const_iterator it = | |
| 260 incoming_ack.sent_info.non_retransmiting.begin(); | |
| 261 it != incoming_ack.sent_info.non_retransmiting.end(); ++it) { | |
| 262 DVLOG(1) << "no longer expecting " << *it; | |
| 263 outgoing_ack_.received_info.missing_packets.erase(*it); | |
| 264 } | |
| 265 | |
| 266 // Make sure we also don't expect any packets lower than the peer's | |
| 267 // last-packet-awaiting-ack. | 245 // last-packet-awaiting-ack. |
| 268 if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { | 246 if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { |
| 269 for (QuicPacketSequenceNumber i = least_packet_awaiting_ack_; | 247 outgoing_ack_.received_info.ClearAcksBefore( |
| 270 i < incoming_ack.sent_info.least_unacked; ++i) { | 248 incoming_ack.sent_info.least_unacked); |
| 271 outgoing_ack_.received_info.missing_packets.erase(i); | |
| 272 } | |
| 273 least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; | 249 least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; |
| 274 } | 250 } |
| 275 | 251 |
| 276 // Possibly close any FecGroups which are now irrelevant | 252 // Possibly close any FecGroups which are now irrelevant |
| 277 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); | 253 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); |
| 278 } | 254 } |
| 279 | 255 |
| 280 void QuicConnection::OnFecData(const QuicFecData& fec) { | 256 void QuicConnection::OnFecData(const QuicFecData& fec) { |
| 281 DCHECK_NE(0, last_header_.fec_group); | 257 DCHECK_NE(0, last_header_.fec_group); |
| 282 QuicFecGroup* group = GetFecGroup(); | 258 QuicFecGroup* group = GetFecGroup(); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 num_queued_packets = queued_packets_.size(); | 363 num_queued_packets = queued_packets_.size(); |
| 388 QueuedPacket p = queued_packets_.front(); | 364 QueuedPacket p = queued_packets_.front(); |
| 389 queued_packets_.pop_front(); | 365 queued_packets_.pop_front(); |
| 390 SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit); | 366 SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit); |
| 391 } | 367 } |
| 392 return !write_blocked_; | 368 return !write_blocked_; |
| 393 } | 369 } |
| 394 | 370 |
| 395 void QuicConnection::AckPacket(const QuicPacketHeader& header) { | 371 void QuicConnection::AckPacket(const QuicPacketHeader& header) { |
| 396 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; | 372 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
| 397 if (sequence_number > outgoing_ack_.received_info.largest_received) { | 373 outgoing_ack_.received_info.RecordAck(sequence_number, clock_->Now()); |
| 398 // We've got a new high sequence number. Note any new intermediate missing | |
| 399 // packets, and update the last_ack data. | |
| 400 for (QuicPacketSequenceNumber i = | |
| 401 outgoing_ack_.received_info.largest_received + 1; | |
| 402 i < sequence_number; ++i) { | |
| 403 DVLOG(1) << "missing " << i; | |
| 404 outgoing_ack_.received_info.missing_packets.insert(i); | |
| 405 } | |
| 406 outgoing_ack_.received_info.largest_received = sequence_number; | |
| 407 outgoing_ack_.received_info.time_received = clock_->Now(); | |
| 408 } else { | |
| 409 // We've gotten one of the out of order packets - remove it from our | |
| 410 // "missing packets" list. | |
| 411 DVLOG(1) << "Removing " << sequence_number << " from missing list"; | |
| 412 outgoing_ack_.received_info.missing_packets.erase(sequence_number); | |
| 413 } | |
| 414 // TODO(alyssar) delay sending until we have data, or enough time has elapsed. | 374 // TODO(alyssar) delay sending until we have data, or enough time has elapsed. |
| 415 if (frames_.size() > 0) { | 375 if (frames_.size() > 0) { |
| 416 SendAck(); | 376 SendAck(); |
| 417 } | 377 } |
| 418 } | 378 } |
| 419 | 379 |
| 420 void QuicConnection::MaybeResendPacket( | 380 void QuicConnection::MaybeResendPacket( |
| 421 QuicPacketSequenceNumber sequence_number) { | 381 QuicPacketSequenceNumber sequence_number) { |
| 422 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 382 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
| 423 | 383 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 } | 424 } |
| 465 } | 425 } |
| 466 if (should_resend) { | 426 if (should_resend) { |
| 467 helper_->SetResendAlarm(sequence_number, DefaultResendTime()); | 427 helper_->SetResendAlarm(sequence_number, DefaultResendTime()); |
| 468 // The second case should never happen in the real world, but does here | 428 // The second case should never happen in the real world, but does here |
| 469 // because we sometimes send out of order to validate corner cases. | 429 // because we sometimes send out of order to validate corner cases. |
| 470 if (outgoing_ack_.sent_info.least_unacked == 0 || | 430 if (outgoing_ack_.sent_info.least_unacked == 0 || |
| 471 sequence_number < outgoing_ack_.sent_info.least_unacked) { | 431 sequence_number < outgoing_ack_.sent_info.least_unacked) { |
| 472 outgoing_ack_.sent_info.least_unacked = sequence_number; | 432 outgoing_ack_.sent_info.least_unacked = sequence_number; |
| 473 } | 433 } |
| 474 } else { | |
| 475 if (outgoing_ack_.sent_info.least_unacked != 0 && | |
| 476 sequence_number > outgoing_ack_.sent_info.least_unacked) { | |
| 477 outgoing_ack_.sent_info.non_retransmiting.insert(sequence_number); | |
| 478 } | |
| 479 } | 434 } |
| 480 | 435 |
| 481 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); | 436 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); |
| 482 int error; | 437 int error; |
| 483 DLOG(INFO) << "Sending packet : " | 438 DLOG(INFO) << "Sending packet : " |
| 484 << (should_resend ? "data bearing " : " ack only ") | 439 << (should_resend ? "data bearing " : " ack only ") |
| 485 << "packet " << sequence_number; | 440 << "packet " << sequence_number; |
| 486 int rv = helper_->WritePacketToWire(*encrypted, &error); | 441 int rv = helper_->WritePacketToWire(*encrypted, &error); |
| 487 if (rv == -1) { | 442 if (rv == -1) { |
| 488 if (error == ERR_IO_PENDING) { | 443 if (error == ERR_IO_PENDING) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 << " delta:" << delta.ToMicroseconds(); | 553 << " delta:" << delta.ToMicroseconds(); |
| 599 if (delta >= timeout_) { | 554 if (delta >= timeout_) { |
| 600 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 555 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
| 601 return true; | 556 return true; |
| 602 } | 557 } |
| 603 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 558 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); |
| 604 return false; | 559 return false; |
| 605 } | 560 } |
| 606 | 561 |
| 607 } // namespace net | 562 } // namespace net |
| OLD | NEW |