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/sequence_checker.h" 19 #include "api/test/network_emulation_manager.h" 20 #include "api/units/data_rate.h" 21 #include "api/units/data_size.h" 22 #include "api/units/time_delta.h" 23 #include "api/units/timestamp.h" 24 #include "rtc_base/random.h" 25 #include "test/network/network_emulation.h" 26 #include "test/scenario/column_printer.h" 27 28 namespace webrtc { 29 namespace test { 30 31 class RandomWalkCrossTraffic final : public CrossTrafficGenerator { 32 public: 33 RandomWalkCrossTraffic(RandomWalkConfig config, 34 CrossTrafficRoute* traffic_route); 35 ~RandomWalkCrossTraffic(); 36 37 void Process(Timestamp at_time) override; 38 TimeDelta GetProcessInterval() const override; 39 DataRate TrafficRate() const; 40 ColumnPrinter StatsPrinter(); 41 42 private: 43 SequenceChecker sequence_checker_; 44 const RandomWalkConfig config_; 45 CrossTrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_); 46 webrtc::Random random_ RTC_GUARDED_BY(sequence_checker_); 47 48 Timestamp last_process_time_ RTC_GUARDED_BY(sequence_checker_) = 49 Timestamp::MinusInfinity(); 50 Timestamp last_update_time_ RTC_GUARDED_BY(sequence_checker_) = 51 Timestamp::MinusInfinity(); 52 Timestamp last_send_time_ RTC_GUARDED_BY(sequence_checker_) = 53 Timestamp::MinusInfinity(); 54 double intensity_ RTC_GUARDED_BY(sequence_checker_) = 0; 55 DataSize pending_size_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero(); 56 }; 57 58 class PulsedPeaksCrossTraffic final : public CrossTrafficGenerator { 59 public: 60 PulsedPeaksCrossTraffic(PulsedPeaksConfig config, 61 CrossTrafficRoute* traffic_route); 62 ~PulsedPeaksCrossTraffic(); 63 64 void Process(Timestamp at_time) override; 65 TimeDelta GetProcessInterval() const override; 66 DataRate TrafficRate() const; 67 ColumnPrinter StatsPrinter(); 68 69 private: 70 SequenceChecker sequence_checker_; 71 const PulsedPeaksConfig config_; 72 CrossTrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_); 73 74 Timestamp last_update_time_ RTC_GUARDED_BY(sequence_checker_) = 75 Timestamp::MinusInfinity(); 76 Timestamp last_send_time_ RTC_GUARDED_BY(sequence_checker_) = 77 Timestamp::MinusInfinity(); 78 bool sending_ RTC_GUARDED_BY(sequence_checker_) = false; 79 }; 80 81 class TcpMessageRouteImpl final : public TcpMessageRoute { 82 public: 83 TcpMessageRouteImpl(Clock* clock, 84 TaskQueueBase* task_queue, 85 EmulatedRoute* send_route, 86 EmulatedRoute* ret_route); 87 88 // Sends a TCP message of the given `size` over the route, `on_received` is 89 // called when the message has been delivered. Note that the connection 90 // parameters are reset iff there's no currently pending message on the route. 91 void SendMessage(size_t size, std::function<void()> on_received) override; 92 93 private: 94 // Represents a message sent over the route. When all fragments has been 95 // delivered, the message is considered delivered and the handler is 96 // triggered. This only happen once. 97 struct Message { 98 std::function<void()> handler; 99 std::set<int> pending_fragment_ids; 100 }; 101 // Represents a piece of a message that fit into a TCP packet. 102 struct MessageFragment { 103 int fragment_id; 104 size_t size; 105 }; 106 // Represents a packet sent on the wire. 107 struct TcpPacket { 108 int sequence_number; 109 Timestamp send_time = Timestamp::MinusInfinity(); 110 MessageFragment fragment; 111 }; 112 113 void OnRequest(TcpPacket packet_info); 114 void OnResponse(TcpPacket packet_info, Timestamp at_time); 115 void HandleLoss(Timestamp at_time); 116 void SendPackets(Timestamp at_time); 117 void HandlePacketTimeout(int seq_num, Timestamp at_time); 118 119 Clock* const clock_; 120 TaskQueueBase* const task_queue_; 121 FakePacketRoute<TcpPacket> request_route_; 122 FakePacketRoute<TcpPacket> response_route_; 123 124 std::deque<MessageFragment> pending_; 125 std::map<int, TcpPacket> in_flight_; 126 std::list<Message> messages_; 127 128 double cwnd_; 129 double ssthresh_; 130 131 int last_acked_seq_num_ = 0; 132 int next_sequence_number_ = 0; 133 int next_fragment_id_ = 0; 134 Timestamp last_reduction_time_ = Timestamp::MinusInfinity(); 135 TimeDelta last_rtt_ = TimeDelta::Zero(); 136 }; 137 138 class FakeTcpCrossTraffic 139 : public TwoWayFakeTrafficRoute<int, int>::TrafficHandlerInterface, 140 public CrossTrafficGenerator { 141 public: 142 FakeTcpCrossTraffic(FakeTcpConfig config, 143 EmulatedRoute* send_route, 144 EmulatedRoute* ret_route); 145 146 TimeDelta GetProcessInterval() const override; 147 void Process(Timestamp at_time) override; 148 149 void OnRequest(int sequence_number, Timestamp at_time) override; 150 void OnResponse(int sequence_number, Timestamp at_time) override; 151 152 void HandleLoss(Timestamp at_time); 153 154 void SendPackets(Timestamp at_time); 155 156 private: 157 const FakeTcpConfig conf_; 158 TwoWayFakeTrafficRoute<int, int> route_; 159 160 std::map<int, Timestamp> in_flight_; 161 double cwnd_ = 10; 162 double ssthresh_ = INFINITY; 163 bool ack_received_ = false; 164 int last_acked_seq_num_ = 0; 165 int next_sequence_number_ = 0; 166 Timestamp last_reduction_time_ = Timestamp::MinusInfinity(); 167 TimeDelta last_rtt_ = TimeDelta::Zero(); 168 DataSize total_sent_ = DataSize::Zero(); 169 }; 170 171 } // namespace test 172 } // namespace webrtc 173 174 #endif // TEST_NETWORK_CROSS_TRAFFIC_H_ 175