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 kMaxAckedPackets = 5000u; | 27 const QuicPacketSequenceNumber kMaxUnackedPackets = 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 <= kMaxAckedPackets; | 34 return delta <= kMaxUnackedPackets; |
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 (info.ContainsAck(header.packet_sequence_number)) { | 108 if (header.packet_sequence_number <= info.largest_received && |
| 109 info.missing_packets.count(header.packet_sequence_number) != 1) { |
109 return false; | 110 return false; |
110 } | 111 } |
111 | 112 |
112 last_header_ = header; | 113 last_header_ = header; |
113 return true; | 114 return true; |
114 } | 115 } |
115 | 116 |
116 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { | 117 void QuicConnection::OnFecProtectedPayload(StringPiece payload) { |
117 DCHECK_NE(0, last_header_.fec_group); | 118 DCHECK_NE(0, last_header_.fec_group); |
118 QuicFecGroup* group = GetFecGroup(); | 119 QuicFecGroup* group = GetFecGroup(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { | 161 bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) { |
161 if (incoming_ack.received_info.largest_received > | 162 if (incoming_ack.received_info.largest_received > |
162 packet_creator_.sequence_number()) { | 163 packet_creator_.sequence_number()) { |
163 DLOG(ERROR) << "Client acked unsent packet:" | 164 DLOG(ERROR) << "Client acked unsent packet:" |
164 << incoming_ack.received_info.largest_received << " vs " | 165 << incoming_ack.received_info.largest_received << " vs " |
165 << packet_creator_.sequence_number(); | 166 << packet_creator_.sequence_number(); |
166 // We got an error for data we have not sent. Error out. | 167 // We got an error for data we have not sent. Error out. |
167 return false; | 168 return false; |
168 } | 169 } |
169 | 170 |
170 // We can't have too many acked packets, or our ack frames go over | 171 // We can't have too many missing or retransmitting packets, or our ack |
171 // kMaxPacketSize. | 172 // frames go over kMaxPacketSize. |
172 DCHECK_LT(incoming_ack.received_info.received_packet_times.size(), | 173 DCHECK_LT(incoming_ack.received_info.missing_packets.size(), |
173 kMaxAckedPackets); | 174 kMaxUnackedPackets); |
| 175 DCHECK_LT(incoming_ack.sent_info.non_retransmiting.size(), |
| 176 kMaxUnackedPackets); |
174 | 177 |
175 if (incoming_ack.sent_info.least_unacked != 0 && | 178 if (incoming_ack.sent_info.least_unacked != 0 && |
176 incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { | 179 incoming_ack.sent_info.least_unacked < least_packet_awaiting_ack_) { |
177 DLOG(INFO) << "Client sent low least_unacked"; | 180 DLOG(INFO) << "Client sent low least_unacked"; |
178 // We never process old ack frames, so this number should only increase. | 181 // We never process old ack frames, so this number should only increase. |
179 return false; | 182 return false; |
180 } | 183 } |
181 | 184 |
182 return true; | 185 return true; |
183 } | 186 } |
184 | 187 |
185 void QuicConnection::UpdatePacketInformationReceivedByPeer( | 188 void QuicConnection::UpdatePacketInformationReceivedByPeer( |
186 const QuicAckFrame& incoming_ack) { | 189 const QuicAckFrame& incoming_ack) { |
187 QuicConnectionVisitorInterface::AckedPackets acked_packets; | 190 QuicConnectionVisitorInterface::AckedPackets acked_packets; |
188 | 191 |
189 // Initialize the lowest unacked packet to the lower of the next outgoing | 192 // Initialize the lowest unacked packet to the lower of the next outgoing |
190 // sequence number and the largest received packed in the incoming ack. | 193 // sequence number and the largest received packed in the incoming ack. |
191 QuicPacketSequenceNumber lowest_unacked = min( | 194 QuicPacketSequenceNumber lowest_unacked = min( |
192 packet_creator_.sequence_number() + 1, | 195 packet_creator_.sequence_number() + 1, |
193 incoming_ack.received_info.largest_received + 1); | 196 incoming_ack.received_info.largest_received + 1); |
194 | 197 |
195 // Go through the packets we have not received an ack for and see if this | 198 // Go through the packets we have not received an ack for and see if this |
196 // incoming_ack shows they've been seen by the peer. | 199 // incoming_ack shows they've been seen by the peer. |
197 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 200 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
198 while (it != unacked_packets_.end()) { | 201 while (it != unacked_packets_.end()) { |
199 if (incoming_ack.received_info.ContainsAck(it->first)) { | 202 if ((it->first < incoming_ack.received_info.largest_received && |
| 203 !ContainsKey(incoming_ack.received_info.missing_packets, it->first)) || |
| 204 it->first == incoming_ack.received_info.largest_received) { |
200 // Packet was acked, so remove it from our unacked packet list. | 205 // Packet was acked, so remove it from our unacked packet list. |
201 DVLOG(1) << "Got an ack for " << it->first; | 206 DVLOG(1) << "Got an ack for " << it->first; |
202 // TODO(rch): This is inefficient and should be sped up. | 207 // TODO(rch): This is inefficient and should be sped up. |
203 // The acked packet might be queued (if a resend had been attempted). | 208 // The acked packet might be queued (if a resend had been attempted). |
204 for (QueuedPacketList::iterator q = queued_packets_.begin(); | 209 for (QueuedPacketList::iterator q = queued_packets_.begin(); |
205 q != queued_packets_.end(); ++q) { | 210 q != queued_packets_.end(); ++q) { |
206 if (q->sequence_number == it->first) { | 211 if (q->sequence_number == it->first) { |
207 queued_packets_.erase(q); | 212 queued_packets_.erase(q); |
208 break; | 213 break; |
209 } | 214 } |
(...skipping 14 matching lines...) Expand all Loading... |
224 ++it; | 229 ++it; |
225 } | 230 } |
226 } | 231 } |
227 if (acked_packets.size() > 0) { | 232 if (acked_packets.size() > 0) { |
228 visitor_->OnAck(acked_packets); | 233 visitor_->OnAck(acked_packets); |
229 } | 234 } |
230 | 235 |
231 // If we've gotten an ack for the lowest packet we were waiting on, | 236 // If we've gotten an ack for the lowest packet we were waiting on, |
232 // update that and the list of packets we advertise we will not resend. | 237 // update that and the list of packets we advertise we will not resend. |
233 if (lowest_unacked > outgoing_ack_.sent_info.least_unacked) { | 238 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 } |
234 // If all packets we sent have been acked, use the special value of 0 | 246 // If all packets we sent have been acked, use the special value of 0 |
235 if (lowest_unacked > packet_creator_.sequence_number()) { | 247 if (lowest_unacked > packet_creator_.sequence_number()) { |
236 lowest_unacked = 0; | 248 lowest_unacked = 0; |
| 249 DCHECK_EQ(0u, non_retrans->size()); |
237 } | 250 } |
238 outgoing_ack_.sent_info.least_unacked = lowest_unacked; | 251 outgoing_ack_.sent_info.least_unacked = lowest_unacked; |
239 } | 252 } |
240 } | 253 } |
241 | 254 |
242 void QuicConnection::UpdatePacketInformationSentByPeer( | 255 void QuicConnection::UpdatePacketInformationSentByPeer( |
243 const QuicAckFrame& incoming_ack) { | 256 const QuicAckFrame& incoming_ack) { |
244 // Make sure we also don't ack any packets lower than the peer's | 257 // Iteratate through the packets which will the peer will not resend and |
| 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 |
245 // last-packet-awaiting-ack. | 267 // last-packet-awaiting-ack. |
246 if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { | 268 if (incoming_ack.sent_info.least_unacked > least_packet_awaiting_ack_) { |
247 outgoing_ack_.received_info.ClearAcksBefore( | 269 for (QuicPacketSequenceNumber i = least_packet_awaiting_ack_; |
248 incoming_ack.sent_info.least_unacked); | 270 i < incoming_ack.sent_info.least_unacked; ++i) { |
| 271 outgoing_ack_.received_info.missing_packets.erase(i); |
| 272 } |
249 least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; | 273 least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked; |
250 } | 274 } |
251 | 275 |
252 // Possibly close any FecGroups which are now irrelevant | 276 // Possibly close any FecGroups which are now irrelevant |
253 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); | 277 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); |
254 } | 278 } |
255 | 279 |
256 void QuicConnection::OnFecData(const QuicFecData& fec) { | 280 void QuicConnection::OnFecData(const QuicFecData& fec) { |
257 DCHECK_NE(0, last_header_.fec_group); | 281 DCHECK_NE(0, last_header_.fec_group); |
258 QuicFecGroup* group = GetFecGroup(); | 282 QuicFecGroup* group = GetFecGroup(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 num_queued_packets = queued_packets_.size(); | 387 num_queued_packets = queued_packets_.size(); |
364 QueuedPacket p = queued_packets_.front(); | 388 QueuedPacket p = queued_packets_.front(); |
365 queued_packets_.pop_front(); | 389 queued_packets_.pop_front(); |
366 SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit); | 390 SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit); |
367 } | 391 } |
368 return !write_blocked_; | 392 return !write_blocked_; |
369 } | 393 } |
370 | 394 |
371 void QuicConnection::AckPacket(const QuicPacketHeader& header) { | 395 void QuicConnection::AckPacket(const QuicPacketHeader& header) { |
372 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; | 396 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; |
373 outgoing_ack_.received_info.RecordAck(sequence_number, clock_->Now()); | 397 if (sequence_number > outgoing_ack_.received_info.largest_received) { |
| 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 } |
374 // TODO(alyssar) delay sending until we have data, or enough time has elapsed. | 414 // TODO(alyssar) delay sending until we have data, or enough time has elapsed. |
375 if (frames_.size() > 0) { | 415 if (frames_.size() > 0) { |
376 SendAck(); | 416 SendAck(); |
377 } | 417 } |
378 } | 418 } |
379 | 419 |
380 void QuicConnection::MaybeResendPacket( | 420 void QuicConnection::MaybeResendPacket( |
381 QuicPacketSequenceNumber sequence_number) { | 421 QuicPacketSequenceNumber sequence_number) { |
382 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); | 422 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); |
383 | 423 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 } | 464 } |
425 } | 465 } |
426 if (should_resend) { | 466 if (should_resend) { |
427 helper_->SetResendAlarm(sequence_number, DefaultResendTime()); | 467 helper_->SetResendAlarm(sequence_number, DefaultResendTime()); |
428 // The second case should never happen in the real world, but does here | 468 // The second case should never happen in the real world, but does here |
429 // because we sometimes send out of order to validate corner cases. | 469 // because we sometimes send out of order to validate corner cases. |
430 if (outgoing_ack_.sent_info.least_unacked == 0 || | 470 if (outgoing_ack_.sent_info.least_unacked == 0 || |
431 sequence_number < outgoing_ack_.sent_info.least_unacked) { | 471 sequence_number < outgoing_ack_.sent_info.least_unacked) { |
432 outgoing_ack_.sent_info.least_unacked = sequence_number; | 472 outgoing_ack_.sent_info.least_unacked = sequence_number; |
433 } | 473 } |
| 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 } |
434 } | 479 } |
435 | 480 |
436 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); | 481 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); |
437 int error; | 482 int error; |
438 DLOG(INFO) << "Sending packet : " | 483 DLOG(INFO) << "Sending packet : " |
439 << (should_resend ? "data bearing " : " ack only ") | 484 << (should_resend ? "data bearing " : " ack only ") |
440 << "packet " << sequence_number; | 485 << "packet " << sequence_number; |
441 int rv = helper_->WritePacketToWire(*encrypted, &error); | 486 int rv = helper_->WritePacketToWire(*encrypted, &error); |
442 if (rv == -1) { | 487 if (rv == -1) { |
443 if (error == ERR_IO_PENDING) { | 488 if (error == ERR_IO_PENDING) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 << " delta:" << delta.ToMicroseconds(); | 598 << " delta:" << delta.ToMicroseconds(); |
554 if (delta >= timeout_) { | 599 if (delta >= timeout_) { |
555 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); | 600 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); |
556 return true; | 601 return true; |
557 } | 602 } |
558 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); | 603 helper_->SetTimeoutAlarm(timeout_.Subtract(delta)); |
559 return false; | 604 return false; |
560 } | 605 } |
561 | 606 |
562 } // namespace net | 607 } // namespace net |
OLD | NEW |