blob: 61dc4686619f12190dc74f90ba5f52f40cc16cbb [file] [log] [blame]
Artem Titov40f51152019-01-04 15:45:01 +01001/*
2 * Copyright (c) 2018 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
Artem Titov386802e2019-07-05 10:48:17 +020011#ifndef TEST_NETWORK_NETWORK_EMULATION_H_
12#define TEST_NETWORK_NETWORK_EMULATION_H_
Artem Titov40f51152019-01-04 15:45:01 +010013
14#include <cstdint>
Artem Titov386802e2019-07-05 10:48:17 +020015#include <deque>
Artem Titov37d18482019-01-08 15:41:45 +010016#include <map>
Artem Titov40f51152019-01-04 15:45:01 +010017#include <memory>
18#include <string>
19#include <utility>
20#include <vector>
21
22#include "absl/types/optional.h"
Artem Titov3e0b65d2020-07-23 02:19:02 +020023#include "api/array_view.h"
Artem Titovcbe6e8a2020-09-22 15:45:00 +020024#include "api/numerics/samples_stats_counter.h"
Artem Titovd15a5752021-02-10 14:31:24 +010025#include "api/sequence_checker.h"
Artem Titov806299e2019-04-12 12:17:19 +020026#include "api/test/network_emulation_manager.h"
Artem Titov37d18482019-01-08 15:41:45 +010027#include "api/test/simulated_network.h"
Artem Titov40f51152019-01-04 15:45:01 +010028#include "api/units/timestamp.h"
Steve Anton10542f22019-01-11 09:11:00 -080029#include "rtc_base/copy_on_write_buffer.h"
Artem Titove5cc85b2019-03-28 12:11:09 +010030#include "rtc_base/network.h"
Artem Titov1e023392020-01-23 15:46:45 +010031#include "rtc_base/network_constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/socket_address.h"
Niels Möller376cf382021-02-26 09:24:51 +010033#include "rtc_base/synchronization/mutex.h"
Sebastian Jansson4124dab2019-04-01 14:33:53 +020034#include "rtc_base/task_queue_for_test.h"
35#include "rtc_base/task_utils/repeating_task.h"
Artem Titovcbe6e8a2020-09-22 15:45:00 +020036#include "rtc_base/thread_annotations.h"
Artem Titov0774bd92019-01-30 15:26:05 +010037#include "system_wrappers/include/clock.h"
Artem Titov40f51152019-01-04 15:45:01 +010038
39namespace webrtc {
Artem Titov7bf8c7f2019-03-15 15:00:37 +010040
Artem Titov14b46a72020-07-31 12:57:24 +020041// This class is immutable and so thread safe.
42class EmulatedNetworkOutgoingStatsImpl final
43 : public EmulatedNetworkOutgoingStats {
Artem Titov3e0b65d2020-07-23 02:19:02 +020044 public:
Artem Titovcbe6e8a2020-09-22 15:45:00 +020045 EmulatedNetworkOutgoingStatsImpl(
46 int64_t packets_sent,
47 DataSize bytes_sent,
48 SamplesStatsCounter sent_packets_size_counter,
49 DataSize first_sent_packet_size,
50 Timestamp first_packet_sent_time,
51 Timestamp last_packet_sent_time)
Artem Titov3e0b65d2020-07-23 02:19:02 +020052 : packets_sent_(packets_sent),
53 bytes_sent_(bytes_sent),
Artem Titovcbe6e8a2020-09-22 15:45:00 +020054 sent_packets_size_counter_(std::move(sent_packets_size_counter)),
Artem Titov3e0b65d2020-07-23 02:19:02 +020055 first_sent_packet_size_(first_sent_packet_size),
56 first_packet_sent_time_(first_packet_sent_time),
Artem Titov14b46a72020-07-31 12:57:24 +020057 last_packet_sent_time_(last_packet_sent_time) {}
58 explicit EmulatedNetworkOutgoingStatsImpl(
59 const EmulatedNetworkOutgoingStats& stats)
60 : packets_sent_(stats.PacketsSent()),
61 bytes_sent_(stats.BytesSent()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +020062 sent_packets_size_counter_(stats.SentPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +020063 first_sent_packet_size_(stats.FirstSentPacketSize()),
64 first_packet_sent_time_(stats.FirstPacketSentTime()),
65 last_packet_sent_time_(stats.LastPacketSentTime()) {}
66 ~EmulatedNetworkOutgoingStatsImpl() override = default;
Artem Titov3e0b65d2020-07-23 02:19:02 +020067
68 int64_t PacketsSent() const override { return packets_sent_; }
69
70 DataSize BytesSent() const override { return bytes_sent_; }
71
Artem Titovcbe6e8a2020-09-22 15:45:00 +020072 const SamplesStatsCounter& SentPacketsSizeCounter() const override {
73 return sent_packets_size_counter_;
74 }
75
Artem Titov3e0b65d2020-07-23 02:19:02 +020076 DataSize FirstSentPacketSize() const override {
77 return first_sent_packet_size_;
78 }
79
80 Timestamp FirstPacketSentTime() const override {
81 return first_packet_sent_time_;
82 }
83
84 Timestamp LastPacketSentTime() const override {
85 return last_packet_sent_time_;
86 }
87
Artem Titov14b46a72020-07-31 12:57:24 +020088 DataRate AverageSendRate() const override;
Artem Titov3e0b65d2020-07-23 02:19:02 +020089
90 private:
Artem Titov3e0b65d2020-07-23 02:19:02 +020091 const int64_t packets_sent_;
92 const DataSize bytes_sent_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +020093 const SamplesStatsCounter sent_packets_size_counter_;
Artem Titov3e0b65d2020-07-23 02:19:02 +020094 const DataSize first_sent_packet_size_;
95 const Timestamp first_packet_sent_time_;
96 const Timestamp last_packet_sent_time_;
Artem Titov14b46a72020-07-31 12:57:24 +020097};
Artem Titov3e0b65d2020-07-23 02:19:02 +020098
Artem Titov14b46a72020-07-31 12:57:24 +020099// This class is immutable and so thread safe.
100class EmulatedNetworkIncomingStatsImpl final
101 : public EmulatedNetworkIncomingStats {
102 public:
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200103 EmulatedNetworkIncomingStatsImpl(
104 int64_t packets_received,
105 DataSize bytes_received,
106 SamplesStatsCounter received_packets_size_counter,
107 int64_t packets_dropped,
108 DataSize bytes_dropped,
109 SamplesStatsCounter dropped_packets_size_counter,
110 DataSize first_received_packet_size,
111 Timestamp first_packet_received_time,
112 Timestamp last_packet_received_time)
Artem Titov14b46a72020-07-31 12:57:24 +0200113 : packets_received_(packets_received),
114 bytes_received_(bytes_received),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200115 received_packets_size_counter_(received_packets_size_counter),
Artem Titov14b46a72020-07-31 12:57:24 +0200116 packets_dropped_(packets_dropped),
117 bytes_dropped_(bytes_dropped),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200118 dropped_packets_size_counter_(dropped_packets_size_counter),
Artem Titov14b46a72020-07-31 12:57:24 +0200119 first_received_packet_size_(first_received_packet_size),
120 first_packet_received_time_(first_packet_received_time),
121 last_packet_received_time_(last_packet_received_time) {}
122 explicit EmulatedNetworkIncomingStatsImpl(
123 const EmulatedNetworkIncomingStats& stats)
124 : packets_received_(stats.PacketsReceived()),
125 bytes_received_(stats.BytesReceived()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200126 received_packets_size_counter_(stats.ReceivedPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +0200127 packets_dropped_(stats.PacketsDropped()),
128 bytes_dropped_(stats.BytesDropped()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200129 dropped_packets_size_counter_(stats.DroppedPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +0200130 first_received_packet_size_(stats.FirstReceivedPacketSize()),
131 first_packet_received_time_(stats.FirstPacketReceivedTime()),
132 last_packet_received_time_(stats.LastPacketReceivedTime()) {}
133 ~EmulatedNetworkIncomingStatsImpl() override = default;
134
135 int64_t PacketsReceived() const override { return packets_received_; }
136
137 DataSize BytesReceived() const override { return bytes_received_; }
138
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200139 const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
140 return received_packets_size_counter_;
141 }
142
Artem Titov14b46a72020-07-31 12:57:24 +0200143 int64_t PacketsDropped() const override { return packets_dropped_; }
144
145 DataSize BytesDropped() const override { return bytes_dropped_; }
146
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200147 const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
148 return dropped_packets_size_counter_;
149 }
150
Artem Titov14b46a72020-07-31 12:57:24 +0200151 DataSize FirstReceivedPacketSize() const override {
152 return first_received_packet_size_;
153 }
154
155 Timestamp FirstPacketReceivedTime() const override {
156 return first_packet_received_time_;
157 }
158
159 Timestamp LastPacketReceivedTime() const override {
160 return last_packet_received_time_;
161 }
162
163 DataRate AverageReceiveRate() const override;
164
165 private:
166 const int64_t packets_received_;
167 const DataSize bytes_received_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200168 const SamplesStatsCounter received_packets_size_counter_;
Artem Titov14b46a72020-07-31 12:57:24 +0200169 const int64_t packets_dropped_;
170 const DataSize bytes_dropped_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200171 const SamplesStatsCounter dropped_packets_size_counter_;
Artem Titov14b46a72020-07-31 12:57:24 +0200172 const DataSize first_received_packet_size_;
173 const Timestamp first_packet_received_time_;
174 const Timestamp last_packet_received_time_;
175};
176
177// This class is immutable and so is thread safe.
178class EmulatedNetworkStatsImpl final : public EmulatedNetworkStats {
179 public:
180 EmulatedNetworkStatsImpl(
181 std::vector<rtc::IPAddress> local_addresses,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200182 SamplesStatsCounter sent_packets_queue_wait_time_us,
Artem Titov14b46a72020-07-31 12:57:24 +0200183 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
184 outgoing_stats_per_destination,
185 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
186 incoming_stats_per_source)
187 : local_addresses_(std::move(local_addresses)),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200188 sent_packets_queue_wait_time_us_(sent_packets_queue_wait_time_us),
Artem Titov14b46a72020-07-31 12:57:24 +0200189 outgoing_stats_per_destination_(
190 std::move(outgoing_stats_per_destination)),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200191 incoming_stats_per_source_(std::move(incoming_stats_per_source)),
192 overall_outgoing_stats_(GetOverallOutgoingStats()),
193 overall_incoming_stats_(GetOverallIncomingStats()) {}
Artem Titov14b46a72020-07-31 12:57:24 +0200194 ~EmulatedNetworkStatsImpl() override = default;
195
196 std::vector<rtc::IPAddress> LocalAddresses() const override {
197 return local_addresses_;
198 }
199
200 int64_t PacketsSent() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200201 return overall_outgoing_stats_->PacketsSent();
Artem Titov14b46a72020-07-31 12:57:24 +0200202 }
203
204 DataSize BytesSent() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200205 return overall_outgoing_stats_->BytesSent();
206 }
207
208 const SamplesStatsCounter& SentPacketsSizeCounter() const override {
209 return overall_outgoing_stats_->SentPacketsSizeCounter();
210 }
211
212 const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const override {
213 return sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200214 }
215
216 DataSize FirstSentPacketSize() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200217 return overall_outgoing_stats_->FirstSentPacketSize();
Artem Titov14b46a72020-07-31 12:57:24 +0200218 }
219
220 Timestamp FirstPacketSentTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200221 return overall_outgoing_stats_->FirstPacketSentTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200222 }
223
224 Timestamp LastPacketSentTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200225 return overall_outgoing_stats_->LastPacketSentTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200226 }
227
228 DataRate AverageSendRate() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200229 return overall_outgoing_stats_->AverageSendRate();
Artem Titov14b46a72020-07-31 12:57:24 +0200230 }
231
232 int64_t PacketsReceived() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200233 return overall_incoming_stats_->PacketsReceived();
Artem Titov14b46a72020-07-31 12:57:24 +0200234 }
235
236 DataSize BytesReceived() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200237 return overall_incoming_stats_->BytesReceived();
238 }
239
240 const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
241 return overall_incoming_stats_->ReceivedPacketsSizeCounter();
Artem Titov14b46a72020-07-31 12:57:24 +0200242 }
243
244 int64_t PacketsDropped() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200245 return overall_incoming_stats_->PacketsDropped();
Artem Titov14b46a72020-07-31 12:57:24 +0200246 }
247
248 DataSize BytesDropped() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200249 return overall_incoming_stats_->BytesDropped();
250 }
251
252 const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
253 return overall_incoming_stats_->DroppedPacketsSizeCounter();
Artem Titov14b46a72020-07-31 12:57:24 +0200254 }
255
256 DataSize FirstReceivedPacketSize() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200257 return overall_incoming_stats_->FirstReceivedPacketSize();
Artem Titov14b46a72020-07-31 12:57:24 +0200258 }
259
260 Timestamp FirstPacketReceivedTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200261 return overall_incoming_stats_->FirstPacketReceivedTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200262 }
263
264 Timestamp LastPacketReceivedTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200265 return overall_incoming_stats_->LastPacketReceivedTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200266 }
267
268 DataRate AverageReceiveRate() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200269 return overall_incoming_stats_->AverageReceiveRate();
Artem Titov14b46a72020-07-31 12:57:24 +0200270 }
271
272 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
273 OutgoingStatsPerDestination() const override;
274
275 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
276 IncomingStatsPerSource() const override;
277
278 private:
279 std::unique_ptr<EmulatedNetworkOutgoingStats> GetOverallOutgoingStats() const;
280 std::unique_ptr<EmulatedNetworkIncomingStats> GetOverallIncomingStats() const;
281
282 const std::vector<rtc::IPAddress> local_addresses_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200283 const SamplesStatsCounter sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200284 const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
285 outgoing_stats_per_destination_;
286 const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
Artem Titov3e0b65d2020-07-23 02:19:02 +0200287 incoming_stats_per_source_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200288 const std::unique_ptr<EmulatedNetworkOutgoingStats> overall_outgoing_stats_;
289 const std::unique_ptr<EmulatedNetworkIncomingStats> overall_incoming_stats_;
Artem Titov3e0b65d2020-07-23 02:19:02 +0200290};
291
Artem Titov14b46a72020-07-31 12:57:24 +0200292class EmulatedNetworkOutgoingStatsBuilder {
293 public:
294 EmulatedNetworkOutgoingStatsBuilder();
295
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200296 void OnPacketSent(Timestamp sent_time,
297 DataSize packet_size,
298 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200299
300 void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
301
302 std::unique_ptr<EmulatedNetworkOutgoingStats> Build() const;
303
304 private:
305 SequenceChecker sequence_checker_;
306
307 int64_t packets_sent_ RTC_GUARDED_BY(sequence_checker_) = 0;
308 DataSize bytes_sent_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200309 SamplesStatsCounter sent_packets_size_counter_
310 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200311 DataSize first_sent_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
312 DataSize::Zero();
313 Timestamp first_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
314 Timestamp::PlusInfinity();
315 Timestamp last_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
316 Timestamp::MinusInfinity();
317};
318
319class EmulatedNetworkIncomingStatsBuilder {
320 public:
321 EmulatedNetworkIncomingStatsBuilder();
322
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200323 void OnPacketDropped(DataSize packet_size,
324 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200325
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200326 void OnPacketReceived(Timestamp received_time,
327 DataSize packet_size,
328 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200329
330 // Adds stats collected from another endpoints to the builder.
331 void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
332
333 std::unique_ptr<EmulatedNetworkIncomingStats> Build() const;
334
335 private:
336 SequenceChecker sequence_checker_;
337
338 int64_t packets_received_ RTC_GUARDED_BY(sequence_checker_) = 0;
339 DataSize bytes_received_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200340 SamplesStatsCounter received_packets_size_counter_
341 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200342 int64_t packets_dropped_ RTC_GUARDED_BY(sequence_checker_) = 0;
343 DataSize bytes_dropped_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200344 SamplesStatsCounter dropped_packets_size_counter_
345 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200346 DataSize first_received_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
347 DataSize::Zero();
348 Timestamp first_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
349 Timestamp::PlusInfinity();
350 Timestamp last_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
351 Timestamp::MinusInfinity();
352};
353
Artem Titov3e0b65d2020-07-23 02:19:02 +0200354// All methods of EmulatedNetworkStatsBuilder have to be used on a single
355// thread. It may be created on another thread.
356class EmulatedNetworkStatsBuilder {
357 public:
358 EmulatedNetworkStatsBuilder();
359 explicit EmulatedNetworkStatsBuilder(rtc::IPAddress local_ip);
360
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200361 void OnPacketSent(Timestamp queued_time,
362 Timestamp sent_time,
Artem Titov14b46a72020-07-31 12:57:24 +0200363 rtc::IPAddress destination_ip,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200364 DataSize packet_size,
365 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200366
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200367 void OnPacketDropped(rtc::IPAddress source_ip,
368 DataSize packet_size,
369 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200370
371 void OnPacketReceived(Timestamp received_time,
372 rtc::IPAddress source_ip,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200373 DataSize packet_size,
374 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200375
Artem Titov14b46a72020-07-31 12:57:24 +0200376 void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200377
378 std::unique_ptr<EmulatedNetworkStats> Build() const;
379
380 private:
381 SequenceChecker sequence_checker_;
382
Artem Titov3e0b65d2020-07-23 02:19:02 +0200383 std::vector<rtc::IPAddress> local_addresses_
384 RTC_GUARDED_BY(sequence_checker_);
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200385 SamplesStatsCounter sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200386 std::map<rtc::IPAddress, EmulatedNetworkOutgoingStatsBuilder>
387 outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
388 std::map<rtc::IPAddress, EmulatedNetworkIncomingStatsBuilder>
Artem Titov3e0b65d2020-07-23 02:19:02 +0200389 incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
390};
Artem Titov40f51152019-01-04 15:45:01 +0100391
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200392class LinkEmulation : public EmulatedNetworkReceiverInterface {
393 public:
394 LinkEmulation(Clock* clock,
395 rtc::TaskQueue* task_queue,
396 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
397 EmulatedNetworkReceiverInterface* receiver)
398 : clock_(clock),
399 task_queue_(task_queue),
400 network_behavior_(std::move(network_behavior)),
401 receiver_(receiver) {}
402 void OnPacketReceived(EmulatedIpPacket packet) override;
403
404 private:
405 struct StoredPacket {
406 uint64_t id;
407 EmulatedIpPacket packet;
408 bool removed;
409 };
410 void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200411
412 Clock* const clock_;
413 rtc::TaskQueue* const task_queue_;
414 const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
415 RTC_GUARDED_BY(task_queue_);
416 EmulatedNetworkReceiverInterface* const receiver_;
417 RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
418 std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
419 uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
420};
421
Artem Titov3d37e062021-02-19 20:26:32 +0100422// Represents a component responsible for routing packets based on their IP
423// address. All possible routes have to be set explicitly before packet for
424// desired destination will be seen for the first time. If route is unknown
425// the packet will be silently dropped.
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200426class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
427 public:
428 explicit NetworkRouterNode(rtc::TaskQueue* task_queue);
429
430 void OnPacketReceived(EmulatedIpPacket packet) override;
Yves Gerey2257c082020-01-03 12:37:56 +0100431 void SetReceiver(const rtc::IPAddress& dest_ip,
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200432 EmulatedNetworkReceiverInterface* receiver);
Yves Gerey2257c082020-01-03 12:37:56 +0100433 void RemoveReceiver(const rtc::IPAddress& dest_ip);
Artem Titov3d37e062021-02-19 20:26:32 +0100434 // Sets a default receive that will be used for all incoming packets for which
435 // there is no specific receiver binded to their destination port.
436 void SetDefaultReceiver(EmulatedNetworkReceiverInterface* receiver);
437 void RemoveDefaultReceiver();
Sebastian Jansson71c6b562019-08-14 11:31:02 +0200438 void SetWatcher(std::function<void(const EmulatedIpPacket&)> watcher);
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +0100439 void SetFilter(std::function<bool(const EmulatedIpPacket&)> filter);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200440
441 private:
442 rtc::TaskQueue* const task_queue_;
Artem Titov3d37e062021-02-19 20:26:32 +0100443 absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
444 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200445 std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
446 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson71c6b562019-08-14 11:31:02 +0200447 std::function<void(const EmulatedIpPacket&)> watcher_
448 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +0100449 std::function<bool(const EmulatedIpPacket&)> filter_
450 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200451};
452
Artem Titov37d18482019-01-08 15:41:45 +0100453// Represents node in the emulated network. Nodes can be connected with each
454// other to form different networks with different behavior. The behavior of
455// the node itself is determined by a concrete implementation of
456// NetworkBehaviorInterface that is provided on construction.
457class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
458 public:
Artem Titov1ee563d2021-07-27 12:46:29 +0200459 // Creates node based on `network_behavior`. The specified `packet_overhead`
Artem Titov37d18482019-01-08 15:41:45 +0100460 // is added to the size of each packet in the information provided to
Artem Titov1ee563d2021-07-27 12:46:29 +0200461 // `network_behavior`.
462 // `task_queue` is used to process packets and to forward the packets when
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200463 // they are ready.
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200464 EmulatedNetworkNode(
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200465 Clock* clock,
466 rtc::TaskQueue* task_queue,
Sebastian Jansson8c8feb92019-01-29 15:59:17 +0100467 std::unique_ptr<NetworkBehaviorInterface> network_behavior);
Artem Titov37d18482019-01-08 15:41:45 +0100468 ~EmulatedNetworkNode() override;
Artem Titov6cae2d52022-01-26 15:01:10 +0000469
470 EmulatedNetworkNode(const EmulatedNetworkNode&) = delete;
471 EmulatedNetworkNode& operator=(const EmulatedNetworkNode&) = delete;
Artem Titov37d18482019-01-08 15:41:45 +0100472
473 void OnPacketReceived(EmulatedIpPacket packet) override;
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200474
475 LinkEmulation* link() { return &link_; }
476 NetworkRouterNode* router() { return &router_; }
Artem Titov37d18482019-01-08 15:41:45 +0100477
Artem Titov4cd433e2019-04-01 11:01:16 +0200478 // Creates a route for the given receiver_ip over all the given nodes to the
Artem Titov37d18482019-01-08 15:41:45 +0100479 // given receiver.
Yves Gerey2257c082020-01-03 12:37:56 +0100480 static void CreateRoute(const rtc::IPAddress& receiver_ip,
Artem Titov37d18482019-01-08 15:41:45 +0100481 std::vector<EmulatedNetworkNode*> nodes,
482 EmulatedNetworkReceiverInterface* receiver);
Yves Gerey2257c082020-01-03 12:37:56 +0100483 static void ClearRoute(const rtc::IPAddress& receiver_ip,
Artem Titov37d18482019-01-08 15:41:45 +0100484 std::vector<EmulatedNetworkNode*> nodes);
485
486 private:
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200487 NetworkRouterNode router_;
488 LinkEmulation link_;
Artem Titov37d18482019-01-08 15:41:45 +0100489};
490
Artem Titov0774bd92019-01-30 15:26:05 +0100491// Represents single network interface on the device.
492// It will be used as sender from socket side to send data to the network and
493// will act as packet receiver from emulated network side to receive packets
494// from other EmulatedNetworkNodes.
Sebastian Janssoncec24332019-12-04 14:26:50 +0100495class EmulatedEndpointImpl : public EmulatedEndpoint {
Artem Titov0774bd92019-01-30 15:26:05 +0100496 public:
Artem Titov3d37e062021-02-19 20:26:32 +0100497 struct Options {
498 Options(uint64_t id,
499 const rtc::IPAddress& ip,
500 const EmulatedEndpointConfig& config);
501
502 // TODO(titovartem) check if we can remove id.
503 uint64_t id;
504 // Endpoint local IP address.
505 rtc::IPAddress ip;
506 EmulatedEndpointConfig::StatsGatheringMode stats_gathering_mode;
507 rtc::AdapterType type;
508 // Allow endpoint to send packets specifying source IP address different to
509 // the current endpoint IP address. If false endpoint will crash if attempt
510 // to send such packet will be done.
511 bool allow_send_packet_with_different_source_ip;
512 // Allow endpoint to receive packet with destination IP address different to
513 // the current endpoint IP address. If false endpoint will crash if such
514 // packet will arrive.
515 bool allow_receive_packets_with_different_dest_ip;
516 // Name of the endpoint used for logging purposes.
517 std::string log_name;
518 };
519
520 EmulatedEndpointImpl(const Options& options,
521 bool is_enabled,
522 rtc::TaskQueue* task_queue,
523 Clock* clock);
Sebastian Janssoncec24332019-12-04 14:26:50 +0100524 ~EmulatedEndpointImpl() override;
Artem Titov0774bd92019-01-30 15:26:05 +0100525
526 uint64_t GetId() const;
527
Artem Titovff393122019-04-05 11:19:52 +0200528 NetworkRouterNode* router() { return &router_; }
Sebastian Janssoncec24332019-12-04 14:26:50 +0100529
Artem Titov0774bd92019-01-30 15:26:05 +0100530 void SendPacket(const rtc::SocketAddress& from,
531 const rtc::SocketAddress& to,
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100532 rtc::CopyOnWriteBuffer packet_data,
533 uint16_t application_overhead = 0) override;
Artem Titov0774bd92019-01-30 15:26:05 +0100534
Artem Titov0774bd92019-01-30 15:26:05 +0100535 absl::optional<uint16_t> BindReceiver(
536 uint16_t desired_port,
Sebastian Janssoncec24332019-12-04 14:26:50 +0100537 EmulatedNetworkReceiverInterface* receiver) override;
Niels Möller376cf382021-02-26 09:24:51 +0100538 // Binds a receiver, and automatically removes the binding after first call to
539 // OnPacketReceived.
540 absl::optional<uint16_t> BindOneShotReceiver(
541 uint16_t desired_port,
542 EmulatedNetworkReceiverInterface* receiver);
Sebastian Janssoncec24332019-12-04 14:26:50 +0100543 void UnbindReceiver(uint16_t port) override;
Artem Titov3d37e062021-02-19 20:26:32 +0100544 void BindDefaultReceiver(EmulatedNetworkReceiverInterface* receiver) override;
545 void UnbindDefaultReceiver() override;
Artem Titov0774bd92019-01-30 15:26:05 +0100546
Sebastian Janssoncec24332019-12-04 14:26:50 +0100547 rtc::IPAddress GetPeerLocalAddress() const override;
Artem Titov0774bd92019-01-30 15:26:05 +0100548
549 // Will be called to deliver packet into endpoint from network node.
550 void OnPacketReceived(EmulatedIpPacket packet) override;
551
Artem Titove5cc85b2019-03-28 12:11:09 +0100552 void Enable();
553 void Disable();
554 bool Enabled() const;
555
556 const rtc::Network& network() const { return *network_.get(); }
557
Artem Titov9dcab802020-08-04 11:19:28 +0200558 std::unique_ptr<EmulatedNetworkStats> stats() const;
Artem Titov806299e2019-04-12 12:17:19 +0200559
Artem Titov0774bd92019-01-30 15:26:05 +0100560 private:
Niels Möller376cf382021-02-26 09:24:51 +0100561 struct ReceiverBinding {
562 EmulatedNetworkReceiverInterface* receiver;
563 bool is_one_shot;
564 };
565
566 absl::optional<uint16_t> BindReceiverInternal(
567 uint16_t desired_port,
568 EmulatedNetworkReceiverInterface* receiver,
569 bool is_one_shot);
570
Artem Titov0774bd92019-01-30 15:26:05 +0100571 static constexpr uint16_t kFirstEphemeralPort = 49152;
572 uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
573
Niels Möller376cf382021-02-26 09:24:51 +0100574 Mutex receiver_lock_;
Artem Titovc8421c42021-02-02 10:57:19 +0100575 SequenceChecker enabled_state_checker_;
Artem Titov0774bd92019-01-30 15:26:05 +0100576
Artem Titov3d37e062021-02-19 20:26:32 +0100577 const Options options_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100578 bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
Artem Titov0774bd92019-01-30 15:26:05 +0100579 Clock* const clock_;
Artem Titovff393122019-04-05 11:19:52 +0200580 rtc::TaskQueue* const task_queue_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100581 std::unique_ptr<rtc::Network> network_;
Artem Titovff393122019-04-05 11:19:52 +0200582 NetworkRouterNode router_;
Artem Titov0774bd92019-01-30 15:26:05 +0100583
584 uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
Artem Titov3d37e062021-02-19 20:26:32 +0100585 absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
586 RTC_GUARDED_BY(receiver_lock_);
Niels Möller376cf382021-02-26 09:24:51 +0100587 std::map<uint16_t, ReceiverBinding> port_to_receiver_
Artem Titov0774bd92019-01-30 15:26:05 +0100588 RTC_GUARDED_BY(receiver_lock_);
Artem Titov806299e2019-04-12 12:17:19 +0200589
Artem Titov3e0b65d2020-07-23 02:19:02 +0200590 EmulatedNetworkStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
Artem Titov0774bd92019-01-30 15:26:05 +0100591};
592
Artem Titovfc6ab002019-03-12 13:48:32 +0100593class EmulatedRoute {
594 public:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100595 EmulatedRoute(EmulatedEndpointImpl* from,
Artem Titovfc6ab002019-03-12 13:48:32 +0100596 std::vector<EmulatedNetworkNode*> via_nodes,
Artem Titov3d37e062021-02-19 20:26:32 +0100597 EmulatedEndpointImpl* to,
598 bool is_default)
599 : from(from),
600 via_nodes(std::move(via_nodes)),
601 to(to),
602 active(true),
603 is_default(is_default) {}
Artem Titovfc6ab002019-03-12 13:48:32 +0100604
Sebastian Janssoncec24332019-12-04 14:26:50 +0100605 EmulatedEndpointImpl* from;
Artem Titovfc6ab002019-03-12 13:48:32 +0100606 std::vector<EmulatedNetworkNode*> via_nodes;
Sebastian Janssoncec24332019-12-04 14:26:50 +0100607 EmulatedEndpointImpl* to;
Artem Titovfc6ab002019-03-12 13:48:32 +0100608 bool active;
Artem Titov3d37e062021-02-19 20:26:32 +0100609 bool is_default;
Artem Titovfc6ab002019-03-12 13:48:32 +0100610};
Artem Titovc1a07372020-07-21 09:50:11 +0200611
Artem Titov5501cef2020-08-04 11:49:19 +0200612// This object is immutable and so thread safe.
Artem Titove5cc85b2019-03-28 12:11:09 +0100613class EndpointsContainer {
614 public:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100615 explicit EndpointsContainer(
616 const std::vector<EmulatedEndpointImpl*>& endpoints);
Artem Titove5cc85b2019-03-28 12:11:09 +0100617
Sebastian Janssoncec24332019-12-04 14:26:50 +0100618 EmulatedEndpointImpl* LookupByLocalAddress(
619 const rtc::IPAddress& local_ip) const;
620 bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
Artem Titove5cc85b2019-03-28 12:11:09 +0100621 // Returns list of networks for enabled endpoints. Caller takes ownership of
622 // returned rtc::Network objects.
623 std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
Artem Titov5501cef2020-08-04 11:49:19 +0200624 std::vector<EmulatedEndpoint*> GetEndpoints() const;
Artem Titov3e0b65d2020-07-23 02:19:02 +0200625 std::unique_ptr<EmulatedNetworkStats> GetStats() const;
Artem Titove5cc85b2019-03-28 12:11:09 +0100626
627 private:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100628 const std::vector<EmulatedEndpointImpl*> endpoints_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100629};
630
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200631template <typename FakePacketType>
632class FakePacketRoute : public EmulatedNetworkReceiverInterface {
633 public:
634 FakePacketRoute(EmulatedRoute* route,
635 std::function<void(FakePacketType, Timestamp)> action)
636 : route_(route),
637 action_(std::move(action)),
638 send_addr_(route_->from->GetPeerLocalAddress(), 0),
639 recv_addr_(route_->to->GetPeerLocalAddress(),
640 *route_->to->BindReceiver(0, this)) {}
641
Sebastian Janssond8aff212019-10-11 17:00:39 +0200642 ~FakePacketRoute() { route_->to->UnbindReceiver(recv_addr_.port()); }
643
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200644 void SendPacket(size_t size, FakePacketType packet) {
645 RTC_CHECK_GE(size, sizeof(int));
646 sent_.emplace(next_packet_id_, packet);
647 rtc::CopyOnWriteBuffer buf(size);
Danil Chapovalove15dc582021-01-07 15:24:05 +0100648 reinterpret_cast<int*>(buf.MutableData())[0] = next_packet_id_++;
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200649 route_->from->SendPacket(send_addr_, recv_addr_, buf);
650 }
651
652 void OnPacketReceived(EmulatedIpPacket packet) override {
Danil Chapovalove15dc582021-01-07 15:24:05 +0100653 int packet_id = reinterpret_cast<const int*>(packet.data.data())[0];
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200654 action_(std::move(sent_[packet_id]), packet.arrival_time);
655 sent_.erase(packet_id);
656 }
657
658 private:
659 EmulatedRoute* const route_;
660 const std::function<void(FakePacketType, Timestamp)> action_;
661 const rtc::SocketAddress send_addr_;
662 const rtc::SocketAddress recv_addr_;
663 int next_packet_id_ = 0;
664 std::map<int, FakePacketType> sent_;
665};
666
667template <typename RequestPacketType, typename ResponsePacketType>
668class TwoWayFakeTrafficRoute {
669 public:
670 class TrafficHandlerInterface {
671 public:
672 virtual void OnRequest(RequestPacketType, Timestamp) = 0;
673 virtual void OnResponse(ResponsePacketType, Timestamp) = 0;
674 virtual ~TrafficHandlerInterface() = default;
675 };
676 TwoWayFakeTrafficRoute(TrafficHandlerInterface* handler,
677 EmulatedRoute* send_route,
678 EmulatedRoute* ret_route)
679 : handler_(handler),
680 request_handler_{send_route,
681 [&](RequestPacketType packet, Timestamp arrival_time) {
682 handler_->OnRequest(std::move(packet), arrival_time);
683 }},
684 response_handler_{
685 ret_route, [&](ResponsePacketType packet, Timestamp arrival_time) {
686 handler_->OnResponse(std::move(packet), arrival_time);
687 }} {}
688 void SendRequest(size_t size, RequestPacketType packet) {
689 request_handler_.SendPacket(size, std::move(packet));
690 }
691 void SendResponse(size_t size, ResponsePacketType packet) {
692 response_handler_.SendPacket(size, std::move(packet));
693 }
694
695 private:
696 TrafficHandlerInterface* handler_;
697 FakePacketRoute<RequestPacketType> request_handler_;
698 FakePacketRoute<ResponsePacketType> response_handler_;
699};
Artem Titov40f51152019-01-04 15:45:01 +0100700} // namespace webrtc
701
Artem Titov386802e2019-07-05 10:48:17 +0200702#endif // TEST_NETWORK_NETWORK_EMULATION_H_