tor-browser

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

network_emulation_manager.h (17679B)


      1 /*
      2 *  Copyright (c) 2019 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 API_TEST_NETWORK_EMULATION_MANAGER_H_
     12 #define API_TEST_NETWORK_EMULATION_MANAGER_H_
     13 
     14 #include <cstdint>
     15 #include <functional>
     16 #include <memory>
     17 #include <optional>
     18 #include <string>
     19 #include <utility>
     20 #include <vector>
     21 
     22 #include "absl/base/nullability.h"
     23 #include "absl/strings/string_view.h"
     24 #include "api/array_view.h"
     25 #include "api/field_trials_view.h"
     26 #include "api/test/network_emulation/cross_traffic.h"
     27 #include "api/test/network_emulation/network_emulation_interfaces.h"
     28 #include "api/test/network_emulation/network_queue.h"
     29 #include "api/test/peer_network_dependencies.h"
     30 #include "api/test/simulated_network.h"
     31 #include "api/test/time_controller.h"
     32 #include "api/units/data_rate.h"
     33 #include "rtc_base/ip_address.h"
     34 #include "rtc_base/network_constants.h"
     35 #include "rtc_base/socket_address.h"
     36 
     37 namespace webrtc {
     38 
     39 // This API is still in development and can be changed without prior notice.
     40 
     41 // These classes are forward declared here, because they used as handles, to
     42 // make it possible for client code to operate with these abstractions and build
     43 // required network configuration. With forward declaration here implementation
     44 // is more readable, than with interfaces approach and cause user needn't any
     45 // API methods on these abstractions it is acceptable here.
     46 
     47 // EmulatedNetworkNode is an abstraction for some network in the real world,
     48 // like 3G network between peers, or Wi-Fi for one peer and LTE for another.
     49 // Multiple networks can be joined into chain emulating a network path from
     50 // one peer to another.
     51 class EmulatedNetworkNode;
     52 
     53 // EmulatedRoute is handle for single route from one network interface on one
     54 // peer device to another network interface on another peer device.
     55 class EmulatedRoute;
     56 
     57 enum class EmulatedNetworkStatsGatheringMode {
     58  // Gather main network stats counters. See more details on which particular
     59  // metrics are collected in the `EmulatedNetworkStats` and
     60  // `EmulatedNetworkNodeStats` documentation.
     61  kDefault,
     62  // kDefault + also gather per packet statistics. In this mode more memory
     63  // will be used.
     64  kDebug
     65 };
     66 
     67 struct EmulatedEndpointConfig {
     68  enum class IpAddressFamily { kIpv4, kIpv6 };
     69 
     70  // If specified will be used to name endpoint for logging purposes.
     71  std::optional<std::string> name = std::nullopt;
     72  IpAddressFamily generated_ip_family = IpAddressFamily::kIpv4;
     73  // If specified will be used as IP address for endpoint node. Must be unique
     74  // among all created nodes.
     75  std::optional<IPAddress> ip;
     76  // Should endpoint be enabled or not, when it will be created.
     77  // Enabled endpoints will be available for webrtc to send packets.
     78  bool start_as_enabled = true;
     79  // Network type which will be used to represent endpoint to WebRTC.
     80  AdapterType type = AdapterType::ADAPTER_TYPE_UNKNOWN;
     81  // Allow endpoint to send packets specifying source IP address different to
     82  // the current endpoint IP address. If false endpoint will crash if attempt
     83  // to send such packet will be done.
     84  bool allow_send_packet_with_different_source_ip = false;
     85  // Allow endpoint to receive packet with destination IP address different to
     86  // the current endpoint IP address. If false endpoint will crash if such
     87  // packet will arrive.
     88  bool allow_receive_packets_with_different_dest_ip = false;
     89 };
     90 
     91 struct EmulatedTURNServerConfig {
     92  EmulatedEndpointConfig client_config;
     93  EmulatedEndpointConfig peer_config;
     94  bool enable_permission_checks = true;
     95 };
     96 
     97 // EmulatedTURNServer is an abstraction for a TURN server.
     98 class EmulatedTURNServerInterface {
     99 public:
    100  struct IceServerConfig {
    101    std::string username;
    102    std::string password;
    103    std::string url;
    104  };
    105 
    106  virtual ~EmulatedTURNServerInterface() {}
    107 
    108  // Get an IceServer configuration suitable to add to a PeerConnection.
    109  virtual IceServerConfig GetIceServerConfig() const = 0;
    110 
    111  // Get non-null client endpoint, an endpoint that accepts TURN allocations.
    112  // This shall typically be connected to one or more webrtc endpoint.
    113  virtual EmulatedEndpoint* GetClientEndpoint() const = 0;
    114 
    115  // Returns socket address, which client should use to connect to TURN server
    116  // and do TURN allocation.
    117  virtual SocketAddress GetClientEndpointAddress() const = 0;
    118 
    119  // Get non-null peer endpoint, that is "connected to the internet".
    120  // This shall typically be connected to another TURN server.
    121  virtual EmulatedEndpoint* GetPeerEndpoint() const = 0;
    122 };
    123 
    124 // Provide interface to obtain all required objects to inject network emulation
    125 // layer into PeerConnection. Also contains information about network interfaces
    126 // accessible by PeerConnection.
    127 class EmulatedNetworkManagerInterface
    128    : public webrtc_pc_e2e::PeerNetworkDependencies {
    129 public:
    130  ~EmulatedNetworkManagerInterface() override = default;
    131 
    132  // Returns list of endpoints that are associated with this instance. Pointers
    133  // are guaranteed to be non-null and are owned by NetworkEmulationManager.
    134  virtual std::vector<EmulatedEndpoint*> endpoints() const = 0;
    135 
    136  // Passes summarized network stats for endpoints for this manager into
    137  // specified `stats_callback`. Callback will be executed on network emulation
    138  // internal task queue.
    139  virtual void GetStats(
    140      std::function<void(EmulatedNetworkStats)> stats_callback) const = 0;
    141 };
    142 
    143 enum class TimeMode { kRealTime, kSimulated };
    144 
    145 // Called implicitly when parsing an ABSL_FLAG of type TimeMode.
    146 // from the command line flag value `text`.
    147 // Returns `true` and sets `*mode` on success;
    148 // returns `false` and sets `*error` on failure.
    149 bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error);
    150 
    151 // AbslUnparseFlag returns a textual flag value corresponding to the TimeMode
    152 // `mode`.
    153 std::string AbslUnparseFlag(TimeMode mode);
    154 
    155 // The construction-time configuration options for NetworkEmulationManager.
    156 struct NetworkEmulationManagerConfig {
    157  // The mode of the underlying time controller.
    158  TimeMode time_mode = TimeMode::kRealTime;
    159  // The mode that determines the set of metrics to collect into
    160  // `EmulatedNetworkStats` and `EmulatedNetworkNodeStats`.
    161  EmulatedNetworkStatsGatheringMode stats_gathering_mode =
    162      EmulatedNetworkStatsGatheringMode::kDefault;
    163  // Field trials that can alter the behavior of NetworkEmulationManager.
    164  const FieldTrialsView* field_trials = nullptr;
    165  // If this flag is set, NetworkEmulationManager ignores the sizes of peers'
    166  // DTLS handshake packets when determining when to let the packets through
    167  // a constrained emulated network. Actual hanshake's packet size is ignored
    168  // and a hardcoded fake size is used to compute packet's use of link capacity.
    169  // This is useful for tests that require deterministic packets scheduling
    170  // timing-wise even when the sizes of DTLS hadshake packets are not
    171  // deterministic. This mode make sense only together with the simulated time.
    172  bool fake_dtls_handshake_sizes = false;
    173 };
    174 
    175 // Provides an API for creating and configuring emulated network layer.
    176 // All objects returned by this API are owned by NetworkEmulationManager itself
    177 // and will be deleted when manager will be deleted.
    178 class NetworkEmulationManager {
    179 public:
    180  // Helper struct to simplify creation of simulated network behaviors. Contains
    181  // non-owning pointers as the underlying instances are owned by the manager.
    182  struct SimulatedNetworkNode {
    183    SimulatedNetworkInterface* simulation;
    184    EmulatedNetworkNode* node;
    185 
    186    class Builder {
    187     public:
    188      explicit Builder(NetworkEmulationManager* net) : net_(net) {}
    189      Builder() : net_(nullptr) {}
    190      Builder(const Builder&) = default;
    191      // Sets the config state, note that this will replace any previously set
    192      // values.
    193      Builder& config(BuiltInNetworkBehaviorConfig config);
    194      // If set, `queue_factory` must outlive the Builder.
    195      Builder& queue_factory(NetworkQueueFactory& queue_factory);
    196      Builder& delay_ms(int queue_delay_ms);
    197      Builder& capacity(DataRate link_capacity);
    198      Builder& capacity_kbps(int link_capacity_kbps);
    199      Builder& capacity_Mbps(int link_capacity_Mbps);
    200      Builder& loss(double loss_rate);
    201      Builder& packet_queue_length(int max_queue_length_in_packets);
    202      Builder& delay_standard_deviation_ms(int delay_standard_deviation_ms);
    203      Builder& allow_reordering();
    204      Builder& avg_burst_loss_length(int avg_burst_loss_length);
    205      Builder& packet_overhead(int packet_overhead);
    206      SimulatedNetworkNode Build(uint64_t random_seed = 1) const;
    207      SimulatedNetworkNode Build(NetworkEmulationManager* net,
    208                                 uint64_t random_seed = 1) const;
    209 
    210     private:
    211      NetworkEmulationManager* const net_;
    212      BuiltInNetworkBehaviorConfig config_;
    213      NetworkQueueFactory* queue_factory_ = nullptr;
    214    };
    215  };
    216  virtual ~NetworkEmulationManager() = default;
    217 
    218  virtual TimeController* time_controller() = 0;
    219  // Returns a mode in which underlying time controller operates.
    220  virtual TimeMode time_mode() const = 0;
    221 
    222  // Creates an emulated network node, which represents ideal network with
    223  // unlimited capacity, no delay and no packet loss.
    224  EmulatedNetworkNode* CreateUnconstrainedEmulatedNode() {
    225    return CreateEmulatedNode(BuiltInNetworkBehaviorConfig());
    226  }
    227  // Creates an emulated network node, which represents single network in
    228  // the emulated network layer. Uses default implementation on network behavior
    229  // which can be configured with `config`. `random_seed` can be provided to
    230  // alter randomization behavior.
    231  virtual EmulatedNetworkNode* CreateEmulatedNode(
    232      BuiltInNetworkBehaviorConfig config,
    233      uint64_t random_seed = 1) = 0;
    234  // Creates an emulated network node, which represents single network in
    235  // the emulated network layer. `network_behavior` determines how created node
    236  // will forward incoming packets to the next receiver.
    237  virtual EmulatedNetworkNode* CreateEmulatedNode(
    238      std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
    239 
    240  virtual SimulatedNetworkNode::Builder NodeBuilder() = 0;
    241 
    242  // Creates an emulated endpoint, which represents single network interface on
    243  // the peer's device.
    244  virtual EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) = 0;
    245  // Enable emulated endpoint to make it available for webrtc.
    246  // Caller mustn't enable currently enabled endpoint.
    247  virtual void EnableEndpoint(EmulatedEndpoint* endpoint) = 0;
    248  // Disable emulated endpoint to make it unavailable for webrtc.
    249  // Caller mustn't disable currently disabled endpoint.
    250  virtual void DisableEndpoint(EmulatedEndpoint* endpoint) = 0;
    251 
    252  // Creates a route between endpoints going through specified network nodes.
    253  // This route is single direction only and describe how traffic that was
    254  // sent by network interface `from` have to be delivered to the network
    255  // interface `to`. Return object can be used to remove created route. The
    256  // route must contains at least one network node inside it.
    257  //
    258  // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
    259  // creation of the route have to follow these rules:
    260  //   1. A route consists of a source endpoint, an ordered list of one or
    261  //      more network nodes, and a destination endpoint.
    262  //   2. If (E1, ..., E2) is a route, then E1 != E2.
    263  //      In other words, the source and the destination may not be the same.
    264  //   3. Given two simultaneously existing routes (E1, ..., E2) and
    265  //      (E3, ..., E4), either E1 != E3 or E2 != E4.
    266  //      In other words, there may be at most one route from any given source
    267  //      endpoint to any given destination endpoint.
    268  //   4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
    269  //      and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
    270  //      In other words, a network node may not belong to two routes that lead
    271  //      to the same destination endpoint.
    272  virtual EmulatedRoute* CreateRoute(
    273      EmulatedEndpoint* from,
    274      const std::vector<EmulatedNetworkNode*>& via_nodes,
    275      EmulatedEndpoint* to) = 0;
    276 
    277  // Creates a route over the given `via_nodes` creating the required endpoints
    278  // in the process. The returned EmulatedRoute pointer can be used in other
    279  // calls as a transport route for message or cross traffic.
    280  virtual EmulatedRoute* CreateRoute(
    281      const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
    282 
    283  // Creates a default route between endpoints going through specified network
    284  // nodes. Default route is used for packet when there is no known route for
    285  // packet's destination IP.
    286  //
    287  // This route is single direction only and describe how traffic that was
    288  // sent by network interface `from` have to be delivered in case if routing
    289  // was unspecified. Return object can be used to remove created route. The
    290  // route must contains at least one network node inside it.
    291  //
    292  // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
    293  // creation of the route have to follow these rules:
    294  //   1. A route consists of a source endpoint, an ordered list of one or
    295  //      more network nodes, and a destination endpoint.
    296  //   2. If (E1, ..., E2) is a route, then E1 != E2.
    297  //      In other words, the source and the destination may not be the same.
    298  //   3. Given two simultaneously existing routes (E1, ..., E2) and
    299  //      (E3, ..., E4), either E1 != E3 or E2 != E4.
    300  //      In other words, there may be at most one route from any given source
    301  //      endpoint to any given destination endpoint.
    302  //   4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
    303  //      and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
    304  //      In other words, a network node may not belong to two routes that lead
    305  //      to the same destination endpoint.
    306  //   5. Any node N can belong to only one default route.
    307  virtual EmulatedRoute* CreateDefaultRoute(
    308      EmulatedEndpoint* from,
    309      const std::vector<EmulatedNetworkNode*>& via_nodes,
    310      EmulatedEndpoint* to) = 0;
    311 
    312  // Removes route previously created by CreateRoute(...).
    313  // Caller mustn't call this function with route, that have been already
    314  // removed earlier. Removing a route that is currently in use will lead to
    315  // packets being dropped.
    316  virtual void ClearRoute(EmulatedRoute* route) = 0;
    317 
    318  // Creates a simulated TCP connection using `send_route` for traffic and
    319  // `ret_route` for feedback. This can be used to emulate HTTP cross traffic
    320  // and to implement realistic reliable signaling over lossy networks.
    321  // TODO(srte): Handle clearing of the routes involved.
    322  virtual TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
    323                                          EmulatedRoute* ret_route) = 0;
    324 
    325  // Creates a route over the given `via_nodes`. Returns an object that can be
    326  // used to emulate network load with cross traffic over the created route.
    327  virtual CrossTrafficRoute* CreateCrossTrafficRoute(
    328      const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
    329 
    330  // Starts generating cross traffic using given `generator`. Takes ownership
    331  // over the generator.
    332  virtual CrossTrafficGenerator* StartCrossTraffic(
    333      std::unique_ptr<CrossTrafficGenerator> generator) = 0;
    334 
    335  // Stops generating cross traffic that was started using given `generator`.
    336  // The `generator` shouldn't be used after and the reference may be invalid.
    337  virtual void StopCrossTraffic(CrossTrafficGenerator* generator) = 0;
    338 
    339  // Creates EmulatedNetworkManagerInterface which can be used then to inject
    340  // network emulation layer into PeerConnectionFactory. `endpoints` are
    341  // available network interfaces for PeerConnection. If endpoint is enabled, it
    342  // will be immediately available for PeerConnection, otherwise user will be
    343  // able to enable endpoint later to make it available for PeerConnection.
    344  virtual EmulatedNetworkManagerInterface* absl_nonnull
    345  CreateEmulatedNetworkManagerInterface(
    346      const std::vector<EmulatedEndpoint*>& endpoints) = 0;
    347 
    348  // Passes combined network stats for all specified `endpoints` into specified
    349  // `stats_callback`. Callback will be executed on network emulation
    350  // internal task queue.
    351  virtual void GetStats(
    352      ArrayView<EmulatedEndpoint* const> endpoints,
    353      std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
    354 
    355  // Passes combined network stats for all specified `nodes` into specified
    356  // `stats_callback`. Callback will be executed on network emulation
    357  // internal task queue.
    358  virtual void GetStats(
    359      ArrayView<EmulatedNetworkNode* const> nodes,
    360      std::function<void(EmulatedNetworkNodeStats)> stats_callback) = 0;
    361 
    362  // Create a EmulatedTURNServer.
    363  // The TURN server has 2 endpoints that need to be connected with routes,
    364  // - GetClientEndpoint() - the endpoint that accepts TURN allocations.
    365  // - GetPeerEndpoint() - the endpoint that is "connected to the internet".
    366  virtual EmulatedTURNServerInterface* CreateTURNServer(
    367      EmulatedTURNServerConfig config) = 0;
    368 
    369  // Create a pair of EmulatedNetworkManagerInterfaces connected to each other.
    370  std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
    371  CreateEndpointPairWithTwoWayRoutes(
    372      const BuiltInNetworkBehaviorConfig& config);
    373 };
    374 
    375 }  // namespace webrtc
    376 
    377 #endif  // API_TEST_NETWORK_EMULATION_MANAGER_H_