| OLD | NEW |
| (Empty) |
| 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 // A test only class to enable simulations of send algorithms. | |
| 6 | |
| 7 #ifndef NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_ | |
| 8 #define NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_ | |
| 9 | |
| 10 #include <stddef.h> | |
| 11 | |
| 12 #include <algorithm> | |
| 13 #include <string> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "base/format_macros.h" | |
| 17 #include "base/macros.h" | |
| 18 #include "base/strings/stringprintf.h" | |
| 19 #include "net/quic/congestion_control/send_algorithm_interface.h" | |
| 20 #include "net/quic/quic_protocol.h" | |
| 21 #include "net/quic/quic_time.h" | |
| 22 #include "net/quic/test_tools/mock_clock.h" | |
| 23 #include "net/quic/test_tools/quic_test_utils.h" | |
| 24 | |
| 25 using base::StringPrintf; | |
| 26 | |
| 27 namespace net { | |
| 28 | |
| 29 class SendAlgorithmSimulator { | |
| 30 public: | |
| 31 struct Sender { | |
| 32 Sender(SendAlgorithmInterface* send_algorithm, RttStats* rtt_stats); | |
| 33 Sender(SendAlgorithmInterface* send_algorithm, | |
| 34 RttStats* rtt_stats, | |
| 35 QuicTime::Delta additional_rtt); | |
| 36 | |
| 37 void RecordStats() { | |
| 38 QuicByteCount cwnd = send_algorithm->GetCongestionWindow(); | |
| 39 max_cwnd = std::max(max_cwnd, cwnd); | |
| 40 min_cwnd = std::min(min_cwnd, cwnd); | |
| 41 if (last_cwnd > cwnd) { | |
| 42 max_cwnd_drop = std::max(max_cwnd_drop, last_cwnd - cwnd); | |
| 43 } | |
| 44 last_cwnd = cwnd; | |
| 45 } | |
| 46 | |
| 47 std::string DebugString() { | |
| 48 return StringPrintf("observed goodput(bytes/s):%" PRId64 | |
| 49 " loss rate:%f" | |
| 50 " cwnd:%" PRIu64 " max_cwnd:%" PRIu64 | |
| 51 " min_cwnd:%" PRIu64 " max_cwnd_drop:%" PRIu64, | |
| 52 last_transfer_bandwidth.ToBytesPerSecond(), | |
| 53 last_transfer_loss_rate, | |
| 54 send_algorithm->GetCongestionWindow(), max_cwnd, | |
| 55 min_cwnd, max_cwnd_drop); | |
| 56 } | |
| 57 | |
| 58 SendAlgorithmInterface* send_algorithm; | |
| 59 RttStats* rtt_stats; | |
| 60 QuicTime::Delta additional_rtt; | |
| 61 | |
| 62 // Last packet number the sender sent. | |
| 63 QuicPacketNumber last_sent; | |
| 64 // Last packet number acked. | |
| 65 QuicPacketNumber last_acked; | |
| 66 // packet number to ack up to. | |
| 67 QuicPacketNumber next_acked; | |
| 68 | |
| 69 // Stats collected for understanding the congestion control. | |
| 70 QuicByteCount max_cwnd; | |
| 71 QuicByteCount min_cwnd; | |
| 72 QuicByteCount max_cwnd_drop; | |
| 73 QuicByteCount last_cwnd; | |
| 74 | |
| 75 QuicBandwidth last_transfer_bandwidth; | |
| 76 float last_transfer_loss_rate; | |
| 77 }; | |
| 78 | |
| 79 struct Transfer { | |
| 80 Transfer(Sender* sender, | |
| 81 QuicByteCount num_bytes, | |
| 82 QuicTime start_time, | |
| 83 std::string name); | |
| 84 | |
| 85 Sender* sender; | |
| 86 QuicByteCount num_bytes; | |
| 87 QuicByteCount bytes_acked; | |
| 88 QuicByteCount bytes_lost; | |
| 89 QuicByteCount bytes_in_flight; | |
| 90 QuicTime start_time; | |
| 91 std::string name; | |
| 92 }; | |
| 93 | |
| 94 struct SentPacket { | |
| 95 SentPacket() | |
| 96 : packet_number(0), | |
| 97 send_time(QuicTime::Zero()), | |
| 98 ack_time(QuicTime::Zero()), | |
| 99 lost(false), | |
| 100 transfer(nullptr) {} | |
| 101 SentPacket(QuicPacketNumber packet_number, | |
| 102 QuicTime send_time, | |
| 103 QuicTime ack_time, | |
| 104 bool lost, | |
| 105 Transfer* transfer) | |
| 106 : packet_number(packet_number), | |
| 107 send_time(send_time), | |
| 108 ack_time(ack_time), | |
| 109 lost(lost), | |
| 110 transfer(transfer) {} | |
| 111 | |
| 112 QuicPacketNumber packet_number; | |
| 113 QuicTime send_time; | |
| 114 QuicTime ack_time; | |
| 115 bool lost; | |
| 116 Transfer* transfer; | |
| 117 }; | |
| 118 | |
| 119 // |rtt_stats| should be the same RttStats used by the |send_algorithm|. | |
| 120 SendAlgorithmSimulator(MockClock* clock_, | |
| 121 QuicBandwidth bandwidth, | |
| 122 QuicTime::Delta rtt); | |
| 123 ~SendAlgorithmSimulator(); | |
| 124 | |
| 125 // For local ad-hoc testing. | |
| 126 void set_bandwidth(QuicBandwidth bandwidth) { bandwidth_ = bandwidth; } | |
| 127 | |
| 128 void set_forward_loss_rate(float loss_rate) { | |
| 129 DCHECK_LT(loss_rate, 1.0f); | |
| 130 forward_loss_rate_ = loss_rate; | |
| 131 } | |
| 132 | |
| 133 // For local ad-hoc testing. | |
| 134 void set_reverse_loss_rate(float loss_rate) { | |
| 135 DCHECK_LT(loss_rate, 1.0f); | |
| 136 reverse_loss_rate_ = loss_rate; | |
| 137 } | |
| 138 | |
| 139 // For local ad-hoc testing. | |
| 140 void set_loss_correlation(float loss_correlation) { | |
| 141 DCHECK_LT(loss_correlation, 1.0f); | |
| 142 loss_correlation_ = loss_correlation; | |
| 143 } | |
| 144 | |
| 145 void set_buffer_size(size_t buffer_size_bytes) { | |
| 146 buffer_size_ = buffer_size_bytes; | |
| 147 } | |
| 148 | |
| 149 void set_delayed_ack_timer(QuicTime::Delta delayed_ack_timer) { | |
| 150 delayed_ack_timer_ = delayed_ack_timer; | |
| 151 } | |
| 152 | |
| 153 // Advance the time by |delta| without sending anything. | |
| 154 // For local ad-hoc testing. | |
| 155 void AdvanceTime(QuicTime::Delta delta); | |
| 156 | |
| 157 // Adds a pending sender. The send will run when TransferBytes is called. | |
| 158 // Adding two transfers with the same sender is unsupported. | |
| 159 void AddTransfer(Sender* sender, size_t num_bytes); | |
| 160 | |
| 161 // Adds a pending sending to start at the specified time. | |
| 162 void AddTransfer(Sender* sender, | |
| 163 size_t num_bytes, | |
| 164 QuicTime start_time, | |
| 165 std::string name); | |
| 166 | |
| 167 // Convenience method to transfer all bytes. | |
| 168 void TransferBytes(); | |
| 169 | |
| 170 // Transfers bytes through the connection until |max_bytes| are reached, | |
| 171 // |max_time| is reached, or all senders have finished sending. If max_bytes | |
| 172 // is 0, it does not apply, and if |max_time| is Zero, no time limit applies. | |
| 173 void TransferBytes(QuicByteCount max_bytes, QuicTime::Delta max_time); | |
| 174 | |
| 175 private: | |
| 176 // A pending packet event, either a send or an ack. | |
| 177 struct PacketEvent { | |
| 178 PacketEvent(QuicTime::Delta time_delta, Transfer* transfer) | |
| 179 : time_delta(time_delta), transfer(transfer) {} | |
| 180 | |
| 181 QuicTime::Delta time_delta; | |
| 182 Transfer* transfer; | |
| 183 }; | |
| 184 | |
| 185 // NextSendTime returns the next time any of the pending transfers send, | |
| 186 // and populates transfer if the send time is not infinite. | |
| 187 PacketEvent NextSendEvent(); | |
| 188 | |
| 189 // NextAckTime takes into account packet loss in both forward and reverse | |
| 190 // direction, as well as delayed ack behavior. | |
| 191 PacketEvent NextAckEvent(); | |
| 192 | |
| 193 // Sets the next acked. | |
| 194 QuicTime::Delta FindNextAcked(Transfer* transfer); | |
| 195 | |
| 196 // Sets the |next_acked| packet for the |transfer| starting at the specified | |
| 197 // |last_acked|. Returns QuicTime::Delta::Infinite and doesn't set | |
| 198 // |next_acked| if there is no ack after |last_acked|. | |
| 199 QuicTime::Delta FindNextAck(const Transfer* transfer, | |
| 200 QuicPacketNumber last_acked, | |
| 201 QuicPacketNumber* next_acked) const; | |
| 202 | |
| 203 // Returns true if any of the packets |transfer| is waiting for less than | |
| 204 // next_acked have been lost. | |
| 205 bool HasRecentLostPackets(const Transfer* transfer, | |
| 206 QuicPacketNumber next_acked) const; | |
| 207 | |
| 208 // Process all the acks that should have arrived by the current time, and | |
| 209 // lose any packets that are missing. Returns the number of bytes acked. | |
| 210 void HandlePendingAck(Transfer* transfer); | |
| 211 | |
| 212 void SendDataNow(Transfer* transfer); | |
| 213 | |
| 214 // List of all pending transfers waiting to use the connection. | |
| 215 std::vector<Transfer> pending_transfers_; | |
| 216 | |
| 217 MockClock* clock_; | |
| 218 // Whether the next ack should be lost. | |
| 219 bool lose_next_ack_; | |
| 220 // The times acks are expected, assuming acks are not lost and every packet | |
| 221 // is acked. | |
| 222 std::list<SentPacket> sent_packets_; | |
| 223 | |
| 224 test::SimpleRandom simple_random_; | |
| 225 float forward_loss_rate_; // Loss rate on the forward path. | |
| 226 float reverse_loss_rate_; // Loss rate on the reverse path. | |
| 227 float loss_correlation_; // Likelihood the subsequent packet is lost. | |
| 228 QuicBandwidth bandwidth_; | |
| 229 QuicTime::Delta rtt_; | |
| 230 size_t buffer_size_; // In bytes. | |
| 231 QuicTime::Delta delayed_ack_timer_; | |
| 232 | |
| 233 DISALLOW_COPY_AND_ASSIGN(SendAlgorithmSimulator); | |
| 234 }; | |
| 235 | |
| 236 } // namespace net | |
| 237 | |
| 238 #endif // NET_QUIC_CONGESTION_CONTROL_SEND_ALGORITHM_SIMULATOR_H_ | |
| OLD | NEW |