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. |
jar (doing other things)
2012/11/29 21:51:40
nit: Please add a comment explaining the intent of
Ian Swett
2012/12/04 21:40:19
I changed the naming and check back to the old app
Ryan Hamilton
2012/12/04 21:52:54
Not really. I suspect that until we have flow con
| |
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 |
jar (doing other things)
2012/11/29 21:51:40
nit: This limitation is probably on the count of s
Ian Swett
2012/12/04 21:40:19
Changed back to the old comment and check in the c
| |
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 |