Home | History | Annotate | Download | only in congestion_control
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/congestion_control/send_algorithm_simulator.h"
      6 
      7 #include <limits>
      8 
      9 #include "base/logging.h"
     10 #include "base/rand_util.h"
     11 #include "net/quic/crypto/quic_random.h"
     12 
     13 using std::list;
     14 using std::make_pair;
     15 using std::max;
     16 using std::min;
     17 using std::vector;
     18 
     19 namespace net {
     20 
     21 namespace {
     22 
     23 const QuicByteCount kPacketSize = 1200;
     24 
     25 }  // namespace
     26 
     27 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm,
     28                                        RttStats* rtt_stats)
     29     : send_algorithm(send_algorithm),
     30       rtt_stats(rtt_stats),
     31       last_sent(0),
     32       last_acked(0),
     33       next_acked(1),
     34       max_cwnd(0),
     35       min_cwnd(100000),
     36       max_cwnd_drop(0),
     37       last_cwnd(0),
     38       last_transfer_bandwidth(QuicBandwidth::Zero()),
     39       last_transfer_loss_rate(0) {}
     40 
     41 SendAlgorithmSimulator::SendAlgorithmSimulator(
     42     MockClock* clock,
     43     QuicBandwidth bandwidth,
     44     QuicTime::Delta rtt)
     45     : clock_(clock),
     46       lose_next_ack_(false),
     47       forward_loss_rate_(0),
     48       reverse_loss_rate_(0),
     49       loss_correlation_(0),
     50       bandwidth_(bandwidth),
     51       rtt_(rtt),
     52       buffer_size_(1000000),
     53       delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
     54   uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
     55   DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
     56   simple_random_.set_seed(seed);
     57 }
     58 
     59 SendAlgorithmSimulator::~SendAlgorithmSimulator() {}
     60 
     61 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
     62   AddTransfer(sender, num_bytes, clock_->Now());
     63 }
     64 
     65 void SendAlgorithmSimulator::AddTransfer(
     66     Sender* sender, size_t num_bytes, QuicTime start_time) {
     67   pending_transfers_.push_back(Transfer(sender, num_bytes, start_time));
     68   // Record initial stats from when the transfer begins.
     69   pending_transfers_.back().sender->RecordStats();
     70 }
     71 
     72 void SendAlgorithmSimulator::TransferBytes() {
     73   TransferBytes(kuint64max, QuicTime::Delta::Infinite());
     74 }
     75 
     76 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
     77                                            QuicTime::Delta max_time) {
     78   const QuicTime end_time = max_time.IsInfinite() ?
     79       QuicTime::Zero().Add(QuicTime::Delta::Infinite()) :
     80       clock_->Now().Add(max_time);
     81   QuicByteCount bytes_sent = 0;
     82   while (!pending_transfers_.empty() &&
     83          clock_->Now() < end_time &&
     84          bytes_sent < max_bytes) {
     85     // Determine the times of next send and of the next ack arrival.
     86     PacketEvent send_event = NextSendEvent();
     87     PacketEvent ack_event = NextAckEvent();
     88     // If both times are infinite, fire a TLP.
     89     if (ack_event.time_delta.IsInfinite() &&
     90         send_event.time_delta.IsInfinite()) {
     91       DVLOG(1) << "Both times are infinite, simulating a TLP.";
     92       // TODO(ianswett): Use a more sophisticated TLP timer or never lose
     93       // the last ack?
     94       clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
     95       SendDataNow(&pending_transfers_.front());
     96     } else if (ack_event.time_delta < send_event.time_delta) {
     97       DVLOG(1) << "Handling ack of largest observed:"
     98                << ack_event.transfer->sender->next_acked << ", advancing time:"
     99                << ack_event.time_delta.ToMicroseconds() << "us";
    100       // Ack data all the data up to ack time and lose any missing sequence
    101       // numbers.
    102       clock_->AdvanceTime(ack_event.time_delta);
    103       HandlePendingAck(ack_event.transfer);
    104     } else {
    105       DVLOG(1) << "Sending, advancing time:"
    106                << send_event.time_delta.ToMicroseconds() << "us";
    107       clock_->AdvanceTime(send_event.time_delta);
    108       SendDataNow(send_event.transfer);
    109       bytes_sent += kPacketSize;
    110     }
    111   }
    112 }
    113 
    114 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
    115   QuicTime::Delta next_send_time = QuicTime::Delta::Infinite();
    116   Transfer* transfer = NULL;
    117   for (vector<Transfer>::iterator it = pending_transfers_.begin();
    118        it != pending_transfers_.end(); ++it) {
    119     // If we've already sent enough bytes, wait for them to be acked.
    120     if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) {
    121       continue;
    122     }
    123     // If the flow hasn't started, use the start time.
    124     QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now());
    125     if (clock_->Now() >= it->start_time) {
    126       transfer_send_time =
    127           it->sender->send_algorithm->TimeUntilSend(
    128               clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
    129     }
    130     if (transfer_send_time < next_send_time) {
    131       next_send_time = transfer_send_time;
    132       transfer = &(*it);
    133     }
    134   }
    135   DVLOG(1) << "NextSendTime returning delta(ms):"
    136            << next_send_time.ToMilliseconds();
    137   return PacketEvent(next_send_time, transfer);
    138 }
    139 
    140 // NextAck takes into account packet loss in both forward and reverse
    141 // direction, as well as correlated losses.  And it assumes the receiver acks
    142 // every other packet when there is no loss.
    143 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() {
    144   if (sent_packets_.empty()) {
    145     DVLOG(1) << "No outstanding packets to ack for any transfer.";
    146     return PacketEvent(QuicTime::Delta::Infinite(), NULL);
    147   }
    148 
    149   // For each connection, find the next acked packet.
    150   QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
    151   Transfer* transfer = NULL;
    152   for (vector<Transfer>::iterator it = pending_transfers_.begin();
    153        it != pending_transfers_.end(); ++it) {
    154     QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it));
    155     if (transfer_ack_time < ack_time) {
    156       ack_time = transfer_ack_time;
    157       transfer = &(*it);
    158     }
    159   }
    160 
    161   return PacketEvent(ack_time, transfer);
    162 }
    163 
    164 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
    165   Sender* sender = transfer->sender;
    166   if (sender->next_acked == sender->last_acked) {
    167     // Determine if the next ack is lost only once, to ensure determinism.
    168     lose_next_ack_ =
    169         reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
    170   }
    171 
    172   QuicPacketSequenceNumber next_acked = sender->last_acked;
    173   QuicTime::Delta next_ack_delay =
    174       FindNextAck(transfer, sender->last_acked, &next_acked);
    175   if (lose_next_ack_) {
    176     next_ack_delay = FindNextAck(transfer, next_acked, &next_acked);
    177   }
    178   sender->next_acked = next_acked;
    179   return next_ack_delay;
    180 }
    181 
    182 QuicTime::Delta SendAlgorithmSimulator::FindNextAck(
    183     const Transfer* transfer,
    184     QuicPacketSequenceNumber last_acked,
    185     QuicPacketSequenceNumber* next_acked) const {
    186   *next_acked = last_acked;
    187   QuicTime::Delta ack_delay = QuicTime::Delta::Infinite();
    188   // Remove any packets that are simulated as lost.
    189   for (list<SentPacket>::const_iterator it = sent_packets_.begin();
    190        it != sent_packets_.end(); ++it) {
    191     if (transfer != it->transfer) {
    192       continue;
    193     }
    194     // Skip over any packets less than or equal to last_acked.
    195     if (it->sequence_number <= last_acked) {
    196       continue;
    197     }
    198     // Lost packets don't trigger an ack.
    199     if (it->lost) {
    200       continue;
    201     }
    202     DCHECK_LT(*next_acked, it->sequence_number);
    203     // Consider a delayed ack for the current next_acked.
    204     if (ack_delay < it->ack_time.Subtract(clock_->Now())) {
    205       break;
    206     }
    207     *next_acked = it->sequence_number;
    208     ack_delay = it->ack_time.Subtract(clock_->Now());
    209     if (HasRecentLostPackets(transfer, *next_acked) ||
    210         (*next_acked - last_acked) >= 2) {
    211       break;
    212     }
    213     ack_delay = ack_delay.Add(delayed_ack_timer_);
    214   }
    215 
    216   DVLOG(1) << "FindNextAcked found next_acked_:"
    217            << transfer->sender->next_acked
    218            << " last_acked:" << transfer->sender->last_acked
    219            << " ack_delay(ms):" << ack_delay.ToMilliseconds();
    220   return ack_delay;
    221 }
    222 
    223 bool SendAlgorithmSimulator::HasRecentLostPackets(
    224     const Transfer* transfer, QuicPacketSequenceNumber next_acked) const {
    225   QuicPacketSequenceNumber last_packet = transfer->sender->last_acked;
    226   for (list<SentPacket>::const_iterator it = sent_packets_.begin();
    227        it != sent_packets_.end() && it->sequence_number < next_acked; ++it) {
    228     if (transfer != it->transfer) {
    229       continue;
    230     }
    231     // Lost packets don't trigger an ack.
    232     if (it->lost) {
    233       return true;
    234     }
    235     // Buffer dropped packets are skipped automatically, but still end up
    236     // being lost and cause acks to be sent immediately.
    237     if (it->sequence_number > last_packet + 1) {
    238       return true;
    239     }
    240     last_packet = it->sequence_number;
    241   }
    242   return false;
    243 }
    244 
    245 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
    246   Sender* sender  = transfer->sender;
    247   DCHECK_LT(sender->last_acked, sender->next_acked);
    248   SendAlgorithmInterface::CongestionVector acked_packets;
    249   SendAlgorithmInterface::CongestionVector lost_packets;
    250   DVLOG(1) << "Acking packets from:" << sender->last_acked
    251              << " to " << sender->next_acked
    252              << " bytes_in_flight:" << transfer->bytes_in_flight
    253              << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
    254   // Some entries may be missing from the sent_packets_ array, if they were
    255   // dropped due to buffer overruns.
    256   SentPacket largest_observed;
    257   list<SentPacket>::iterator it = sent_packets_.begin();
    258   while (sender->last_acked < sender->next_acked) {
    259     ++sender->last_acked;
    260     TransmissionInfo info = TransmissionInfo();
    261     info.bytes_sent = kPacketSize;
    262     info.in_flight = true;
    263     // Find the next SentPacket for this transfer.
    264     while (it->transfer != transfer) {
    265       DCHECK(it != sent_packets_.end());
    266       ++it;
    267     }
    268     // If it's missing from the array, it's a loss.
    269     if (it->sequence_number > sender->last_acked) {
    270       DVLOG(1) << "Lost packet:" << sender->last_acked
    271                << " dropped by buffer overflow.";
    272       lost_packets.push_back(make_pair(sender->last_acked, info));
    273       continue;
    274     }
    275     if (it->lost) {
    276       lost_packets.push_back(make_pair(sender->last_acked, info));
    277     } else {
    278       acked_packets.push_back(make_pair(sender->last_acked, info));
    279     }
    280     // This packet has been acked or lost, remove it from sent_packets_.
    281     largest_observed = *it;
    282     sent_packets_.erase(it++);
    283   }
    284 
    285   DCHECK(largest_observed.ack_time.IsInitialized());
    286   DVLOG(1) << "Updating RTT from send_time:"
    287            << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
    288            << largest_observed.ack_time.ToDebuggingValue();
    289   QuicTime::Delta measured_rtt =
    290       largest_observed.ack_time.Subtract(largest_observed.send_time);
    291   DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
    292   sender->rtt_stats->UpdateRtt(measured_rtt,
    293                                QuicTime::Delta::Zero(),
    294                                clock_->Now());
    295   sender->send_algorithm->OnCongestionEvent(
    296       true, transfer->bytes_in_flight, acked_packets, lost_packets);
    297   DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
    298             transfer->bytes_in_flight);
    299   transfer->bytes_in_flight -=
    300       kPacketSize * (acked_packets.size() + lost_packets.size());
    301 
    302   sender->RecordStats();
    303   transfer->bytes_acked += acked_packets.size() * kPacketSize;
    304   transfer->bytes_lost += lost_packets.size() * kPacketSize;
    305   if (transfer->bytes_acked >= transfer->num_bytes) {
    306     // Remove completed transfers and record transfer bandwidth.
    307     QuicTime::Delta transfer_time =
    308         clock_->Now().Subtract(transfer->start_time);
    309     sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) /
    310         (transfer->bytes_lost + transfer->bytes_acked);
    311     sender->last_transfer_bandwidth =
    312         QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes,
    313                                              transfer_time);
    314     DCHECK_GE(bandwidth_.ToBitsPerSecond(),
    315               sender->last_transfer_bandwidth.ToBitsPerSecond());
    316     for (vector<Transfer>::iterator it = pending_transfers_.begin();
    317          it != pending_transfers_.end(); ++it) {
    318       if (transfer == &(*it)) {
    319         pending_transfers_.erase(it);
    320         break;
    321       }
    322     }
    323   }
    324 }
    325 
    326 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
    327   Sender* sender  = transfer->sender;
    328   ++sender->last_sent;
    329   DVLOG(1) << "Sending packet:" << sender->last_sent
    330            << " bytes_in_flight:" << transfer->bytes_in_flight
    331            << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
    332   sender->send_algorithm->OnPacketSent(
    333       clock_->Now(), transfer->bytes_in_flight,
    334       sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
    335   // Lose the packet immediately if the buffer is full.
    336   if (sent_packets_.size() * kPacketSize < buffer_size_) {
    337     // TODO(ianswett): This buffer simulation is an approximation.
    338     // An ack time of zero means loss.
    339     bool packet_lost =
    340         forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
    341     // Handle correlated loss.
    342     if (!sent_packets_.empty() && sent_packets_.back().lost &&
    343         loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
    344       packet_lost = true;
    345     }
    346     DVLOG(1) << "losing packet:" << sender->last_sent
    347              << " due to random loss.";
    348 
    349     // If the number of bytes in flight are less than the bdp, there's
    350     // no buffering delay.  Bytes lost from the buffer are not counted.
    351     QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
    352     QuicTime ack_time = clock_->Now().Add(rtt_);
    353     if (kPacketSize > bdp) {
    354       ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
    355     }
    356     QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
    357         sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
    358     ack_time = QuicTime::Max(ack_time, queue_ack_time);
    359     sent_packets_.push_back(SentPacket(
    360         sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer));
    361   } else {
    362     DVLOG(1) << "losing packet:" << sender->last_sent
    363              << " because the buffer was full.";
    364   }
    365   transfer->bytes_in_flight += kPacketSize;
    366 }
    367 
    368 // Advance the time by |delta| without sending anything.
    369 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
    370   clock_->AdvanceTime(delta);
    371 }
    372 
    373 }  // namespace net
    374