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