Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: net/quic/quic_connection.cc

Issue 11416155: Adding transmission times for every QUIC packet received in the AckFrame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/congestion_control/quic_send_scheduler_test.cc ('k') | net/quic/quic_connection_helper_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698