tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

fake_network_pipe.h (8937B)


      1 /*
      2 *  Copyright (c) 2012 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 
     11 #ifndef CALL_FAKE_NETWORK_PIPE_H_
     12 #define CALL_FAKE_NETWORK_PIPE_H_
     13 
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <deque>
     17 #include <map>
     18 #include <memory>
     19 #include <optional>
     20 
     21 #include "api/array_view.h"
     22 #include "api/call/transport.h"
     23 #include "api/test/simulated_network.h"
     24 #include "call/simulated_packet_receiver.h"
     25 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
     26 #include "rtc_base/copy_on_write_buffer.h"
     27 #include "rtc_base/synchronization/mutex.h"
     28 #include "rtc_base/thread_annotations.h"
     29 
     30 namespace webrtc {
     31 
     32 class Clock;
     33 class PacketReceiver;
     34 enum class MediaType;
     35 
     36 class NetworkPacket {
     37 public:
     38  NetworkPacket(CopyOnWriteBuffer packet,
     39                int64_t send_time,
     40                int64_t arrival_time,
     41                std::optional<PacketOptions> packet_options,
     42                bool is_rtcp,
     43                MediaType media_type,
     44                std::optional<int64_t> packet_time_us,
     45                Transport* transport);
     46 
     47  NetworkPacket(RtpPacketReceived packet,
     48                MediaType media_type,
     49                int64_t send_time,
     50                int64_t arrival_time);
     51 
     52  // Disallow copy constructor and copy assignment (no deep copies of `data_`).
     53  NetworkPacket(const NetworkPacket&) = delete;
     54  ~NetworkPacket();
     55  NetworkPacket& operator=(const NetworkPacket&) = delete;
     56  // Allow move constructor/assignment, so that we can use in stl containers.
     57  NetworkPacket(NetworkPacket&&);
     58  NetworkPacket& operator=(NetworkPacket&&);
     59 
     60  const uint8_t* data() const { return packet_.data(); }
     61  size_t data_length() const { return packet_.size(); }
     62  CopyOnWriteBuffer* raw_packet() { return &packet_; }
     63  int64_t send_time() const { return send_time_; }
     64  int64_t arrival_time() const { return arrival_time_; }
     65  void IncrementArrivalTime(int64_t extra_delay) {
     66    arrival_time_ += extra_delay;
     67  }
     68  PacketOptions packet_options() const {
     69    return packet_options_.value_or(PacketOptions());
     70  }
     71  bool is_rtcp() const { return is_rtcp_; }
     72  MediaType media_type() const { return media_type_; }
     73  std::optional<int64_t> packet_time_us() const { return packet_time_us_; }
     74  RtpPacketReceived* packet_received() {
     75    return packet_received_ ? &packet_received_.value() : nullptr;
     76  }
     77  std::optional<RtpPacketReceived> packet_received() const {
     78    return packet_received_;
     79  }
     80  Transport* transport() const { return transport_; }
     81 
     82 private:
     83  CopyOnWriteBuffer packet_;
     84  // The time the packet was sent out on the network.
     85  int64_t send_time_;
     86  // The time the packet should arrive at the receiver.
     87  int64_t arrival_time_;
     88  // If using a Transport for outgoing degradation, populate with
     89  // PacketOptions (transport-wide sequence number) for RTP.
     90  std::optional<PacketOptions> packet_options_;
     91  bool is_rtcp_;
     92  // If using a PacketReceiver for incoming degradation, populate with
     93  // appropriate MediaType and packet time. This type/timing will be kept and
     94  // forwarded. The packet time might be altered to reflect time spent in fake
     95  // network pipe.
     96  MediaType media_type_;
     97  std::optional<int64_t> packet_time_us_;
     98  std::optional<RtpPacketReceived> packet_received_;
     99  Transport* transport_;
    100 };
    101 
    102 // Class faking a network link, internally is uses an implementation of a
    103 // SimulatedNetworkInterface to simulate network behavior.
    104 class FakeNetworkPipe : public SimulatedPacketReceiverInterface {
    105 public:
    106  // Will keep `network_behavior` alive while pipe is alive itself.
    107  FakeNetworkPipe(Clock* clock,
    108                  std::unique_ptr<NetworkBehaviorInterface> network_behavior);
    109  FakeNetworkPipe(Clock* clock,
    110                  std::unique_ptr<NetworkBehaviorInterface> network_behavior,
    111                  PacketReceiver* receiver);
    112  FakeNetworkPipe(Clock* clock,
    113                  std::unique_ptr<NetworkBehaviorInterface> network_behavior,
    114                  PacketReceiver* receiver,
    115                  uint64_t seed);
    116 
    117  ~FakeNetworkPipe() override;
    118 
    119  FakeNetworkPipe(const FakeNetworkPipe&) = delete;
    120  FakeNetworkPipe& operator=(const FakeNetworkPipe&) = delete;
    121 
    122  void SetClockOffset(int64_t offset_ms);
    123 
    124  // Must not be called in parallel with DeliverPacket or Process.
    125  void SetReceiver(PacketReceiver* receiver) override;
    126 
    127  // Adds/subtracts references to Transport instances. If a Transport is
    128  // destroyed we cannot use to forward a potential delayed packet, these
    129  // methods are used to maintain a map of which instances are live.
    130  void AddActiveTransport(Transport* transport);
    131  void RemoveActiveTransport(Transport* transport);
    132 
    133  // Methods for use with Transport interface. When/if packets are delivered,
    134  // they will be passed to the instance specified by the `transport` parameter.
    135  // Note that that instance must be in the map of active transports.
    136  bool SendRtp(ArrayView<const uint8_t> packet,
    137               const PacketOptions& options,
    138               Transport* transport);
    139  bool SendRtcp(ArrayView<const uint8_t> packet, Transport* transport);
    140 
    141  // Implements the PacketReceiver interface. When/if packets are delivered,
    142  // they will be passed directly to the receiver instance given in
    143  // SetReceiver(). The receive time will be increased by the amount of time the
    144  // packet spent in the fake network pipe.
    145  void DeliverRtpPacket(
    146      MediaType media_type,
    147      RtpPacketReceived packet,
    148      OnUndemuxablePacketHandler undemuxable_packet_handler) override;
    149  void DeliverRtcpPacket(CopyOnWriteBuffer packet) override;
    150 
    151  // Processes the network queues and trigger PacketReceiver::IncomingPacket for
    152  // packets ready to be delivered.
    153  void Process() override;
    154  std::optional<int64_t> TimeUntilNextProcess() override;
    155 
    156  // Get statistics.
    157  float PercentageLoss();
    158  int AverageDelay() override;
    159  size_t DroppedPackets();
    160  size_t SentPackets();
    161  void ResetStats();
    162 
    163 protected:
    164  void DeliverPacketWithLock(NetworkPacket* packet);
    165  int64_t GetTimeInMicroseconds() const;
    166  bool ShouldProcess(int64_t time_now_us) const;
    167  void SetTimeToNextProcess(int64_t skip_us);
    168 
    169 private:
    170  struct StoredPacket {
    171    NetworkPacket packet;
    172    bool removed = false;
    173    explicit StoredPacket(NetworkPacket&& packet);
    174    StoredPacket(StoredPacket&&) = default;
    175    StoredPacket(const StoredPacket&) = delete;
    176    StoredPacket& operator=(const StoredPacket&) = delete;
    177    StoredPacket() = delete;
    178  };
    179 
    180  // Returns true if enqueued, or false if packet was dropped. Use this method
    181  // when enqueueing packets that should be received by PacketReceiver instance.
    182  bool EnqueuePacket(CopyOnWriteBuffer packet,
    183                     std::optional<PacketOptions> options,
    184                     bool is_rtcp,
    185                     MediaType media_type,
    186                     std::optional<int64_t> packet_time_us);
    187 
    188  // Returns true if enqueued, or false if packet was dropped. Use this method
    189  // when enqueueing packets that should be received by Transport instance.
    190  bool EnqueuePacket(CopyOnWriteBuffer packet,
    191                     std::optional<PacketOptions> options,
    192                     bool is_rtcp,
    193                     Transport* transport);
    194 
    195  bool EnqueuePacket(NetworkPacket&& net_packet)
    196      RTC_EXCLUSIVE_LOCKS_REQUIRED(process_lock_);
    197 
    198  void DeliverNetworkPacket(NetworkPacket* packet)
    199      RTC_EXCLUSIVE_LOCKS_REQUIRED(config_lock_);
    200  bool HasReceiver() const;
    201 
    202  Clock* const clock_;
    203  // `config_lock` guards the mostly constant things like the callbacks.
    204  mutable Mutex config_lock_;
    205  const std::unique_ptr<NetworkBehaviorInterface> network_behavior_;
    206  PacketReceiver* receiver_ RTC_GUARDED_BY(config_lock_);
    207 
    208  // `process_lock` guards the data structures involved in delay and loss
    209  // processes, such as the packet queues.
    210  Mutex process_lock_;
    211  // Packets  are added at the back of the deque, this makes the deque ordered
    212  // by increasing send time. The common case when removing packets from the
    213  // deque is removing early packets, which will be close to the front of the
    214  // deque. This makes finding the packets in the deque efficient in the common
    215  // case.
    216  std::deque<StoredPacket> packets_in_flight_ RTC_GUARDED_BY(process_lock_);
    217 
    218  int64_t clock_offset_ms_ RTC_GUARDED_BY(config_lock_);
    219 
    220  // Statistics.
    221  size_t dropped_packets_ RTC_GUARDED_BY(process_lock_);
    222  size_t sent_packets_ RTC_GUARDED_BY(process_lock_);
    223  int64_t total_packet_delay_us_ RTC_GUARDED_BY(process_lock_);
    224  int64_t last_log_time_us_;
    225 
    226  std::map<Transport*, size_t> active_transports_ RTC_GUARDED_BY(config_lock_);
    227 };
    228 
    229 }  // namespace webrtc
    230 
    231 #endif  // CALL_FAKE_NETWORK_PIPE_H_