blob: 8597367addf4be7b26f67bb0fcd6f27222d30f5c [file] [log] [blame]
Sebastian Janssonf96b1ca2018-08-07 16:58:051/*
2 * Copyright 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#ifndef CALL_SIMULATED_NETWORK_H_
11#define CALL_SIMULATED_NETWORK_H_
12
Yves Gerey3e707812018-11-28 15:47:4913#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3314
Sebastian Janssonf96b1ca2018-08-07 16:58:0515#include <deque>
16#include <queue>
17#include <vector>
18
Sebastian Janssonf96b1ca2018-08-07 16:58:0519#include "absl/types/optional.h"
Artem Titovd15a5752021-02-10 13:31:2420#include "api/sequence_checker.h"
Sebastian Janssonf96b1ca2018-08-07 16:58:0521#include "api/test/simulated_network.h"
Sebastian Jansson2b08e312019-02-25 09:24:4622#include "api/units/data_size.h"
23#include "api/units/timestamp.h"
Sebastian Janssoneceea312019-01-31 10:50:0424#include "rtc_base/race_checker.h"
Sebastian Janssonf96b1ca2018-08-07 16:58:0525#include "rtc_base/random.h"
Markus Handell8fe932a2020-07-06 15:41:3526#include "rtc_base/synchronization/mutex.h"
Sebastian Janssonf96b1ca2018-08-07 16:58:0527#include "rtc_base/thread_annotations.h"
28
29namespace webrtc {
30
Mirko Bonadei248fdb12022-10-13 13:06:0831// Class simulating a network link.
32//
33// This is a basic implementation of NetworkBehaviorInterface that supports:
34// - Packet loss
35// - Capacity delay
36// - Extra delay with or without packets reorder
37// - Packet overhead
38// - Queue max capacity
Sebastian Janssoncec24332019-12-04 13:26:5039class SimulatedNetwork : public SimulatedNetworkInterface {
Sebastian Janssonf96b1ca2018-08-07 16:58:0540 public:
Artem Titov75e36472018-10-08 10:28:5641 using Config = BuiltInNetworkBehaviorConfig;
Sebastian Janssonf96b1ca2018-08-07 16:58:0542 explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
43 ~SimulatedNetwork() override;
44
Mirko Bonadei248fdb12022-10-13 13:06:0845 // Sets a new configuration. This will affect packets that will be sent with
46 // EnqueuePacket but also packets in the network that have not left the
47 // network emulation. Packets that are ready to be retrieved by
48 // DequeueDeliverablePackets are not affected by the new configuration.
49 // TODO(bugs.webrtc.org/14525): Fix SetConfig and make it apply only to the
50 // part of the packet that is currently being sent (instead of applying to
51 // all of it).
Sebastian Janssoncec24332019-12-04 13:26:5052 void SetConfig(const Config& config) override;
Sebastian Jansson89eb0bb2020-03-13 16:47:3853 void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)>
54 config_modifier) override;
Sebastian Janssoncec24332019-12-04 13:26:5055 void PauseTransmissionUntil(int64_t until_us) override;
Sebastian Janssonf96b1ca2018-08-07 16:58:0556
Artem Titov8ea1e9d2018-10-04 12:46:3157 // NetworkBehaviorInterface
Sebastian Janssonf96b1ca2018-08-07 16:58:0558 bool EnqueuePacket(PacketInFlightInfo packet) override;
59 std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
60 int64_t receive_time_us) override;
61
62 absl::optional<int64_t> NextDeliveryTimeUs() const override;
63
64 private:
65 struct PacketInfo {
66 PacketInFlightInfo packet;
Mirko Bonadei248fdb12022-10-13 13:06:0867 // Time when the packet has left (or will leave) the network.
Sebastian Janssonf96b1ca2018-08-07 16:58:0568 int64_t arrival_time_us;
69 };
Sebastian Janssoneceea312019-01-31 10:50:0470 // Contains current configuration state.
71 struct ConfigState {
72 // Static link configuration.
73 Config config;
74 // The probability to drop the packet if we are currently dropping a
75 // burst of packet
76 double prob_loss_bursting;
77 // The probability to drop a burst of packets.
78 double prob_start_bursting;
79 // Used for temporary delay spikes.
80 int64_t pause_transmission_until_us = 0;
81 };
Christoffer Rodbro813c79b2019-01-31 08:25:1282
83 // Moves packets from capacity- to delay link.
Sebastian Janssoneceea312019-01-31 10:50:0484 void UpdateCapacityQueue(ConfigState state, int64_t time_now_us)
85 RTC_RUN_ON(&process_checker_);
86 ConfigState GetConfigState() const;
Christoffer Rodbro813c79b2019-01-31 08:25:1287
Markus Handell8fe932a2020-07-06 15:41:3588 mutable Mutex config_lock_;
Sebastian Janssonf96b1ca2018-08-07 16:58:0589
Mirko Bonadei248fdb12022-10-13 13:06:0890 // Guards the data structures involved in delay and loss processing, such as
91 // the packet queues.
Sebastian Janssoneceea312019-01-31 10:50:0492 rtc::RaceChecker process_checker_;
Mirko Bonadei248fdb12022-10-13 13:06:0893 // Models the capacity of the network by rejecting packets if the queue is
94 // full and keeping them in the queue until they are ready to exit (according
95 // to the link capacity, which cannot be violated, e.g. a 1 kbps link will
96 // only be able to deliver 1000 bits per second).
97 //
98 // Invariant:
99 // The head of the `capacity_link_` has arrival_time_us correctly set to the
100 // time when the packet is supposed to be delivered (without accounting
101 // potential packet loss or potential extra delay and without accounting for a
102 // new configuration of the network, which requires a re-computation of the
103 // arrival_time_us).
Sebastian Janssoneceea312019-01-31 10:50:04104 std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_);
Mirko Bonadei248fdb12022-10-13 13:06:08105 // Models the extra delay of the network (see `queue_delay_ms`
106 // and `delay_standard_deviation_ms` in BuiltInNetworkBehaviorConfig), packets
107 // in the `delay_link_` have technically already left the network and don't
108 // use its capacity but they are not delivered yet.
Sebastian Janssoneceea312019-01-31 10:50:04109 std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_);
Mirko Bonadei248fdb12022-10-13 13:06:08110 // Represents the next moment in time when the network is supposed to deliver
111 // packets to the client (either by pulling them from `delay_link_` or
112 // `capacity_link_` or both).
113 absl::optional<int64_t> next_process_time_us_
114 RTC_GUARDED_BY(process_checker_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05115
Sebastian Janssoneceea312019-01-31 10:50:04116 ConfigState config_state_ RTC_GUARDED_BY(config_lock_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05117
Mirko Bonadei248fdb12022-10-13 13:06:08118 Random random_ RTC_GUARDED_BY(process_checker_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05119 // Are we currently dropping a burst of packets?
120 bool bursting_;
121
Mirko Bonadei248fdb12022-10-13 13:06:08122 // The send time of the last enqueued packet, this is only used to check that
123 // the send time of enqueued packets is monotonically increasing.
124 int64_t last_enqueue_time_us_;
125
126 // The last time a packet left the capacity_link_ (used to enforce
127 // the capacity of the link and avoid packets starts to get sent before
128 // the link it free).
129 int64_t last_capacity_link_exit_time_;
Sebastian Janssonf96b1ca2018-08-07 16:58:05130};
131
132} // namespace webrtc
133
134#endif // CALL_SIMULATED_NETWORK_H_