• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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