1 /* 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 13 #include <stdint.h> 14 15 #include <deque> 16 #include <queue> 17 #include <vector> 18 19 #include "absl/types/optional.h" 20 #include "api/sequence_checker.h" 21 #include "api/test/simulated_network.h" 22 #include "api/units/data_size.h" 23 #include "api/units/timestamp.h" 24 #include "rtc_base/race_checker.h" 25 #include "rtc_base/random.h" 26 #include "rtc_base/synchronization/mutex.h" 27 #include "rtc_base/thread_annotations.h" 28 29 namespace webrtc { 30 31 // 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 39 class SimulatedNetwork : public SimulatedNetworkInterface { 40 public: 41 using Config = BuiltInNetworkBehaviorConfig; 42 explicit SimulatedNetwork(Config config, uint64_t random_seed = 1); 43 ~SimulatedNetwork() override; 44 45 // 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). 52 void SetConfig(const Config& config) override; 53 void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)> 54 config_modifier) override; 55 void PauseTransmissionUntil(int64_t until_us) override; 56 57 // NetworkBehaviorInterface 58 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; 67 // Time when the packet has left (or will leave) the network. 68 int64_t arrival_time_us; 69 }; 70 // 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 }; 82 83 // Moves packets from capacity- to delay link. 84 void UpdateCapacityQueue(ConfigState state, int64_t time_now_us) 85 RTC_RUN_ON(&process_checker_); 86 ConfigState GetConfigState() const; 87 88 mutable Mutex config_lock_; 89 90 // Guards the data structures involved in delay and loss processing, such as 91 // the packet queues. 92 rtc::RaceChecker process_checker_; 93 // 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). 104 std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_); 105 // 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. 109 std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_); 110 // 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_); 115 116 ConfigState config_state_ RTC_GUARDED_BY(config_lock_); 117 118 Random random_ RTC_GUARDED_BY(process_checker_); 119 // Are we currently dropping a burst of packets? 120 bool bursting_; 121 122 // 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_; 130 }; 131 132 } // namespace webrtc 133 134 #endif // CALL_SIMULATED_NETWORK_H_ 135