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 |