1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker #ifndef CALL_SIMULATED_NETWORK_H_ 11*d9f75844SAndroid Build Coastguard Worker #define CALL_SIMULATED_NETWORK_H_ 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 14*d9f75844SAndroid Build Coastguard Worker 15*d9f75844SAndroid Build Coastguard Worker #include <deque> 16*d9f75844SAndroid Build Coastguard Worker #include <queue> 17*d9f75844SAndroid Build Coastguard Worker #include <vector> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/test/simulated_network.h" 22*d9f75844SAndroid Build Coastguard Worker #include "api/units/data_size.h" 23*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h" 24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/race_checker.h" 25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/random.h" 26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 28*d9f75844SAndroid Build Coastguard Worker 29*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker // Class simulating a network link. 32*d9f75844SAndroid Build Coastguard Worker // 33*d9f75844SAndroid Build Coastguard Worker // This is a basic implementation of NetworkBehaviorInterface that supports: 34*d9f75844SAndroid Build Coastguard Worker // - Packet loss 35*d9f75844SAndroid Build Coastguard Worker // - Capacity delay 36*d9f75844SAndroid Build Coastguard Worker // - Extra delay with or without packets reorder 37*d9f75844SAndroid Build Coastguard Worker // - Packet overhead 38*d9f75844SAndroid Build Coastguard Worker // - Queue max capacity 39*d9f75844SAndroid Build Coastguard Worker class SimulatedNetwork : public SimulatedNetworkInterface { 40*d9f75844SAndroid Build Coastguard Worker public: 41*d9f75844SAndroid Build Coastguard Worker using Config = BuiltInNetworkBehaviorConfig; 42*d9f75844SAndroid Build Coastguard Worker explicit SimulatedNetwork(Config config, uint64_t random_seed = 1); 43*d9f75844SAndroid Build Coastguard Worker ~SimulatedNetwork() override; 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard Worker // Sets a new configuration. This will affect packets that will be sent with 46*d9f75844SAndroid Build Coastguard Worker // EnqueuePacket but also packets in the network that have not left the 47*d9f75844SAndroid Build Coastguard Worker // network emulation. Packets that are ready to be retrieved by 48*d9f75844SAndroid Build Coastguard Worker // DequeueDeliverablePackets are not affected by the new configuration. 49*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/14525): Fix SetConfig and make it apply only to the 50*d9f75844SAndroid Build Coastguard Worker // part of the packet that is currently being sent (instead of applying to 51*d9f75844SAndroid Build Coastguard Worker // all of it). 52*d9f75844SAndroid Build Coastguard Worker void SetConfig(const Config& config) override; 53*d9f75844SAndroid Build Coastguard Worker void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)> 54*d9f75844SAndroid Build Coastguard Worker config_modifier) override; 55*d9f75844SAndroid Build Coastguard Worker void PauseTransmissionUntil(int64_t until_us) override; 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker // NetworkBehaviorInterface 58*d9f75844SAndroid Build Coastguard Worker bool EnqueuePacket(PacketInFlightInfo packet) override; 59*d9f75844SAndroid Build Coastguard Worker std::vector<PacketDeliveryInfo> DequeueDeliverablePackets( 60*d9f75844SAndroid Build Coastguard Worker int64_t receive_time_us) override; 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> NextDeliveryTimeUs() const override; 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker private: 65*d9f75844SAndroid Build Coastguard Worker struct PacketInfo { 66*d9f75844SAndroid Build Coastguard Worker PacketInFlightInfo packet; 67*d9f75844SAndroid Build Coastguard Worker // Time when the packet has left (or will leave) the network. 68*d9f75844SAndroid Build Coastguard Worker int64_t arrival_time_us; 69*d9f75844SAndroid Build Coastguard Worker }; 70*d9f75844SAndroid Build Coastguard Worker // Contains current configuration state. 71*d9f75844SAndroid Build Coastguard Worker struct ConfigState { 72*d9f75844SAndroid Build Coastguard Worker // Static link configuration. 73*d9f75844SAndroid Build Coastguard Worker Config config; 74*d9f75844SAndroid Build Coastguard Worker // The probability to drop the packet if we are currently dropping a 75*d9f75844SAndroid Build Coastguard Worker // burst of packet 76*d9f75844SAndroid Build Coastguard Worker double prob_loss_bursting; 77*d9f75844SAndroid Build Coastguard Worker // The probability to drop a burst of packets. 78*d9f75844SAndroid Build Coastguard Worker double prob_start_bursting; 79*d9f75844SAndroid Build Coastguard Worker // Used for temporary delay spikes. 80*d9f75844SAndroid Build Coastguard Worker int64_t pause_transmission_until_us = 0; 81*d9f75844SAndroid Build Coastguard Worker }; 82*d9f75844SAndroid Build Coastguard Worker 83*d9f75844SAndroid Build Coastguard Worker // Moves packets from capacity- to delay link. 84*d9f75844SAndroid Build Coastguard Worker void UpdateCapacityQueue(ConfigState state, int64_t time_now_us) 85*d9f75844SAndroid Build Coastguard Worker RTC_RUN_ON(&process_checker_); 86*d9f75844SAndroid Build Coastguard Worker ConfigState GetConfigState() const; 87*d9f75844SAndroid Build Coastguard Worker 88*d9f75844SAndroid Build Coastguard Worker mutable Mutex config_lock_; 89*d9f75844SAndroid Build Coastguard Worker 90*d9f75844SAndroid Build Coastguard Worker // Guards the data structures involved in delay and loss processing, such as 91*d9f75844SAndroid Build Coastguard Worker // the packet queues. 92*d9f75844SAndroid Build Coastguard Worker rtc::RaceChecker process_checker_; 93*d9f75844SAndroid Build Coastguard Worker // Models the capacity of the network by rejecting packets if the queue is 94*d9f75844SAndroid Build Coastguard Worker // full and keeping them in the queue until they are ready to exit (according 95*d9f75844SAndroid Build Coastguard Worker // to the link capacity, which cannot be violated, e.g. a 1 kbps link will 96*d9f75844SAndroid Build Coastguard Worker // only be able to deliver 1000 bits per second). 97*d9f75844SAndroid Build Coastguard Worker // 98*d9f75844SAndroid Build Coastguard Worker // Invariant: 99*d9f75844SAndroid Build Coastguard Worker // The head of the `capacity_link_` has arrival_time_us correctly set to the 100*d9f75844SAndroid Build Coastguard Worker // time when the packet is supposed to be delivered (without accounting 101*d9f75844SAndroid Build Coastguard Worker // potential packet loss or potential extra delay and without accounting for a 102*d9f75844SAndroid Build Coastguard Worker // new configuration of the network, which requires a re-computation of the 103*d9f75844SAndroid Build Coastguard Worker // arrival_time_us). 104*d9f75844SAndroid Build Coastguard Worker std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_); 105*d9f75844SAndroid Build Coastguard Worker // Models the extra delay of the network (see `queue_delay_ms` 106*d9f75844SAndroid Build Coastguard Worker // and `delay_standard_deviation_ms` in BuiltInNetworkBehaviorConfig), packets 107*d9f75844SAndroid Build Coastguard Worker // in the `delay_link_` have technically already left the network and don't 108*d9f75844SAndroid Build Coastguard Worker // use its capacity but they are not delivered yet. 109*d9f75844SAndroid Build Coastguard Worker std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_); 110*d9f75844SAndroid Build Coastguard Worker // Represents the next moment in time when the network is supposed to deliver 111*d9f75844SAndroid Build Coastguard Worker // packets to the client (either by pulling them from `delay_link_` or 112*d9f75844SAndroid Build Coastguard Worker // `capacity_link_` or both). 113*d9f75844SAndroid Build Coastguard Worker absl::optional<int64_t> next_process_time_us_ 114*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(process_checker_); 115*d9f75844SAndroid Build Coastguard Worker 116*d9f75844SAndroid Build Coastguard Worker ConfigState config_state_ RTC_GUARDED_BY(config_lock_); 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker Random random_ RTC_GUARDED_BY(process_checker_); 119*d9f75844SAndroid Build Coastguard Worker // Are we currently dropping a burst of packets? 120*d9f75844SAndroid Build Coastguard Worker bool bursting_; 121*d9f75844SAndroid Build Coastguard Worker 122*d9f75844SAndroid Build Coastguard Worker // The send time of the last enqueued packet, this is only used to check that 123*d9f75844SAndroid Build Coastguard Worker // the send time of enqueued packets is monotonically increasing. 124*d9f75844SAndroid Build Coastguard Worker int64_t last_enqueue_time_us_; 125*d9f75844SAndroid Build Coastguard Worker 126*d9f75844SAndroid Build Coastguard Worker // The last time a packet left the capacity_link_ (used to enforce 127*d9f75844SAndroid Build Coastguard Worker // the capacity of the link and avoid packets starts to get sent before 128*d9f75844SAndroid Build Coastguard Worker // the link it free). 129*d9f75844SAndroid Build Coastguard Worker int64_t last_capacity_link_exit_time_; 130*d9f75844SAndroid Build Coastguard Worker }; 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 133*d9f75844SAndroid Build Coastguard Worker 134*d9f75844SAndroid Build Coastguard Worker #endif // CALL_SIMULATED_NETWORK_H_ 135