blob: 68d066cb827133a6d476479483e75a53d2f87931 [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 {
Sebastian Jansson2b08e312019-02-25 09:24:4630// Implementation of the CoDel active queue management algorithm. Loosely based
31// on CoDel pseudocode from ACMQueue. CoDel keeps queuing delays low by dropping
32// packets when delay is high. For each packet ready for dequeue, call
33// DropDequeuePacket with the packet parameters to update the CoDel state.
34class CoDelSimulation {
35 public:
36 CoDelSimulation();
37 ~CoDelSimulation();
38
39 // Returns true if packet should be dropped.
40 bool DropDequeuedPacket(Timestamp now,
41 Timestamp enqueing_time,
42 DataSize packet_size,
43 DataSize queue_size);
44
45 private:
46 enum State { kNormal, kPending, kDropping };
47 Timestamp enter_drop_state_at_ = Timestamp::PlusInfinity();
48 Timestamp last_drop_at_ = Timestamp::MinusInfinity();
49 int drop_count_ = 0;
50 int previous_drop_count_ = 0;
51 State state_ = State::kNormal;
52};
Sebastian Janssonf96b1ca2018-08-07 16:58:0553
54// Class simulating a network link. This is a simple and naive solution just
55// faking capacity and adding an extra transport delay in addition to the
56// capacity introduced delay.
Sebastian Janssoncec24332019-12-04 13:26:5057class SimulatedNetwork : public SimulatedNetworkInterface {
Sebastian Janssonf96b1ca2018-08-07 16:58:0558 public:
Artem Titov75e36472018-10-08 10:28:5659 using Config = BuiltInNetworkBehaviorConfig;
Sebastian Janssonf96b1ca2018-08-07 16:58:0560 explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
61 ~SimulatedNetwork() override;
62
63 // Sets a new configuration. This won't affect packets already in the pipe.
Sebastian Janssoncec24332019-12-04 13:26:5064 void SetConfig(const Config& config) override;
Sebastian Jansson89eb0bb2020-03-13 16:47:3865 void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)>
66 config_modifier) override;
Sebastian Janssoncec24332019-12-04 13:26:5067 void PauseTransmissionUntil(int64_t until_us) override;
Sebastian Janssonf96b1ca2018-08-07 16:58:0568
Artem Titov8ea1e9d2018-10-04 12:46:3169 // NetworkBehaviorInterface
Sebastian Janssonf96b1ca2018-08-07 16:58:0570 bool EnqueuePacket(PacketInFlightInfo packet) override;
71 std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
72 int64_t receive_time_us) override;
73
74 absl::optional<int64_t> NextDeliveryTimeUs() const override;
75
76 private:
77 struct PacketInfo {
78 PacketInFlightInfo packet;
79 int64_t arrival_time_us;
80 };
Sebastian Janssoneceea312019-01-31 10:50:0481 // Contains current configuration state.
82 struct ConfigState {
83 // Static link configuration.
84 Config config;
85 // The probability to drop the packet if we are currently dropping a
86 // burst of packet
87 double prob_loss_bursting;
88 // The probability to drop a burst of packets.
89 double prob_start_bursting;
90 // Used for temporary delay spikes.
91 int64_t pause_transmission_until_us = 0;
92 };
Christoffer Rodbro813c79b2019-01-31 08:25:1293
94 // Moves packets from capacity- to delay link.
Sebastian Janssoneceea312019-01-31 10:50:0495 void UpdateCapacityQueue(ConfigState state, int64_t time_now_us)
96 RTC_RUN_ON(&process_checker_);
97 ConfigState GetConfigState() const;
Christoffer Rodbro813c79b2019-01-31 08:25:1298
Markus Handell8fe932a2020-07-06 15:41:3599 mutable Mutex config_lock_;
Sebastian Janssonf96b1ca2018-08-07 16:58:05100
Sebastian Janssoneceea312019-01-31 10:50:04101 // |process_checker_| guards the data structures involved in delay and loss
Sebastian Janssonf96b1ca2018-08-07 16:58:05102 // processes, such as the packet queues.
Sebastian Janssoneceea312019-01-31 10:50:04103 rtc::RaceChecker process_checker_;
Sebastian Jansson2b08e312019-02-25 09:24:46104 CoDelSimulation codel_controller_ RTC_GUARDED_BY(process_checker_);
Sebastian Janssoneceea312019-01-31 10:50:04105 std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05106 Random random_;
107
Sebastian Janssoneceea312019-01-31 10:50:04108 std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05109
Sebastian Janssoneceea312019-01-31 10:50:04110 ConfigState config_state_ RTC_GUARDED_BY(config_lock_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05111
112 // Are we currently dropping a burst of packets?
113 bool bursting_;
114
Sebastian Janssoneceea312019-01-31 10:50:04115 int64_t queue_size_bytes_ RTC_GUARDED_BY(process_checker_) = 0;
116 int64_t pending_drain_bits_ RTC_GUARDED_BY(process_checker_) = 0;
Christoffer Rodbro813c79b2019-01-31 08:25:12117 absl::optional<int64_t> last_capacity_link_visit_us_
Sebastian Janssoneceea312019-01-31 10:50:04118 RTC_GUARDED_BY(process_checker_);
Sebastian Jansson836fee12019-02-08 15:08:10119 absl::optional<int64_t> next_process_time_us_
120 RTC_GUARDED_BY(process_checker_);
Sebastian Janssonf96b1ca2018-08-07 16:58:05121};
122
123} // namespace webrtc
124
125#endif // CALL_SIMULATED_NETWORK_H_