summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/call/simulated_network.h
blob: 02a37a3c43e76540f115aa1086fbd8c84a4d02c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#ifndef CALL_SIMULATED_NETWORK_H_
#define CALL_SIMULATED_NETWORK_H_

#include <stdint.h>

#include <deque>
#include <queue>
#include <vector>

#include "absl/types/optional.h"
#include "api/sequence_checker.h"
#include "api/test/simulated_network.h"
#include "api/units/data_size.h"
#include "api/units/timestamp.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/random.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

// Class simulating a network link.
//
// This is a basic implementation of NetworkBehaviorInterface that supports:
// - Packet loss
// - Capacity delay
// - Extra delay with or without packets reorder
// - Packet overhead
// - Queue max capacity
class RTC_EXPORT SimulatedNetwork : public SimulatedNetworkInterface {
 public:
  using Config = BuiltInNetworkBehaviorConfig;
  explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
  ~SimulatedNetwork() override;

  // Sets a new configuration. This will affect packets that will be sent with
  // EnqueuePacket but also packets in the network that have not left the
  // network emulation. Packets that are ready to be retrieved by
  // DequeueDeliverablePackets are not affected by the new configuration.
  // TODO(bugs.webrtc.org/14525): Fix SetConfig and make it apply only to the
  // part of the packet that is currently being sent (instead of applying to
  // all of it).
  void SetConfig(const Config& config) override;
  void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)>
                        config_modifier) override;
  void PauseTransmissionUntil(int64_t until_us) override;

  // NetworkBehaviorInterface
  bool EnqueuePacket(PacketInFlightInfo packet) override;
  std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
      int64_t receive_time_us) override;

  absl::optional<int64_t> NextDeliveryTimeUs() const override;

 private:
  struct PacketInfo {
    PacketInFlightInfo packet;
    // Time when the packet has left (or will leave) the network.
    int64_t arrival_time_us;
  };
  // Contains current configuration state.
  struct ConfigState {
    // Static link configuration.
    Config config;
    // The probability to drop the packet if we are currently dropping a
    // burst of packet
    double prob_loss_bursting;
    // The probability to drop a burst of packets.
    double prob_start_bursting;
    // Used for temporary delay spikes.
    int64_t pause_transmission_until_us = 0;
  };

  // Moves packets from capacity- to delay link.
  void UpdateCapacityQueue(ConfigState state, int64_t time_now_us)
      RTC_RUN_ON(&process_checker_);
  ConfigState GetConfigState() const;

  mutable Mutex config_lock_;

  // Guards the data structures involved in delay and loss processing, such as
  // the packet queues.
  rtc::RaceChecker process_checker_;
  // Models the capacity of the network by rejecting packets if the queue is
  // full and keeping them in the queue until they are ready to exit (according
  // to the link capacity, which cannot be violated, e.g. a 1 kbps link will
  // only be able to deliver 1000 bits per second).
  //
  // Invariant:
  // The head of the `capacity_link_` has arrival_time_us correctly set to the
  // time when the packet is supposed to be delivered (without accounting
  // potential packet loss or potential extra delay and without accounting for a
  // new configuration of the network, which requires a re-computation of the
  // arrival_time_us).
  std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_);
  // Models the extra delay of the network (see `queue_delay_ms`
  // and `delay_standard_deviation_ms` in BuiltInNetworkBehaviorConfig), packets
  // in the `delay_link_` have technically already left the network and don't
  // use its capacity but they are not delivered yet.
  std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_);
  // Represents the next moment in time when the network is supposed to deliver
  // packets to the client (either by pulling them from `delay_link_` or
  // `capacity_link_` or both).
  absl::optional<int64_t> next_process_time_us_
      RTC_GUARDED_BY(process_checker_);

  ConfigState config_state_ RTC_GUARDED_BY(config_lock_);

  Random random_ RTC_GUARDED_BY(process_checker_);
  // Are we currently dropping a burst of packets?
  bool bursting_;

  // The send time of the last enqueued packet, this is only used to check that
  // the send time of enqueued packets is monotonically increasing.
  int64_t last_enqueue_time_us_;

  // The last time a packet left the capacity_link_ (used to enforce
  // the capacity of the link and avoid packets starts to get sent before
  // the link it free).
  int64_t last_capacity_link_exit_time_;
};

}  // namespace webrtc

#endif  // CALL_SIMULATED_NETWORK_H_