xref: /aosp_15_r20/external/webrtc/test/network/cross_traffic.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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