blob: 78d53c1e9c2fdb5c40e40b26bcbb5467bb2f098e [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 Titov806299e2019-04-12 12:17:19 +020025#include "api/test/network_emulation_manager.h"
Artem Titov37d18482019-01-08 15:41:45 +010026#include "api/test/simulated_network.h"
Artem Titov40f51152019-01-04 15:45:01 +010027#include "api/units/timestamp.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/copy_on_write_buffer.h"
Artem Titove5cc85b2019-03-28 12:11:09 +010029#include "rtc_base/network.h"
Artem Titov1e023392020-01-23 15:46:45 +010030#include "rtc_base/network_constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080031#include "rtc_base/socket_address.h"
Artem Titov3e0b65d2020-07-23 02:19:02 +020032#include "rtc_base/synchronization/sequence_checker.h"
Sebastian Jansson4124dab2019-04-01 14:33:53 +020033#include "rtc_base/task_queue_for_test.h"
34#include "rtc_base/task_utils/repeating_task.h"
Artem Titovcbe6e8a2020-09-22 15:45:00 +020035#include "rtc_base/thread_annotations.h"
Artem Titov0774bd92019-01-30 15:26:05 +010036#include "system_wrappers/include/clock.h"
Artem Titov40f51152019-01-04 15:45:01 +010037
38namespace webrtc {
Artem Titov7bf8c7f2019-03-15 15:00:37 +010039
Artem Titov14b46a72020-07-31 12:57:24 +020040// This class is immutable and so thread safe.
41class EmulatedNetworkOutgoingStatsImpl final
42 : public EmulatedNetworkOutgoingStats {
Artem Titov3e0b65d2020-07-23 02:19:02 +020043 public:
Artem Titovcbe6e8a2020-09-22 15:45:00 +020044 EmulatedNetworkOutgoingStatsImpl(
45 int64_t packets_sent,
46 DataSize bytes_sent,
47 SamplesStatsCounter sent_packets_size_counter,
48 DataSize first_sent_packet_size,
49 Timestamp first_packet_sent_time,
50 Timestamp last_packet_sent_time)
Artem Titov3e0b65d2020-07-23 02:19:02 +020051 : packets_sent_(packets_sent),
52 bytes_sent_(bytes_sent),
Artem Titovcbe6e8a2020-09-22 15:45:00 +020053 sent_packets_size_counter_(std::move(sent_packets_size_counter)),
Artem Titov3e0b65d2020-07-23 02:19:02 +020054 first_sent_packet_size_(first_sent_packet_size),
55 first_packet_sent_time_(first_packet_sent_time),
Artem Titov14b46a72020-07-31 12:57:24 +020056 last_packet_sent_time_(last_packet_sent_time) {}
57 explicit EmulatedNetworkOutgoingStatsImpl(
58 const EmulatedNetworkOutgoingStats& stats)
59 : packets_sent_(stats.PacketsSent()),
60 bytes_sent_(stats.BytesSent()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +020061 sent_packets_size_counter_(stats.SentPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +020062 first_sent_packet_size_(stats.FirstSentPacketSize()),
63 first_packet_sent_time_(stats.FirstPacketSentTime()),
64 last_packet_sent_time_(stats.LastPacketSentTime()) {}
65 ~EmulatedNetworkOutgoingStatsImpl() override = default;
Artem Titov3e0b65d2020-07-23 02:19:02 +020066
67 int64_t PacketsSent() const override { return packets_sent_; }
68
69 DataSize BytesSent() const override { return bytes_sent_; }
70
Artem Titovcbe6e8a2020-09-22 15:45:00 +020071 const SamplesStatsCounter& SentPacketsSizeCounter() const override {
72 return sent_packets_size_counter_;
73 }
74
Artem Titov3e0b65d2020-07-23 02:19:02 +020075 DataSize FirstSentPacketSize() const override {
76 return first_sent_packet_size_;
77 }
78
79 Timestamp FirstPacketSentTime() const override {
80 return first_packet_sent_time_;
81 }
82
83 Timestamp LastPacketSentTime() const override {
84 return last_packet_sent_time_;
85 }
86
Artem Titov14b46a72020-07-31 12:57:24 +020087 DataRate AverageSendRate() const override;
Artem Titov3e0b65d2020-07-23 02:19:02 +020088
89 private:
Artem Titov3e0b65d2020-07-23 02:19:02 +020090 const int64_t packets_sent_;
91 const DataSize bytes_sent_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +020092 const SamplesStatsCounter sent_packets_size_counter_;
Artem Titov3e0b65d2020-07-23 02:19:02 +020093 const DataSize first_sent_packet_size_;
94 const Timestamp first_packet_sent_time_;
95 const Timestamp last_packet_sent_time_;
Artem Titov14b46a72020-07-31 12:57:24 +020096};
Artem Titov3e0b65d2020-07-23 02:19:02 +020097
Artem Titov14b46a72020-07-31 12:57:24 +020098// This class is immutable and so thread safe.
99class EmulatedNetworkIncomingStatsImpl final
100 : public EmulatedNetworkIncomingStats {
101 public:
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200102 EmulatedNetworkIncomingStatsImpl(
103 int64_t packets_received,
104 DataSize bytes_received,
105 SamplesStatsCounter received_packets_size_counter,
106 int64_t packets_dropped,
107 DataSize bytes_dropped,
108 SamplesStatsCounter dropped_packets_size_counter,
109 DataSize first_received_packet_size,
110 Timestamp first_packet_received_time,
111 Timestamp last_packet_received_time)
Artem Titov14b46a72020-07-31 12:57:24 +0200112 : packets_received_(packets_received),
113 bytes_received_(bytes_received),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200114 received_packets_size_counter_(received_packets_size_counter),
Artem Titov14b46a72020-07-31 12:57:24 +0200115 packets_dropped_(packets_dropped),
116 bytes_dropped_(bytes_dropped),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200117 dropped_packets_size_counter_(dropped_packets_size_counter),
Artem Titov14b46a72020-07-31 12:57:24 +0200118 first_received_packet_size_(first_received_packet_size),
119 first_packet_received_time_(first_packet_received_time),
120 last_packet_received_time_(last_packet_received_time) {}
121 explicit EmulatedNetworkIncomingStatsImpl(
122 const EmulatedNetworkIncomingStats& stats)
123 : packets_received_(stats.PacketsReceived()),
124 bytes_received_(stats.BytesReceived()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200125 received_packets_size_counter_(stats.ReceivedPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +0200126 packets_dropped_(stats.PacketsDropped()),
127 bytes_dropped_(stats.BytesDropped()),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200128 dropped_packets_size_counter_(stats.DroppedPacketsSizeCounter()),
Artem Titov14b46a72020-07-31 12:57:24 +0200129 first_received_packet_size_(stats.FirstReceivedPacketSize()),
130 first_packet_received_time_(stats.FirstPacketReceivedTime()),
131 last_packet_received_time_(stats.LastPacketReceivedTime()) {}
132 ~EmulatedNetworkIncomingStatsImpl() override = default;
133
134 int64_t PacketsReceived() const override { return packets_received_; }
135
136 DataSize BytesReceived() const override { return bytes_received_; }
137
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200138 const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
139 return received_packets_size_counter_;
140 }
141
Artem Titov14b46a72020-07-31 12:57:24 +0200142 int64_t PacketsDropped() const override { return packets_dropped_; }
143
144 DataSize BytesDropped() const override { return bytes_dropped_; }
145
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200146 const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
147 return dropped_packets_size_counter_;
148 }
149
Artem Titov14b46a72020-07-31 12:57:24 +0200150 DataSize FirstReceivedPacketSize() const override {
151 return first_received_packet_size_;
152 }
153
154 Timestamp FirstPacketReceivedTime() const override {
155 return first_packet_received_time_;
156 }
157
158 Timestamp LastPacketReceivedTime() const override {
159 return last_packet_received_time_;
160 }
161
162 DataRate AverageReceiveRate() const override;
163
164 private:
165 const int64_t packets_received_;
166 const DataSize bytes_received_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200167 const SamplesStatsCounter received_packets_size_counter_;
Artem Titov14b46a72020-07-31 12:57:24 +0200168 const int64_t packets_dropped_;
169 const DataSize bytes_dropped_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200170 const SamplesStatsCounter dropped_packets_size_counter_;
Artem Titov14b46a72020-07-31 12:57:24 +0200171 const DataSize first_received_packet_size_;
172 const Timestamp first_packet_received_time_;
173 const Timestamp last_packet_received_time_;
174};
175
176// This class is immutable and so is thread safe.
177class EmulatedNetworkStatsImpl final : public EmulatedNetworkStats {
178 public:
179 EmulatedNetworkStatsImpl(
180 std::vector<rtc::IPAddress> local_addresses,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200181 SamplesStatsCounter sent_packets_queue_wait_time_us,
Artem Titov14b46a72020-07-31 12:57:24 +0200182 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
183 outgoing_stats_per_destination,
184 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
185 incoming_stats_per_source)
186 : local_addresses_(std::move(local_addresses)),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200187 sent_packets_queue_wait_time_us_(sent_packets_queue_wait_time_us),
Artem Titov14b46a72020-07-31 12:57:24 +0200188 outgoing_stats_per_destination_(
189 std::move(outgoing_stats_per_destination)),
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200190 incoming_stats_per_source_(std::move(incoming_stats_per_source)),
191 overall_outgoing_stats_(GetOverallOutgoingStats()),
192 overall_incoming_stats_(GetOverallIncomingStats()) {}
Artem Titov14b46a72020-07-31 12:57:24 +0200193 ~EmulatedNetworkStatsImpl() override = default;
194
195 std::vector<rtc::IPAddress> LocalAddresses() const override {
196 return local_addresses_;
197 }
198
199 int64_t PacketsSent() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200200 return overall_outgoing_stats_->PacketsSent();
Artem Titov14b46a72020-07-31 12:57:24 +0200201 }
202
203 DataSize BytesSent() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200204 return overall_outgoing_stats_->BytesSent();
205 }
206
207 const SamplesStatsCounter& SentPacketsSizeCounter() const override {
208 return overall_outgoing_stats_->SentPacketsSizeCounter();
209 }
210
211 const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const override {
212 return sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200213 }
214
215 DataSize FirstSentPacketSize() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200216 return overall_outgoing_stats_->FirstSentPacketSize();
Artem Titov14b46a72020-07-31 12:57:24 +0200217 }
218
219 Timestamp FirstPacketSentTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200220 return overall_outgoing_stats_->FirstPacketSentTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200221 }
222
223 Timestamp LastPacketSentTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200224 return overall_outgoing_stats_->LastPacketSentTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200225 }
226
227 DataRate AverageSendRate() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200228 return overall_outgoing_stats_->AverageSendRate();
Artem Titov14b46a72020-07-31 12:57:24 +0200229 }
230
231 int64_t PacketsReceived() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200232 return overall_incoming_stats_->PacketsReceived();
Artem Titov14b46a72020-07-31 12:57:24 +0200233 }
234
235 DataSize BytesReceived() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200236 return overall_incoming_stats_->BytesReceived();
237 }
238
239 const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
240 return overall_incoming_stats_->ReceivedPacketsSizeCounter();
Artem Titov14b46a72020-07-31 12:57:24 +0200241 }
242
243 int64_t PacketsDropped() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200244 return overall_incoming_stats_->PacketsDropped();
Artem Titov14b46a72020-07-31 12:57:24 +0200245 }
246
247 DataSize BytesDropped() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200248 return overall_incoming_stats_->BytesDropped();
249 }
250
251 const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
252 return overall_incoming_stats_->DroppedPacketsSizeCounter();
Artem Titov14b46a72020-07-31 12:57:24 +0200253 }
254
255 DataSize FirstReceivedPacketSize() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200256 return overall_incoming_stats_->FirstReceivedPacketSize();
Artem Titov14b46a72020-07-31 12:57:24 +0200257 }
258
259 Timestamp FirstPacketReceivedTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200260 return overall_incoming_stats_->FirstPacketReceivedTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200261 }
262
263 Timestamp LastPacketReceivedTime() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200264 return overall_incoming_stats_->LastPacketReceivedTime();
Artem Titov14b46a72020-07-31 12:57:24 +0200265 }
266
267 DataRate AverageReceiveRate() const override {
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200268 return overall_incoming_stats_->AverageReceiveRate();
Artem Titov14b46a72020-07-31 12:57:24 +0200269 }
270
271 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
272 OutgoingStatsPerDestination() const override;
273
274 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
275 IncomingStatsPerSource() const override;
276
277 private:
278 std::unique_ptr<EmulatedNetworkOutgoingStats> GetOverallOutgoingStats() const;
279 std::unique_ptr<EmulatedNetworkIncomingStats> GetOverallIncomingStats() const;
280
281 const std::vector<rtc::IPAddress> local_addresses_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200282 const SamplesStatsCounter sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200283 const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
284 outgoing_stats_per_destination_;
285 const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
Artem Titov3e0b65d2020-07-23 02:19:02 +0200286 incoming_stats_per_source_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200287 const std::unique_ptr<EmulatedNetworkOutgoingStats> overall_outgoing_stats_;
288 const std::unique_ptr<EmulatedNetworkIncomingStats> overall_incoming_stats_;
Artem Titov3e0b65d2020-07-23 02:19:02 +0200289};
290
Artem Titov14b46a72020-07-31 12:57:24 +0200291class EmulatedNetworkOutgoingStatsBuilder {
292 public:
293 EmulatedNetworkOutgoingStatsBuilder();
294
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200295 void OnPacketSent(Timestamp sent_time,
296 DataSize packet_size,
297 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200298
299 void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
300
301 std::unique_ptr<EmulatedNetworkOutgoingStats> Build() const;
302
303 private:
304 SequenceChecker sequence_checker_;
305
306 int64_t packets_sent_ RTC_GUARDED_BY(sequence_checker_) = 0;
307 DataSize bytes_sent_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200308 SamplesStatsCounter sent_packets_size_counter_
309 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200310 DataSize first_sent_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
311 DataSize::Zero();
312 Timestamp first_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
313 Timestamp::PlusInfinity();
314 Timestamp last_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
315 Timestamp::MinusInfinity();
316};
317
318class EmulatedNetworkIncomingStatsBuilder {
319 public:
320 EmulatedNetworkIncomingStatsBuilder();
321
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200322 void OnPacketDropped(DataSize packet_size,
323 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200324
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200325 void OnPacketReceived(Timestamp received_time,
326 DataSize packet_size,
327 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov14b46a72020-07-31 12:57:24 +0200328
329 // Adds stats collected from another endpoints to the builder.
330 void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
331
332 std::unique_ptr<EmulatedNetworkIncomingStats> Build() const;
333
334 private:
335 SequenceChecker sequence_checker_;
336
337 int64_t packets_received_ RTC_GUARDED_BY(sequence_checker_) = 0;
338 DataSize bytes_received_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200339 SamplesStatsCounter received_packets_size_counter_
340 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200341 int64_t packets_dropped_ RTC_GUARDED_BY(sequence_checker_) = 0;
342 DataSize bytes_dropped_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200343 SamplesStatsCounter dropped_packets_size_counter_
344 RTC_GUARDED_BY(sequence_checker_);
Artem Titov14b46a72020-07-31 12:57:24 +0200345 DataSize first_received_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
346 DataSize::Zero();
347 Timestamp first_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
348 Timestamp::PlusInfinity();
349 Timestamp last_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
350 Timestamp::MinusInfinity();
351};
352
Artem Titov3e0b65d2020-07-23 02:19:02 +0200353// All methods of EmulatedNetworkStatsBuilder have to be used on a single
354// thread. It may be created on another thread.
355class EmulatedNetworkStatsBuilder {
356 public:
357 EmulatedNetworkStatsBuilder();
358 explicit EmulatedNetworkStatsBuilder(rtc::IPAddress local_ip);
359
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200360 void OnPacketSent(Timestamp queued_time,
361 Timestamp sent_time,
Artem Titov14b46a72020-07-31 12:57:24 +0200362 rtc::IPAddress destination_ip,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200363 DataSize packet_size,
364 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200365
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200366 void OnPacketDropped(rtc::IPAddress source_ip,
367 DataSize packet_size,
368 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200369
370 void OnPacketReceived(Timestamp received_time,
371 rtc::IPAddress source_ip,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200372 DataSize packet_size,
373 EmulatedEndpointConfig::StatsGatheringMode mode);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200374
Artem Titov14b46a72020-07-31 12:57:24 +0200375 void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200376
377 std::unique_ptr<EmulatedNetworkStats> Build() const;
378
379 private:
380 SequenceChecker sequence_checker_;
381
Artem Titov3e0b65d2020-07-23 02:19:02 +0200382 std::vector<rtc::IPAddress> local_addresses_
383 RTC_GUARDED_BY(sequence_checker_);
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200384 SamplesStatsCounter sent_packets_queue_wait_time_us_;
Artem Titov14b46a72020-07-31 12:57:24 +0200385 std::map<rtc::IPAddress, EmulatedNetworkOutgoingStatsBuilder>
386 outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
387 std::map<rtc::IPAddress, EmulatedNetworkIncomingStatsBuilder>
Artem Titov3e0b65d2020-07-23 02:19:02 +0200388 incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
389};
Artem Titov40f51152019-01-04 15:45:01 +0100390
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200391class LinkEmulation : public EmulatedNetworkReceiverInterface {
392 public:
393 LinkEmulation(Clock* clock,
394 rtc::TaskQueue* task_queue,
395 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
396 EmulatedNetworkReceiverInterface* receiver)
397 : clock_(clock),
398 task_queue_(task_queue),
399 network_behavior_(std::move(network_behavior)),
400 receiver_(receiver) {}
401 void OnPacketReceived(EmulatedIpPacket packet) override;
402
403 private:
404 struct StoredPacket {
405 uint64_t id;
406 EmulatedIpPacket packet;
407 bool removed;
408 };
409 void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200410
411 Clock* const clock_;
412 rtc::TaskQueue* const task_queue_;
413 const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
414 RTC_GUARDED_BY(task_queue_);
415 EmulatedNetworkReceiverInterface* const receiver_;
416 RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
417 std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
418 uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
419};
420
421class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
422 public:
423 explicit NetworkRouterNode(rtc::TaskQueue* task_queue);
424
425 void OnPacketReceived(EmulatedIpPacket packet) override;
Yves Gerey2257c082020-01-03 12:37:56 +0100426 void SetReceiver(const rtc::IPAddress& dest_ip,
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200427 EmulatedNetworkReceiverInterface* receiver);
Yves Gerey2257c082020-01-03 12:37:56 +0100428 void RemoveReceiver(const rtc::IPAddress& dest_ip);
Sebastian Jansson71c6b562019-08-14 11:31:02 +0200429 void SetWatcher(std::function<void(const EmulatedIpPacket&)> watcher);
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +0100430 void SetFilter(std::function<bool(const EmulatedIpPacket&)> filter);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200431
432 private:
433 rtc::TaskQueue* const task_queue_;
434 std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
435 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson71c6b562019-08-14 11:31:02 +0200436 std::function<void(const EmulatedIpPacket&)> watcher_
437 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson3d4d94a2020-01-14 14:25:41 +0100438 std::function<bool(const EmulatedIpPacket&)> filter_
439 RTC_GUARDED_BY(task_queue_);
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200440};
441
Artem Titov37d18482019-01-08 15:41:45 +0100442// Represents node in the emulated network. Nodes can be connected with each
443// other to form different networks with different behavior. The behavior of
444// the node itself is determined by a concrete implementation of
445// NetworkBehaviorInterface that is provided on construction.
446class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
447 public:
448 // Creates node based on |network_behavior|. The specified |packet_overhead|
449 // is added to the size of each packet in the information provided to
450 // |network_behavior|.
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200451 // |task_queue| is used to process packets and to forward the packets when
452 // they are ready.
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200453 EmulatedNetworkNode(
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200454 Clock* clock,
455 rtc::TaskQueue* task_queue,
Sebastian Jansson8c8feb92019-01-29 15:59:17 +0100456 std::unique_ptr<NetworkBehaviorInterface> network_behavior);
Artem Titov37d18482019-01-08 15:41:45 +0100457 ~EmulatedNetworkNode() override;
458 RTC_DISALLOW_COPY_AND_ASSIGN(EmulatedNetworkNode);
459
460 void OnPacketReceived(EmulatedIpPacket packet) override;
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200461
462 LinkEmulation* link() { return &link_; }
463 NetworkRouterNode* router() { return &router_; }
Artem Titov37d18482019-01-08 15:41:45 +0100464
Artem Titov4cd433e2019-04-01 11:01:16 +0200465 // Creates a route for the given receiver_ip over all the given nodes to the
Artem Titov37d18482019-01-08 15:41:45 +0100466 // given receiver.
Yves Gerey2257c082020-01-03 12:37:56 +0100467 static void CreateRoute(const rtc::IPAddress& receiver_ip,
Artem Titov37d18482019-01-08 15:41:45 +0100468 std::vector<EmulatedNetworkNode*> nodes,
469 EmulatedNetworkReceiverInterface* receiver);
Yves Gerey2257c082020-01-03 12:37:56 +0100470 static void ClearRoute(const rtc::IPAddress& receiver_ip,
Artem Titov37d18482019-01-08 15:41:45 +0100471 std::vector<EmulatedNetworkNode*> nodes);
472
473 private:
Sebastian Jansson62bb47f2019-04-01 18:23:58 +0200474 NetworkRouterNode router_;
475 LinkEmulation link_;
Artem Titov37d18482019-01-08 15:41:45 +0100476};
477
Artem Titov0774bd92019-01-30 15:26:05 +0100478// Represents single network interface on the device.
479// It will be used as sender from socket side to send data to the network and
480// will act as packet receiver from emulated network side to receive packets
481// from other EmulatedNetworkNodes.
Sebastian Janssoncec24332019-12-04 14:26:50 +0100482class EmulatedEndpointImpl : public EmulatedEndpoint {
Artem Titov0774bd92019-01-30 15:26:05 +0100483 public:
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200484 EmulatedEndpointImpl(
485 uint64_t id,
Artem Titovd2dd7322021-01-21 17:28:17 +0100486 absl::optional<std::string> name,
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200487 const rtc::IPAddress& ip,
488 EmulatedEndpointConfig::StatsGatheringMode stats_gathering_mode,
489 bool is_enabled,
490 rtc::AdapterType type,
491 rtc::TaskQueue* task_queue,
492 Clock* clock);
Sebastian Janssoncec24332019-12-04 14:26:50 +0100493 ~EmulatedEndpointImpl() override;
Artem Titov0774bd92019-01-30 15:26:05 +0100494
495 uint64_t GetId() const;
496
Artem Titovff393122019-04-05 11:19:52 +0200497 NetworkRouterNode* router() { return &router_; }
Sebastian Janssoncec24332019-12-04 14:26:50 +0100498
Artem Titov0774bd92019-01-30 15:26:05 +0100499 void SendPacket(const rtc::SocketAddress& from,
500 const rtc::SocketAddress& to,
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100501 rtc::CopyOnWriteBuffer packet_data,
502 uint16_t application_overhead = 0) override;
Artem Titov0774bd92019-01-30 15:26:05 +0100503
Artem Titov0774bd92019-01-30 15:26:05 +0100504 absl::optional<uint16_t> BindReceiver(
505 uint16_t desired_port,
Sebastian Janssoncec24332019-12-04 14:26:50 +0100506 EmulatedNetworkReceiverInterface* receiver) override;
507 void UnbindReceiver(uint16_t port) override;
Artem Titov0774bd92019-01-30 15:26:05 +0100508
Sebastian Janssoncec24332019-12-04 14:26:50 +0100509 rtc::IPAddress GetPeerLocalAddress() const override;
Artem Titov0774bd92019-01-30 15:26:05 +0100510
511 // Will be called to deliver packet into endpoint from network node.
512 void OnPacketReceived(EmulatedIpPacket packet) override;
513
Artem Titove5cc85b2019-03-28 12:11:09 +0100514 void Enable();
515 void Disable();
516 bool Enabled() const;
517
518 const rtc::Network& network() const { return *network_.get(); }
519
Artem Titov9dcab802020-08-04 11:19:28 +0200520 std::unique_ptr<EmulatedNetworkStats> stats() const;
Artem Titov806299e2019-04-12 12:17:19 +0200521
Artem Titov0774bd92019-01-30 15:26:05 +0100522 private:
523 static constexpr uint16_t kFirstEphemeralPort = 49152;
524 uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
525
Markus Handell3cb525b2020-07-16 16:16:09 +0200526 rtc::RecursiveCriticalSection receiver_lock_;
Artem Titovc8421c42021-02-02 10:57:19 +0100527 SequenceChecker enabled_state_checker_;
Artem Titov0774bd92019-01-30 15:26:05 +0100528
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200529 const uint64_t id_;
Artem Titovd2dd7322021-01-21 17:28:17 +0100530 const std::string log_name_;
Artem Titov0774bd92019-01-30 15:26:05 +0100531 // Peer's local IP address for this endpoint network interface.
532 const rtc::IPAddress peer_local_addr_;
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200533 const EmulatedEndpointConfig::StatsGatheringMode stats_gathering_mode_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100534 bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
Artem Titov1e023392020-01-23 15:46:45 +0100535 const rtc::AdapterType type_;
Artem Titov0774bd92019-01-30 15:26:05 +0100536 Clock* const clock_;
Artem Titovff393122019-04-05 11:19:52 +0200537 rtc::TaskQueue* const task_queue_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100538 std::unique_ptr<rtc::Network> network_;
Artem Titovff393122019-04-05 11:19:52 +0200539 NetworkRouterNode router_;
Artem Titov0774bd92019-01-30 15:26:05 +0100540
541 uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
542 std::map<uint16_t, EmulatedNetworkReceiverInterface*> port_to_receiver_
543 RTC_GUARDED_BY(receiver_lock_);
Artem Titov806299e2019-04-12 12:17:19 +0200544
Artem Titov3e0b65d2020-07-23 02:19:02 +0200545 EmulatedNetworkStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
Artem Titov0774bd92019-01-30 15:26:05 +0100546};
547
Artem Titovfc6ab002019-03-12 13:48:32 +0100548class EmulatedRoute {
549 public:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100550 EmulatedRoute(EmulatedEndpointImpl* from,
Artem Titovfc6ab002019-03-12 13:48:32 +0100551 std::vector<EmulatedNetworkNode*> via_nodes,
Sebastian Janssoncec24332019-12-04 14:26:50 +0100552 EmulatedEndpointImpl* to)
Artem Titovfc6ab002019-03-12 13:48:32 +0100553 : from(from), via_nodes(std::move(via_nodes)), to(to), active(true) {}
554
Sebastian Janssoncec24332019-12-04 14:26:50 +0100555 EmulatedEndpointImpl* from;
Artem Titovfc6ab002019-03-12 13:48:32 +0100556 std::vector<EmulatedNetworkNode*> via_nodes;
Sebastian Janssoncec24332019-12-04 14:26:50 +0100557 EmulatedEndpointImpl* to;
Artem Titovfc6ab002019-03-12 13:48:32 +0100558 bool active;
559};
Artem Titovc1a07372020-07-21 09:50:11 +0200560
Artem Titov5501cef2020-08-04 11:49:19 +0200561// This object is immutable and so thread safe.
Artem Titove5cc85b2019-03-28 12:11:09 +0100562class EndpointsContainer {
563 public:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100564 explicit EndpointsContainer(
565 const std::vector<EmulatedEndpointImpl*>& endpoints);
Artem Titove5cc85b2019-03-28 12:11:09 +0100566
Sebastian Janssoncec24332019-12-04 14:26:50 +0100567 EmulatedEndpointImpl* LookupByLocalAddress(
568 const rtc::IPAddress& local_ip) const;
569 bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
Artem Titove5cc85b2019-03-28 12:11:09 +0100570 // Returns list of networks for enabled endpoints. Caller takes ownership of
571 // returned rtc::Network objects.
572 std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
Artem Titov5501cef2020-08-04 11:49:19 +0200573 std::vector<EmulatedEndpoint*> GetEndpoints() const;
Artem Titov3e0b65d2020-07-23 02:19:02 +0200574 std::unique_ptr<EmulatedNetworkStats> GetStats() const;
Artem Titove5cc85b2019-03-28 12:11:09 +0100575
576 private:
Sebastian Janssoncec24332019-12-04 14:26:50 +0100577 const std::vector<EmulatedEndpointImpl*> endpoints_;
Artem Titove5cc85b2019-03-28 12:11:09 +0100578};
579
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200580template <typename FakePacketType>
581class FakePacketRoute : public EmulatedNetworkReceiverInterface {
582 public:
583 FakePacketRoute(EmulatedRoute* route,
584 std::function<void(FakePacketType, Timestamp)> action)
585 : route_(route),
586 action_(std::move(action)),
587 send_addr_(route_->from->GetPeerLocalAddress(), 0),
588 recv_addr_(route_->to->GetPeerLocalAddress(),
589 *route_->to->BindReceiver(0, this)) {}
590
Sebastian Janssond8aff212019-10-11 17:00:39 +0200591 ~FakePacketRoute() { route_->to->UnbindReceiver(recv_addr_.port()); }
592
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200593 void SendPacket(size_t size, FakePacketType packet) {
594 RTC_CHECK_GE(size, sizeof(int));
595 sent_.emplace(next_packet_id_, packet);
596 rtc::CopyOnWriteBuffer buf(size);
Danil Chapovalove15dc582021-01-07 15:24:05 +0100597 reinterpret_cast<int*>(buf.MutableData())[0] = next_packet_id_++;
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200598 route_->from->SendPacket(send_addr_, recv_addr_, buf);
599 }
600
601 void OnPacketReceived(EmulatedIpPacket packet) override {
Danil Chapovalove15dc582021-01-07 15:24:05 +0100602 int packet_id = reinterpret_cast<const int*>(packet.data.data())[0];
Sebastian Janssonb13ccc52019-06-07 13:06:00 +0200603 action_(std::move(sent_[packet_id]), packet.arrival_time);
604 sent_.erase(packet_id);
605 }
606
607 private:
608 EmulatedRoute* const route_;
609 const std::function<void(FakePacketType, Timestamp)> action_;
610 const rtc::SocketAddress send_addr_;
611 const rtc::SocketAddress recv_addr_;
612 int next_packet_id_ = 0;
613 std::map<int, FakePacketType> sent_;
614};
615
616template <typename RequestPacketType, typename ResponsePacketType>
617class TwoWayFakeTrafficRoute {
618 public:
619 class TrafficHandlerInterface {
620 public:
621 virtual void OnRequest(RequestPacketType, Timestamp) = 0;
622 virtual void OnResponse(ResponsePacketType, Timestamp) = 0;
623 virtual ~TrafficHandlerInterface() = default;
624 };
625 TwoWayFakeTrafficRoute(TrafficHandlerInterface* handler,
626 EmulatedRoute* send_route,
627 EmulatedRoute* ret_route)
628 : handler_(handler),
629 request_handler_{send_route,
630 [&](RequestPacketType packet, Timestamp arrival_time) {
631 handler_->OnRequest(std::move(packet), arrival_time);
632 }},
633 response_handler_{
634 ret_route, [&](ResponsePacketType packet, Timestamp arrival_time) {
635 handler_->OnResponse(std::move(packet), arrival_time);
636 }} {}
637 void SendRequest(size_t size, RequestPacketType packet) {
638 request_handler_.SendPacket(size, std::move(packet));
639 }
640 void SendResponse(size_t size, ResponsePacketType packet) {
641 response_handler_.SendPacket(size, std::move(packet));
642 }
643
644 private:
645 TrafficHandlerInterface* handler_;
646 FakePacketRoute<RequestPacketType> request_handler_;
647 FakePacketRoute<ResponsePacketType> response_handler_;
648};
Artem Titov40f51152019-01-04 15:45:01 +0100649} // namespace webrtc
650
Artem Titov386802e2019-07-05 10:48:17 +0200651#endif // TEST_NETWORK_NETWORK_EMULATION_H_