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

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

Issue 11377096: Change from re-transmitting an packet with a retransmit number to sending a new packet with a new s… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_helper_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "base/stl_util.h" 10 #include "base/stl_util.h"
9 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
10 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h" 12 #include "net/quic/congestion_control/quic_receipt_metrics_collector.h"
11 #include "net/quic/congestion_control/quic_send_scheduler.h" 13 #include "net/quic/congestion_control/quic_send_scheduler.h"
12 #include "net/quic/quic_utils.h" 14 #include "net/quic/quic_utils.h"
13 15
14 using base::hash_map; 16 using base::hash_map;
15 using base::hash_set; 17 using base::hash_set;
16 using base::StringPiece; 18 using base::StringPiece;
17 using std::list; 19 using std::list;
20 using std::min;
18 using std::vector; 21 using std::vector;
19 using std::set; 22 using std::set;
20 23
21 /* 24 /*
22 DEFINE_int32(fake_packet_loss_percentage, 0, 25 DEFINE_int32(fake_packet_loss_percentage, 0,
23 "The percentage of packets to drop."); 26 "The percentage of packets to drop.");
24 DEFINE_int32(negotiated_timeout_us, net::kDefaultTimeout, 27 DEFINE_int32(negotiated_timeout_us, net::kDefaultTimeout,
25 "The default timeout for connections being closed"); 28 "The default timeout for connections being closed");
26 */ 29 */
27 30
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 return false; 185 return false;
183 } 186 }
184 187
185 return true; 188 return true;
186 } 189 }
187 190
188 void QuicConnection::UpdatePacketInformationReceivedByPeer( 191 void QuicConnection::UpdatePacketInformationReceivedByPeer(
189 const QuicAckFrame& incoming_ack) { 192 const QuicAckFrame& incoming_ack) {
190 QuicConnectionVisitorInterface::AckedPackets acked_packets; 193 QuicConnectionVisitorInterface::AckedPackets acked_packets;
191 194
192 // For tracking the lowest unacked packet, pick one we have not sent yet. 195 // Initialize the lowest unacked packet to the lower of the next outgoing
193 QuicPacketSequenceNumber lowest_unacked = 196 // sequence number and the largest received packed in the incoming ack.
194 packet_creator_.sequence_number() + 1; 197 QuicPacketSequenceNumber lowest_unacked = min(
195 198 packet_creator_.sequence_number() + 1,
196 // If there's a packet between the next one we're sending and the 199 incoming_ack.received_info.largest_received + 1);
197 // highest one the peer has seen, that's our new lowest unacked.
198 if (incoming_ack.received_info.largest_received + 1 < lowest_unacked) {
199 lowest_unacked = incoming_ack.received_info.largest_received + 1;
200 }
201 200
202 // Go through the packets we have not received an ack for and see if this 201 // Go through the packets we have not received an ack for and see if this
203 // incoming_ack shows they've been seen by the peer. 202 // incoming_ack shows they've been seen by the peer.
204 UnackedPacketMap::iterator it = unacked_packets_.begin(); 203 UnackedPacketMap::iterator it = unacked_packets_.begin();
205 while (it != unacked_packets_.end()) { 204 while (it != unacked_packets_.end()) {
206 if ((it->first < incoming_ack.received_info.largest_received && 205 if ((it->first < incoming_ack.received_info.largest_received &&
207 incoming_ack.received_info.missing_packets.find(it->first) == 206 !ContainsKey(incoming_ack.received_info.missing_packets, it->first)) ||
208 incoming_ack.received_info.missing_packets.end()) ||
209 it->first == incoming_ack.received_info.largest_received) { 207 it->first == incoming_ack.received_info.largest_received) {
210 // This was either explicitly or implicitly acked. Remove it from our 208 // This was either explicitly or implicitly acked. Remove it from our
211 // unacked packet list. 209 // unacked packet list.
212 DVLOG(1) << "Got an ack for " << it->first; 210 DVLOG(1) << "Got an ack for " << it->first;
213 // TODO(rch): This is inefficient and should be sped up. 211 // TODO(rch): This is inefficient and should be sped up.
214 // The acked packet might be queued (if a resend had been attempted). 212 // The acked packet might be queued (if a resend had been attempted).
215 for (QueuedPacketList::iterator q = queued_packets_.begin(); 213 for (QueuedPacketList::iterator q = queued_packets_.begin();
216 q != queued_packets_.end(); ++q) { 214 q != queued_packets_.end(); ++q) {
217 if (q->sequence_number == it->first) { 215 if (q->sequence_number == it->first) {
218 queued_packets_.erase(q); 216 queued_packets_.erase(q);
219 break; 217 break;
220 } 218 }
221 } 219 }
220 acked_packets.insert(it->first);
222 delete it->second; 221 delete it->second;
223 UnackedPacketMap::iterator tmp_it = it; 222 UnackedPacketMap::iterator it_tmp = it;
224 acked_packets.insert(it->first); 223 ++it;
225 ++tmp_it; 224 unacked_packets_.erase(it_tmp);
226 unacked_packets_.erase(it);
227 it = tmp_it;
228 } else { 225 } else {
229 // This is a packet which we planned on resending and has not been 226 // This is a packet which we planned on resending and has not been
230 // seen at the time of this ack being sent out. See if it's our new 227 // seen at the time of this ack being sent out. See if it's our new
231 // lowest unacked packet. 228 // lowest unacked packet.
232 DVLOG(1) << "still missing " << it->first; 229 DVLOG(1) << "still missing " << it->first;
233 if (it->first < lowest_unacked) { 230 if (it->first < lowest_unacked) {
234 lowest_unacked = it->first; 231 lowest_unacked = it->first;
235 } 232 }
236 ++it; 233 ++it;
237 } 234 }
(...skipping 18 matching lines...) Expand all
256 DCHECK_EQ(0u, non_retrans->size()); 253 DCHECK_EQ(0u, non_retrans->size());
257 } 254 }
258 outgoing_ack_.sent_info.least_unacked = lowest_unacked; 255 outgoing_ack_.sent_info.least_unacked = lowest_unacked;
259 } 256 }
260 } 257 }
261 258
262 void QuicConnection::UpdatePacketInformationSentByPeer( 259 void QuicConnection::UpdatePacketInformationSentByPeer(
263 const QuicAckFrame& incoming_ack) { 260 const QuicAckFrame& incoming_ack) {
264 // Iteratate through the packets which will the peer will not resend and 261 // Iteratate through the packets which will the peer will not resend and
265 // remove them from our missing list. 262 // remove them from our missing list.
266 hash_set<QuicPacketSequenceNumber>::const_iterator it = 263 for (hash_set<QuicPacketSequenceNumber>::const_iterator it =
267 incoming_ack.sent_info.non_retransmiting.begin(); 264 incoming_ack.sent_info.non_retransmiting.begin();
268 while (it != incoming_ack.sent_info.non_retransmiting.end()) { 265 it != incoming_ack.sent_info.non_retransmiting.end(); ++it) {
269 outgoing_ack_.received_info.missing_packets.erase(*it); 266 DVLOG(1) << "no longer expecting " << *it;
270 DVLOG(1) << "no longer expecting " << *it; 267 outgoing_ack_.received_info.missing_packets.erase(*it);
271 ++it;
272 } 268 }
273 269
274 // Make sure we also don't expect any packets lower than the peer's 270 // Make sure we also don't expect any packets lower than the peer's
275 // last-packet-awaiting-ack 271 // last-packet-awaiting-ack
276 if (incoming_ack.sent_info.least_unacked > 272 if (incoming_ack.sent_info.least_unacked >
277 largest_seen_least_packet_awaiting_ack_) { 273 largest_seen_least_packet_awaiting_ack_) {
278 for (QuicPacketSequenceNumber i = largest_seen_least_packet_awaiting_ack_; 274 for (QuicPacketSequenceNumber i = largest_seen_least_packet_awaiting_ack_;
279 i < incoming_ack.sent_info.least_unacked; 275 i < incoming_ack.sent_info.least_unacked; ++i) {
280 ++i) {
281 outgoing_ack_.received_info.missing_packets.erase(i); 276 outgoing_ack_.received_info.missing_packets.erase(i);
282 } 277 }
283 largest_seen_least_packet_awaiting_ack_ = 278 largest_seen_least_packet_awaiting_ack_ =
284 incoming_ack.sent_info.least_unacked; 279 incoming_ack.sent_info.least_unacked;
285 } 280 }
286 281
287 // Possibly close any FecGroups which are now irrelevant 282 // Possibly close any FecGroups which are now irrelevant
288 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1); 283 CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1);
289 } 284 }
290 285
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 QuicStreamId id, 336 QuicStreamId id,
342 StringPiece data, 337 StringPiece data,
343 QuicStreamOffset offset, 338 QuicStreamOffset offset,
344 bool fin, 339 bool fin,
345 QuicPacketSequenceNumber* last_packet) { 340 QuicPacketSequenceNumber* last_packet) {
346 vector<PacketPair> packets; 341 vector<PacketPair> packets;
347 packet_creator_.DataToStream(id, data, offset, fin, &packets); 342 packet_creator_.DataToStream(id, data, offset, fin, &packets);
348 DCHECK_LT(0u, packets.size()); 343 DCHECK_LT(0u, packets.size());
349 344
350 for (size_t i = 0; i < packets.size(); ++i) { 345 for (size_t i = 0; i < packets.size(); ++i) {
351 SendPacket(packets[i].first, packets[i].second, true, false); 346 // Resend is false for FEC packets.
347 SendPacket(packets[i].first,
348 packets[i].second,
349 !packets[i].second->IsFecPacket(),
350 false,
351 false);
352 // TODO(alyssar) either only buffer this up if we send successfully, 352 // TODO(alyssar) either only buffer this up if we send successfully,
353 // and make the upper levels deal with backup, or handle backup here. 353 // and make the upper levels deal with backup, or handle backup here.
354 unacked_packets_.insert(packets[i]); 354 unacked_packets_.insert(packets[i]);
355 } 355 }
356 356
357 if (last_packet != NULL) { 357 if (last_packet != NULL) {
358 *last_packet = packets[packets.size() - 1].first; 358 *last_packet = packets[packets.size() - 1].first;
359 } 359 }
360 return data.size(); 360 return data.size();
361 } 361 }
362 362
363 void QuicConnection::SendRstStream(QuicStreamId id, 363 void QuicConnection::SendRstStream(QuicStreamId id,
364 QuicErrorCode error, 364 QuicErrorCode error,
365 QuicStreamOffset offset) { 365 QuicStreamOffset offset) {
366 PacketPair packetpair = packet_creator_.ResetStream(id, offset, error); 366 PacketPair packetpair = packet_creator_.ResetStream(id, offset, error);
367 367
368 SendPacket(packetpair.first, packetpair.second, true, false); 368 SendPacket(packetpair.first, packetpair.second, true, false, false);
369 unacked_packets_.insert(packetpair); 369 unacked_packets_.insert(packetpair);
370 } 370 }
371 371
372 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, 372 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
373 const IPEndPoint& peer_address, 373 const IPEndPoint& peer_address,
374 const QuicEncryptedPacket& packet) { 374 const QuicEncryptedPacket& packet) {
375 last_packet_revived_ = false; 375 last_packet_revived_ = false;
376 last_size_ = packet.length(); 376 last_size_ = packet.length();
377 framer_.ProcessPacket(self_address, peer_address, packet); 377 framer_.ProcessPacket(self_address, peer_address, packet);
378 378
379 MaybeProcessRevivedPacket(); 379 MaybeProcessRevivedPacket();
380 } 380 }
381 381
382 bool QuicConnection::OnCanWrite() { 382 bool QuicConnection::OnCanWrite() {
383 write_blocked_ = false; 383 write_blocked_ = false;
384 size_t num_queued_packets = queued_packets_.size() + 1; 384 size_t num_queued_packets = queued_packets_.size() + 1;
385 while (!write_blocked_ && !helper_->IsSendAlarmSet() && 385 while (!write_blocked_ && !helper_->IsSendAlarmSet() &&
386 !queued_packets_.empty()) { 386 !queued_packets_.empty()) {
387 // Ensure that from one iteration of this loop to the next we 387 // Ensure that from one iteration of this loop to the next we
388 // succeeded in sending a packet so we don't infinitely loop. 388 // succeeded in sending a packet so we don't infinitely loop.
389 // TODO(rch): clean up and close the connection if we really hit this. 389 // TODO(rch): clean up and close the connection if we really hit this.
390 DCHECK_LT(queued_packets_.size(), num_queued_packets); 390 DCHECK_LT(queued_packets_.size(), num_queued_packets);
391 num_queued_packets = queued_packets_.size(); 391 num_queued_packets = queued_packets_.size();
392 QueuedPacket p = queued_packets_.front(); 392 QueuedPacket p = queued_packets_.front();
393 queued_packets_.pop_front(); 393 queued_packets_.pop_front();
394 SendPacket(p.sequence_number, p.packet, p.resend, false); 394 SendPacket(p.sequence_number, p.packet, p.resend, false, p.retransmit);
395 } 395 }
396 return !write_blocked_; 396 return !write_blocked_;
397 } 397 }
398 398
399 void QuicConnection::AckPacket(const QuicPacketHeader& header) { 399 void QuicConnection::AckPacket(const QuicPacketHeader& header) {
400 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number; 400 QuicPacketSequenceNumber sequence_number = header.packet_sequence_number;
401 if (sequence_number > outgoing_ack_.received_info.largest_received) { 401 if (sequence_number > outgoing_ack_.received_info.largest_received) {
402 // We've got a new high sequence number. Note any new intermediate missing 402 // We've got a new high sequence number. Note any new intermediate missing
403 // packets, and update the last_ack data. 403 // packets, and update the last_ack data.
404 for (QuicPacketSequenceNumber i = 404 for (QuicPacketSequenceNumber i =
(...skipping 15 matching lines...) Expand all
420 SendAck(); 420 SendAck();
421 } 421 }
422 } 422 }
423 423
424 void QuicConnection::MaybeResendPacket( 424 void QuicConnection::MaybeResendPacket(
425 QuicPacketSequenceNumber sequence_number) { 425 QuicPacketSequenceNumber sequence_number) {
426 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 426 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
427 427
428 if (it != unacked_packets_.end()) { 428 if (it != unacked_packets_.end()) {
429 DVLOG(1) << "Resending unacked packet " << sequence_number; 429 DVLOG(1) << "Resending unacked packet " << sequence_number;
430 framer_.IncrementRetransmitCount(it->second); 430 QuicPacket* packet = it->second;
431 SendPacket(sequence_number, it->second, true, false); 431 unacked_packets_.erase(it);
432 // Re-frame the packet with a new sequence number for resend.
433 QuicPacketSequenceNumber new_sequence_number =
434 packet_creator_.SetNewSequenceNumber(packet);
435 // Clear the FEC group.
436 framer_.WriteFecGroup(0u, packet);
437 unacked_packets_[new_sequence_number] = packet;
438 SendPacket(new_sequence_number, packet, true, false, true);
432 } else { 439 } else {
433 DVLOG(2) << "alarm fired for " << sequence_number 440 DVLOG(2) << "alarm fired for " << sequence_number
434 << " but it has been acked"; 441 << " but it has been acked";
435 } 442 }
436 } 443 }
437 444
438 bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number, 445 bool QuicConnection::SendPacket(QuicPacketSequenceNumber sequence_number,
439 QuicPacket* packet, 446 QuicPacket* packet,
440 bool resend, 447 bool should_resend,
441 bool force) { 448 bool force,
449 bool is_retransmit) {
442 // If this packet is being forced, don't bother checking to see if we should 450 // If this packet is being forced, don't bother checking to see if we should
443 // write, just write. 451 // write, just write.
444 if (!force) { 452 if (!force) {
445 // If we can't write, then simply queue the packet. 453 // If we can't write, then simply queue the packet.
446 if (write_blocked_ || helper_->IsSendAlarmSet()) { 454 if (write_blocked_ || helper_->IsSendAlarmSet()) {
447 queued_packets_.push_back(QueuedPacket(sequence_number, packet, resend)); 455 queued_packets_.push_back(
456 QueuedPacket(sequence_number, packet, should_resend, is_retransmit));
448 return false; 457 return false;
449 } 458 }
450 459
451 int delay = scheduler_->TimeUntilSend(resend); 460 int delay = scheduler_->TimeUntilSend(should_resend);
452 // If the scheduler requires a delay, then we can not send this packet now. 461 // If the scheduler requires a delay, then we can not send this packet now.
453 if (delay > 0) { 462 if (delay > 0) {
454 helper_->SetSendAlarm(delay); 463 helper_->SetSendAlarm(delay);
455 queued_packets_.push_back(QueuedPacket(sequence_number, packet, resend)); 464 queued_packets_.push_back(
465 QueuedPacket(sequence_number, packet, should_resend, is_retransmit));
456 return false; 466 return false;
457 } 467 }
458 } 468 }
459 if (resend) { 469 if (should_resend) {
460 helper_->SetResendAlarm(sequence_number, kDefaultResendTimeMs * 1000); 470 helper_->SetResendAlarm(sequence_number, kDefaultResendTimeMs * 1000);
461 // The second case should never happen in the real world, but does here 471 // The second case should never happen in the real world, but does here
462 // because we sometimes send out of order to validate corner cases. 472 // because we sometimes send out of order to validate corner cases.
463 if (outgoing_ack_.sent_info.least_unacked == 0 || 473 if (outgoing_ack_.sent_info.least_unacked == 0 ||
464 sequence_number < outgoing_ack_.sent_info.least_unacked) { 474 sequence_number < outgoing_ack_.sent_info.least_unacked) {
465 outgoing_ack_.sent_info.least_unacked = sequence_number; 475 outgoing_ack_.sent_info.least_unacked = sequence_number;
466 } 476 }
467 } else { 477 } else {
468 if (outgoing_ack_.sent_info.least_unacked!= 0 && 478 if (outgoing_ack_.sent_info.least_unacked!= 0 &&
469 sequence_number > outgoing_ack_.sent_info.least_unacked) { 479 sequence_number > outgoing_ack_.sent_info.least_unacked) {
470 outgoing_ack_.sent_info.non_retransmiting.insert(sequence_number); 480 outgoing_ack_.sent_info.non_retransmiting.insert(sequence_number);
471 } 481 }
472 } 482 }
473 483
474 // Just before we send the packet to the wire, update the transmission time. 484 // Just before we send the packet to the wire, update the transmission time.
475 framer_.WriteTransmissionTime(clock_->NowInUsec(), packet); 485 framer_.WriteTransmissionTime(clock_->NowInUsec(), packet);
476 486
477 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet)); 487 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(*packet));
478 int error; 488 int error;
479 int rv = helper_->WritePacketToWire(sequence_number, *encrypted, resend, 489 int rv = helper_->WritePacketToWire(sequence_number, *encrypted,
480 &error); 490 should_resend, &error);
491 DLOG(INFO) << "Sending packet : "
492 << (should_resend ? "data bearing " : " ack only ")
493 << "packet " << sequence_number;
481 if (rv == -1) { 494 if (rv == -1) {
482 if (error == ERR_IO_PENDING) { 495 if (error == ERR_IO_PENDING) {
483 write_blocked_ = true; 496 write_blocked_ = true;
484 queued_packets_.push_front(QueuedPacket(sequence_number, packet, resend)); 497 queued_packets_.push_front(
498 QueuedPacket(sequence_number, packet, should_resend, is_retransmit));
485 return false; 499 return false;
486 } 500 }
487 } 501 }
488 502
489 time_of_last_packet_us_ = clock_->NowInUsec(); 503 time_of_last_packet_us_ = clock_->NowInUsec();
490 DVLOG(1) << "last packet: " << time_of_last_packet_us_; 504 DVLOG(1) << "last packet: " << time_of_last_packet_us_;
491 505
492 scheduler_->SentPacket(sequence_number, packet->length(), 506 scheduler_->SentPacket(sequence_number, packet->length(), is_retransmit);
493 framer_.GetRetransmitCount(packet) != 0); 507 if (!should_resend) delete packet;
494 if (!resend) delete packet;
495 return true; 508 return true;
496 } 509 }
497 510
498 bool QuicConnection::ShouldSimulateLostPacket() { 511 bool QuicConnection::ShouldSimulateLostPacket() {
499 // TODO(rch): enable this 512 // TODO(rch): enable this
500 return false; 513 return false;
501 /* 514 /*
502 return FLAGS_fake_packet_loss_percentage > 0 && 515 return FLAGS_fake_packet_loss_percentage > 0 &&
503 random_->Rand32() % 100 < FLAGS_fake_packet_loss_percentage; 516 random_->Rand32() % 100 < FLAGS_fake_packet_loss_percentage;
504 */ 517 */
505 } 518 }
506 519
507 void QuicConnection::SendAck() { 520 void QuicConnection::SendAck() {
508 if (!collector_->GenerateCongestionInfo(&outgoing_ack_.congestion_info)) { 521 if (!collector_->GenerateCongestionInfo(&outgoing_ack_.congestion_info)) {
509 outgoing_ack_.congestion_info.type = kNone; 522 outgoing_ack_.congestion_info.type = kNone;
510 } 523 }
511 DVLOG(1) << "Sending ack " << outgoing_ack_; 524 DVLOG(1) << "Sending ack " << outgoing_ack_;
512 525
513 PacketPair packetpair = packet_creator_.AckPacket(&outgoing_ack_); 526 PacketPair packetpair = packet_creator_.AckPacket(&outgoing_ack_);
514 SendPacket(packetpair.first, packetpair.second, false, false); 527 SendPacket(packetpair.first, packetpair.second, false, false, false);
515 } 528 }
516 529
517 void QuicConnection::MaybeProcessRevivedPacket() { 530 void QuicConnection::MaybeProcessRevivedPacket() {
518 QuicFecGroup* group = GetFecGroup(); 531 QuicFecGroup* group = GetFecGroup();
519 if (group == NULL || !group->CanRevive()) { 532 if (group == NULL || !group->CanRevive()) {
520 return; 533 return;
521 } 534 }
522 DCHECK(!revived_payload_.get()); 535 DCHECK(!revived_payload_.get());
523 revived_payload_.reset(new char[kMaxPacketSize]); 536 revived_payload_.reset(new char[kMaxPacketSize]);
524 size_t len = group->Revive(&revived_header_, revived_payload_.get(), 537 size_t len = group->Revive(&revived_header_, revived_payload_.get(),
(...skipping 21 matching lines...) Expand all
546 559
547 void QuicConnection::SendConnectionClose(QuicErrorCode error) { 560 void QuicConnection::SendConnectionClose(QuicErrorCode error) {
548 DLOG(INFO) << "Force closing with error " << QuicUtils::ErrorToString(error) 561 DLOG(INFO) << "Force closing with error " << QuicUtils::ErrorToString(error)
549 << " (" << error << ")"; 562 << " (" << error << ")";
550 QuicConnectionCloseFrame frame; 563 QuicConnectionCloseFrame frame;
551 frame.error_code = error; 564 frame.error_code = error;
552 frame.ack_frame = outgoing_ack_; 565 frame.ack_frame = outgoing_ack_;
553 566
554 PacketPair packetpair = packet_creator_.CloseConnection(&frame); 567 PacketPair packetpair = packet_creator_.CloseConnection(&frame);
555 // There's no point in resending this: we're closing the connection. 568 // There's no point in resending this: we're closing the connection.
556 SendPacket(packetpair.first, packetpair.second, false, true); 569 SendPacket(packetpair.first, packetpair.second, false, true, false);
557 connected_ = false; 570 connected_ = false;
558 visitor_->ConnectionClose(error, false); 571 visitor_->ConnectionClose(error, false);
559 } 572 }
560 573
561 void QuicConnection::CloseFecGroupsBefore( 574 void QuicConnection::CloseFecGroupsBefore(
562 QuicPacketSequenceNumber sequence_number) { 575 QuicPacketSequenceNumber sequence_number) {
563 FecGroupMap::iterator it = group_map_.begin(); 576 FecGroupMap::iterator it = group_map_.begin();
564 while (it != group_map_.end()) { 577 while (it != group_map_.end()) {
565 // If this is the current group or the group doesn't protect this packet 578 // If this is the current group or the group doesn't protect this packet
566 // we can ignore it. 579 // we can ignore it.
(...skipping 20 matching lines...) Expand all
587 << " delta:" << delta_in_us; 600 << " delta:" << delta_in_us;
588 if (delta_in_us >= timeout_us_) { 601 if (delta_in_us >= timeout_us_) {
589 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT); 602 SendConnectionClose(QUIC_CONNECTION_TIMED_OUT);
590 return true; 603 return true;
591 } 604 }
592 helper_->SetTimeoutAlarm(timeout_us_ - delta_in_us); 605 helper_->SetTimeoutAlarm(timeout_us_ - delta_in_us);
593 return false; 606 return false;
594 } 607 }
595 608
596 } // namespace net 609 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_helper_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698