1 /* 2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef TEST_NETWORK_CROSS_TRAFFIC_H_ 12 #define TEST_NETWORK_CROSS_TRAFFIC_H_ 13 14 #include <algorithm> 15 #include <map> 16 #include <memory> 17 18 #include "api/units/data_rate.h" 19 #include "api/units/data_size.h" 20 #include "api/units/time_delta.h" 21 #include "api/units/timestamp.h" 22 #include "rtc_base/random.h" 23 #include "rtc_base/synchronization/sequence_checker.h" 24 #include "test/network/traffic_route.h" 25 #include "test/scenario/column_printer.h" 26 27 namespace webrtc { 28 namespace test { 29 30 struct RandomWalkConfig { 31 int random_seed = 1; 32 DataRate peak_rate = DataRate::KilobitsPerSec(100); 33 DataSize min_packet_size = DataSize::Bytes(200); 34 TimeDelta min_packet_interval = TimeDelta::Millis(1); 35 TimeDelta update_interval = TimeDelta::Millis(200); 36 double variance = 0.6; 37 double bias = -0.1; 38 }; 39 40 class RandomWalkCrossTraffic { 41 public: 42 RandomWalkCrossTraffic(RandomWalkConfig config, TrafficRoute* traffic_route); 43 ~RandomWalkCrossTraffic(); 44 45 void Process(Timestamp at_time); 46 DataRate TrafficRate() const; 47 ColumnPrinter StatsPrinter(); 48 49 private: 50 SequenceChecker sequence_checker_; 51 const RandomWalkConfig config_; 52 TrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_); 53 webrtc::Random random_ RTC_GUARDED_BY(sequence_checker_); 54 55 Timestamp last_process_time_ RTC_GUARDED_BY(sequence_checker_) = 56 Timestamp::MinusInfinity(); 57 Timestamp last_update_time_ RTC_GUARDED_BY(sequence_checker_) = 58 Timestamp::MinusInfinity(); 59 Timestamp last_send_time_ RTC_GUARDED_BY(sequence_checker_) = 60 Timestamp::MinusInfinity(); 61 double intensity_ RTC_GUARDED_BY(sequence_checker_) = 0; 62 DataSize pending_size_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero(); 63 }; 64 65 struct PulsedPeaksConfig { 66 DataRate peak_rate = DataRate::KilobitsPerSec(100); 67 DataSize min_packet_size = DataSize::Bytes(200); 68 TimeDelta min_packet_interval = TimeDelta::Millis(1); 69 TimeDelta send_duration = TimeDelta::Millis(100); 70 TimeDelta hold_duration = TimeDelta::Millis(2000); 71 }; 72 73 class PulsedPeaksCrossTraffic { 74 public: 75 PulsedPeaksCrossTraffic(PulsedPeaksConfig config, 76 TrafficRoute* traffic_route); 77 ~PulsedPeaksCrossTraffic(); 78 79 void Process(Timestamp at_time); 80 DataRate TrafficRate() const; 81 ColumnPrinter StatsPrinter(); 82 83 private: 84 SequenceChecker sequence_checker_; 85 const PulsedPeaksConfig config_; 86 TrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_); 87 88 Timestamp last_update_time_ RTC_GUARDED_BY(sequence_checker_) = 89 Timestamp::MinusInfinity(); 90 Timestamp last_send_time_ RTC_GUARDED_BY(sequence_checker_) = 91 Timestamp::MinusInfinity(); 92 bool sending_ RTC_GUARDED_BY(sequence_checker_) = false; 93 }; 94 95 class TcpMessageRouteImpl final : public TcpMessageRoute { 96 public: 97 TcpMessageRouteImpl(Clock* clock, 98 TaskQueueBase* task_queue, 99 EmulatedRoute* send_route, 100 EmulatedRoute* ret_route); 101 102 // Sends a TCP message of the given |size| over the route, |on_received| is 103 // called when the message has been delivered. Note that the connection 104 // parameters are reset iff there's no currently pending message on the route. 105 void SendMessage(size_t size, std::function<void()> on_received) override; 106 107 private: 108 // Represents a message sent over the route. When all fragments has been 109 // delivered, the message is considered delivered and the handler is 110 // triggered. This only happen once. 111 struct Message { 112 std::function<void()> handler; 113 std::set<int> pending_fragment_ids; 114 }; 115 // Represents a piece of a message that fit into a TCP packet. 116 struct MessageFragment { 117 int fragment_id; 118 size_t size; 119 }; 120 // Represents a packet sent on the wire. 121 struct TcpPacket { 122 int sequence_number; 123 Timestamp send_time = Timestamp::MinusInfinity(); 124 MessageFragment fragment; 125 }; 126 127 void OnRequest(TcpPacket packet_info); 128 void OnResponse(TcpPacket packet_info, Timestamp at_time); 129 void HandleLoss(Timestamp at_time); 130 void SendPackets(Timestamp at_time); 131 void HandlePacketTimeout(int seq_num, Timestamp at_time); 132 133 Clock* const clock_; 134 TaskQueueBase* const task_queue_; 135 FakePacketRoute<TcpPacket> request_route_; 136 FakePacketRoute<TcpPacket> response_route_; 137 138 std::deque<MessageFragment> pending_; 139 std::map<int, TcpPacket> in_flight_; 140 std::list<Message> messages_; 141 142 double cwnd_; 143 double ssthresh_; 144 145 int last_acked_seq_num_ = 0; 146 int next_sequence_number_ = 0; 147 int next_fragment_id_ = 0; 148 Timestamp last_reduction_time_ = Timestamp::MinusInfinity(); 149 TimeDelta last_rtt_ = TimeDelta::Zero(); 150 }; 151 152 struct FakeTcpConfig { 153 DataSize packet_size = DataSize::Bytes(1200); 154 DataSize send_limit = DataSize::PlusInfinity(); 155 TimeDelta process_interval = TimeDelta::Millis(200); 156 TimeDelta packet_timeout = TimeDelta::Seconds(1); 157 }; 158 159 class FakeTcpCrossTraffic 160 : public TwoWayFakeTrafficRoute<int, int>::TrafficHandlerInterface { 161 public: 162 FakeTcpCrossTraffic(Clock* clock, 163 FakeTcpConfig config, 164 EmulatedRoute* send_route, 165 EmulatedRoute* ret_route); 166 void Start(TaskQueueBase* task_queue); 167 void Stop(); 168 void Process(Timestamp at_time); 169 void OnRequest(int sequence_number, Timestamp at_time) override; 170 void OnResponse(int sequence_number, Timestamp at_time) override; 171 172 void HandleLoss(Timestamp at_time); 173 174 void SendPackets(Timestamp at_time); 175 176 private: 177 Clock* const clock_; 178 const FakeTcpConfig conf_; 179 TwoWayFakeTrafficRoute<int, int> route_; 180 181 std::map<int, Timestamp> in_flight_; 182 double cwnd_ = 10; 183 double ssthresh_ = INFINITY; 184 bool ack_received_ = false; 185 int last_acked_seq_num_ = 0; 186 int next_sequence_number_ = 0; 187 Timestamp last_reduction_time_ = Timestamp::MinusInfinity(); 188 TimeDelta last_rtt_ = TimeDelta::Zero(); 189 DataSize total_sent_ = DataSize::Zero(); 190 RepeatingTaskHandle repeating_task_handle_; 191 }; 192 193 } // namespace test 194 } // namespace webrtc 195 196 #endif // TEST_NETWORK_CROSS_TRAFFIC_H_ 197