• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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