blob: 6b66d8188afac1d6323c6acc0ea6647f30337a88 [file] [log] [blame]
Artem Titov7bf8c7f2019-03-15 14:00:371/*
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
Artem Titov3e0b65d2020-07-23 00:19:0214#include <functional>
Artem Titov7bf8c7f2019-03-15 14:00:3715#include <memory>
Jonas Oreland97050112020-11-17 20:30:3316#include <string>
Byoungchan Leee2f2cae2022-09-26 14:44:4417#include <utility>
Artem Titov7bf8c7f2019-03-15 14:00:3718#include <vector>
19
Artem Titovcf781282020-07-28 11:45:1620#include "api/array_view.h"
Niels Möller5e7a3ae2021-09-09 13:54:4221#include "api/packet_socket_factory.h"
Andrey Logvinf9ee0e02021-01-14 09:50:3222#include "api/test/network_emulation/cross_traffic.h"
Sebastian Janssoncec24332019-12-04 13:26:5023#include "api/test/network_emulation/network_emulation_interfaces.h"
Niels Möllerf47a7242021-11-22 15:07:3524#include "api/test/peer_network_dependencies.h"
Artem Titov7bf8c7f2019-03-15 14:00:3725#include "api/test/simulated_network.h"
Sebastian Jansson6ce033a2020-01-22 09:12:5626#include "api/test/time_controller.h"
Artem Titov806299e2019-04-12 10:17:1927#include "api/units/timestamp.h"
Artem Titov7bf8c7f2019-03-15 14:00:3728#include "rtc_base/network.h"
Artem Titov1e023392020-01-23 14:46:4529#include "rtc_base/network_constants.h"
Artem Titov7bf8c7f2019-03-15 14:00:3730#include "rtc_base/thread.h"
31
32namespace webrtc {
33
34// This API is still in development and can be changed without prior notice.
35
36// These classes are forward declared here, because they used as handles, to
37// make it possible for client code to operate with these abstractions and build
38// required network configuration. With forward declaration here implementation
39// is more readable, than with interfaces approach and cause user needn't any
40// API methods on these abstractions it is acceptable here.
41
42// EmulatedNetworkNode is an abstraction for some network in the real world,
43// like 3G network between peers, or Wi-Fi for one peer and LTE for another.
44// Multiple networks can be joined into chain emulating a network path from
45// one peer to another.
46class EmulatedNetworkNode;
Sebastian Janssoncec24332019-12-04 13:26:5047
Artem Titov7bf8c7f2019-03-15 14:00:3748// EmulatedRoute is handle for single route from one network interface on one
49// peer device to another network interface on another peer device.
50class EmulatedRoute;
51
Artem Titovb41568b2022-11-11 22:14:3052enum class EmulatedNetworkStatsGatheringMode {
53 // Gather main network stats counters. See more details on which particular
54 // metrics are collected in the `EmulatedNetworkStats` and
55 // `EmulatedNetworkNodeStats` documentation.
56 kDefault,
57 // kDefault + also gather per packet statistics. In this mode more memory
58 // will be used.
59 kDebug
60};
61
Artem Titov7bf8c7f2019-03-15 14:00:3762struct EmulatedEndpointConfig {
63 enum class IpAddressFamily { kIpv4, kIpv6 };
64
Artem Titovd2dd7322021-01-21 16:28:1765 // If specified will be used to name endpoint for logging purposes.
66 absl::optional<std::string> name = absl::nullopt;
Artem Titov7bf8c7f2019-03-15 14:00:3767 IpAddressFamily generated_ip_family = IpAddressFamily::kIpv4;
68 // If specified will be used as IP address for endpoint node. Must be unique
69 // among all created nodes.
70 absl::optional<rtc::IPAddress> ip;
Artem Titove5cc85b2019-03-28 11:11:0971 // Should endpoint be enabled or not, when it will be created.
72 // Enabled endpoints will be available for webrtc to send packets.
73 bool start_as_enabled = true;
Artem Titov1e023392020-01-23 14:46:4574 // Network type which will be used to represent endpoint to WebRTC.
75 rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN;
Artem Titov3d37e062021-02-19 19:26:3276 // Allow endpoint to send packets specifying source IP address different to
77 // the current endpoint IP address. If false endpoint will crash if attempt
78 // to send such packet will be done.
79 bool allow_send_packet_with_different_source_ip = false;
80 // Allow endpoint to receive packet with destination IP address different to
81 // the current endpoint IP address. If false endpoint will crash if such
82 // packet will arrive.
83 bool allow_receive_packets_with_different_dest_ip = false;
Artem Titove5cc85b2019-03-28 11:11:0984};
85
Jonas Oreland97050112020-11-17 20:30:3386struct EmulatedTURNServerConfig {
87 EmulatedEndpointConfig client_config;
88 EmulatedEndpointConfig peer_config;
89};
90
91// EmulatedTURNServer is an abstraction for a TURN server.
92class EmulatedTURNServerInterface {
93 public:
94 struct IceServerConfig {
95 std::string username;
96 std::string password;
97 std::string url;
98 };
99
100 virtual ~EmulatedTURNServerInterface() {}
101
102 // Get an IceServer configuration suitable to add to a PeerConnection.
103 virtual IceServerConfig GetIceServerConfig() const = 0;
104
105 // Get non-null client endpoint, an endpoint that accepts TURN allocations.
106 // This shall typically be connected to one or more webrtc endpoint.
107 virtual EmulatedEndpoint* GetClientEndpoint() const = 0;
108
109 // Returns socket address, which client should use to connect to TURN server
110 // and do TURN allocation.
111 virtual rtc::SocketAddress GetClientEndpointAddress() const = 0;
112
113 // Get non-null peer endpoint, that is "connected to the internet".
114 // This shall typically be connected to another TURN server.
115 virtual EmulatedEndpoint* GetPeerEndpoint() const = 0;
116};
Artem Titov806299e2019-04-12 10:17:19117
Artem Titove5cc85b2019-03-28 11:11:09118// Provide interface to obtain all required objects to inject network emulation
Artem Titov806299e2019-04-12 10:17:19119// layer into PeerConnection. Also contains information about network interfaces
120// accessible by PeerConnection.
Artem Titove5cc85b2019-03-28 11:11:09121class EmulatedNetworkManagerInterface {
122 public:
123 virtual ~EmulatedNetworkManagerInterface() = default;
124
Artem Titovcf781282020-07-28 11:45:16125 // Returns non-null pointer to thread that have to be used as network thread
126 // for WebRTC to properly setup network emulation. Returned thread is owned
127 // by EmulatedNetworkManagerInterface implementation.
Artem Titove5cc85b2019-03-28 11:11:09128 virtual rtc::Thread* network_thread() = 0;
Artem Titovcf781282020-07-28 11:45:16129 // Returns non-null pointer to network manager that have to be injected into
130 // WebRTC to properly setup network emulation. Returned manager is owned by
131 // EmulatedNetworkManagerInterface implementation.
Artem Titove5cc85b2019-03-28 11:11:09132 virtual rtc::NetworkManager* network_manager() = 0;
Niels Möller5e7a3ae2021-09-09 13:54:42133 // Returns non-null pointer to packet socket factory that have to be injected
134 // into WebRTC to properly setup network emulation. Returned factory is owned
135 // by EmulatedNetworkManagerInterface implementation.
136 virtual rtc::PacketSocketFactory* packet_socket_factory() = 0;
Niels Möllerf47a7242021-11-22 15:07:35137 webrtc::webrtc_pc_e2e::PeerNetworkDependencies network_dependencies() {
138 return {network_thread(), network_manager(), packet_socket_factory()};
139 }
Artem Titovcf781282020-07-28 11:45:16140 // Returns list of endpoints that are associated with this instance. Pointers
141 // are guaranteed to be non-null and are owned by NetworkEmulationManager.
142 virtual std::vector<EmulatedEndpoint*> endpoints() const = 0;
Artem Titov806299e2019-04-12 10:17:19143
Artem Titovcf781282020-07-28 11:45:16144 // Passes summarized network stats for endpoints for this manager into
Artem Titov0e61fdd2021-07-25 19:50:14145 // specified `stats_callback`. Callback will be executed on network emulation
Artem Titov5501cef2020-08-04 09:49:19146 // internal task queue.
Artem Titove4c1b1c2022-11-09 10:54:12147 virtual void GetStats(
148 std::function<void(EmulatedNetworkStats)> stats_callback) const = 0;
Artem Titov7bf8c7f2019-03-15 14:00:37149};
150
Sebastian Jansson6ce033a2020-01-22 09:12:56151enum class TimeMode { kRealTime, kSimulated };
152
Björn Tereliusb22cabc2022-06-02 08:51:59153// Called implicitly when parsing an ABSL_FLAG of type TimeMode.
154// from the command line flag value `text`.
155// Returns `true` and sets `*mode` on success;
156// returns `false` and sets `*error` on failure.
157bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error);
158
159// AbslUnparseFlag returns a textual flag value corresponding to the TimeMode
160// `mode`.
161std::string AbslUnparseFlag(TimeMode mode);
162
Artem Titov7bf8c7f2019-03-15 14:00:37163// Provides an API for creating and configuring emulated network layer.
164// All objects returned by this API are owned by NetworkEmulationManager itself
165// and will be deleted when manager will be deleted.
166class NetworkEmulationManager {
167 public:
Sebastian Janssoncec24332019-12-04 13:26:50168 // Helper struct to simplify creation of simulated network behaviors. Contains
169 // non-owning pointers as the underlying instances are owned by the manager.
170 struct SimulatedNetworkNode {
171 SimulatedNetworkInterface* simulation;
172 EmulatedNetworkNode* node;
173
174 class Builder {
175 public:
176 explicit Builder(NetworkEmulationManager* net) : net_(net) {}
Sebastian Janssonce911262019-12-11 18:08:40177 Builder() : net_(nullptr) {}
Sebastian Janssoncec24332019-12-04 13:26:50178 Builder(const Builder&) = default;
179 // Sets the config state, note that this will replace any previously set
180 // values.
181 Builder& config(BuiltInNetworkBehaviorConfig config);
182 Builder& delay_ms(int queue_delay_ms);
183 Builder& capacity_kbps(int link_capacity_kbps);
184 Builder& capacity_Mbps(int link_capacity_Mbps);
185 Builder& loss(double loss_rate);
Sebastian Jansson39272982019-12-11 18:29:57186 Builder& packet_queue_length(int max_queue_length_in_packets);
Mirko Bonadeicad3aed2023-08-04 09:00:24187 Builder& delay_standard_deviation_ms(int delay_standard_deviation_ms);
188 Builder& allow_reordering();
189 Builder& avg_burst_loss_length(int avg_burst_loss_length);
190 Builder& packet_overhead(int packet_overhead);
Artem Titovec9b2812021-01-07 14:49:31191 SimulatedNetworkNode Build(uint64_t random_seed = 1) const;
192 SimulatedNetworkNode Build(NetworkEmulationManager* net,
193 uint64_t random_seed = 1) const;
Sebastian Janssoncec24332019-12-04 13:26:50194
195 private:
196 NetworkEmulationManager* const net_;
197 BuiltInNetworkBehaviorConfig config_;
198 };
199 };
Artem Titov7bf8c7f2019-03-15 14:00:37200 virtual ~NetworkEmulationManager() = default;
201
Sebastian Jansson6ce033a2020-01-22 09:12:56202 virtual TimeController* time_controller() = 0;
Artem Titovcc8a1f82021-01-26 12:58:23203 // Returns a mode in which underlying time controller operates.
204 virtual TimeMode time_mode() const = 0;
Sebastian Jansson6ce033a2020-01-22 09:12:56205
Artem Titov1031a4f2022-07-21 14:04:45206 // Creates an emulated network node, which represents ideal network with
207 // unlimited capacity, no delay and no packet loss.
208 EmulatedNetworkNode* CreateUnconstrainedEmulatedNode() {
209 return CreateEmulatedNode(BuiltInNetworkBehaviorConfig());
210 }
Artem Titov7bf8c7f2019-03-15 14:00:37211 // Creates an emulated network node, which represents single network in
Artem Titovec9b2812021-01-07 14:49:31212 // the emulated network layer. Uses default implementation on network behavior
Artem Titov0e61fdd2021-07-25 19:50:14213 // which can be configured with `config`. `random_seed` can be provided to
Artem Titovec9b2812021-01-07 14:49:31214 // alter randomization behavior.
Artem Titov7bf8c7f2019-03-15 14:00:37215 virtual EmulatedNetworkNode* CreateEmulatedNode(
Artem Titovec9b2812021-01-07 14:49:31216 BuiltInNetworkBehaviorConfig config,
217 uint64_t random_seed = 1) = 0;
218 // Creates an emulated network node, which represents single network in
Artem Titov0e61fdd2021-07-25 19:50:14219 // the emulated network layer. `network_behavior` determines how created node
Artem Titovec9b2812021-01-07 14:49:31220 // will forward incoming packets to the next receiver.
Artem Titov48b1b182019-07-05 11:09:48221 virtual EmulatedNetworkNode* CreateEmulatedNode(
Artem Titov7bf8c7f2019-03-15 14:00:37222 std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
223
Sebastian Janssoncec24332019-12-04 13:26:50224 virtual SimulatedNetworkNode::Builder NodeBuilder() = 0;
225
Artem Titov7bf8c7f2019-03-15 14:00:37226 // Creates an emulated endpoint, which represents single network interface on
227 // the peer's device.
228 virtual EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) = 0;
Artem Titove5cc85b2019-03-28 11:11:09229 // Enable emulated endpoint to make it available for webrtc.
230 // Caller mustn't enable currently enabled endpoint.
231 virtual void EnableEndpoint(EmulatedEndpoint* endpoint) = 0;
232 // Disable emulated endpoint to make it unavailable for webrtc.
233 // Caller mustn't disable currently disabled endpoint.
234 virtual void DisableEndpoint(EmulatedEndpoint* endpoint) = 0;
Artem Titov7bf8c7f2019-03-15 14:00:37235
236 // Creates a route between endpoints going through specified network nodes.
237 // This route is single direction only and describe how traffic that was
Artem Titov0e61fdd2021-07-25 19:50:14238 // sent by network interface `from` have to be delivered to the network
239 // interface `to`. Return object can be used to remove created route. The
Artem Titovff393122019-04-05 09:19:52240 // route must contains at least one network node inside it.
Artem Titov7bf8c7f2019-03-15 14:00:37241 //
Artem Titovff393122019-04-05 09:19:52242 // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
243 // creation of the route have to follow these rules:
244 // 1. A route consists of a source endpoint, an ordered list of one or
245 // more network nodes, and a destination endpoint.
246 // 2. If (E1, ..., E2) is a route, then E1 != E2.
247 // In other words, the source and the destination may not be the same.
248 // 3. Given two simultaneously existing routes (E1, ..., E2) and
249 // (E3, ..., E4), either E1 != E3 or E2 != E4.
250 // In other words, there may be at most one route from any given source
251 // endpoint to any given destination endpoint.
252 // 4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
253 // and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
254 // In other words, a network node may not belong to two routes that lead
255 // to the same destination endpoint.
Artem Titov7bf8c7f2019-03-15 14:00:37256 virtual EmulatedRoute* CreateRoute(
257 EmulatedEndpoint* from,
258 const std::vector<EmulatedNetworkNode*>& via_nodes,
259 EmulatedEndpoint* to) = 0;
Sebastian Janssoncec24332019-12-04 13:26:50260
Artem Titov0e61fdd2021-07-25 19:50:14261 // Creates a route over the given `via_nodes` creating the required endpoints
Sebastian Janssoncec24332019-12-04 13:26:50262 // in the process. The returned EmulatedRoute pointer can be used in other
263 // calls as a transport route for message or cross traffic.
264 virtual EmulatedRoute* CreateRoute(
265 const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
266
Artem Titov3d37e062021-02-19 19:26:32267 // Creates a default route between endpoints going through specified network
268 // nodes. Default route is used for packet when there is no known route for
269 // packet's destination IP.
270 //
271 // This route is single direction only and describe how traffic that was
Artem Titov0e61fdd2021-07-25 19:50:14272 // sent by network interface `from` have to be delivered in case if routing
Artem Titov3d37e062021-02-19 19:26:32273 // was unspecified. Return object can be used to remove created route. The
274 // route must contains at least one network node inside it.
275 //
276 // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
277 // creation of the route have to follow these rules:
278 // 1. A route consists of a source endpoint, an ordered list of one or
279 // more network nodes, and a destination endpoint.
280 // 2. If (E1, ..., E2) is a route, then E1 != E2.
281 // In other words, the source and the destination may not be the same.
282 // 3. Given two simultaneously existing routes (E1, ..., E2) and
283 // (E3, ..., E4), either E1 != E3 or E2 != E4.
284 // In other words, there may be at most one route from any given source
285 // endpoint to any given destination endpoint.
286 // 4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
287 // and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
288 // In other words, a network node may not belong to two routes that lead
289 // to the same destination endpoint.
290 // 5. Any node N can belong to only one default route.
291 virtual EmulatedRoute* CreateDefaultRoute(
292 EmulatedEndpoint* from,
293 const std::vector<EmulatedNetworkNode*>& via_nodes,
294 EmulatedEndpoint* to) = 0;
295
Artem Titov7bf8c7f2019-03-15 14:00:37296 // Removes route previously created by CreateRoute(...).
297 // Caller mustn't call this function with route, that have been already
Andrey Logvinf9ee0e02021-01-14 09:50:32298 // removed earlier. Removing a route that is currently in use will lead to
299 // packets being dropped.
Artem Titov7bf8c7f2019-03-15 14:00:37300 virtual void ClearRoute(EmulatedRoute* route) = 0;
301
Artem Titov0e61fdd2021-07-25 19:50:14302 // Creates a simulated TCP connection using `send_route` for traffic and
303 // `ret_route` for feedback. This can be used to emulate HTTP cross traffic
Sebastian Janssoncec24332019-12-04 13:26:50304 // and to implement realistic reliable signaling over lossy networks.
305 // TODO(srte): Handle clearing of the routes involved.
306 virtual TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
307 EmulatedRoute* ret_route) = 0;
308
Artem Titov0e61fdd2021-07-25 19:50:14309 // Creates a route over the given `via_nodes`. Returns an object that can be
Andrey Logvinf9ee0e02021-01-14 09:50:32310 // used to emulate network load with cross traffic over the created route.
311 virtual CrossTrafficRoute* CreateCrossTrafficRoute(
312 const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
313
Artem Titov0e61fdd2021-07-25 19:50:14314 // Starts generating cross traffic using given `generator`. Takes ownership
Andrey Logvinf9ee0e02021-01-14 09:50:32315 // over the generator.
316 virtual CrossTrafficGenerator* StartCrossTraffic(
317 std::unique_ptr<CrossTrafficGenerator> generator) = 0;
318
Artem Titov0e61fdd2021-07-25 19:50:14319 // Stops generating cross traffic that was started using given `generator`.
320 // The `generator` shouldn't be used after and the reference may be invalid.
Andrey Logvinf9ee0e02021-01-14 09:50:32321 virtual void StopCrossTraffic(CrossTrafficGenerator* generator) = 0;
322
Artem Titove5cc85b2019-03-28 11:11:09323 // Creates EmulatedNetworkManagerInterface which can be used then to inject
Artem Titov0e61fdd2021-07-25 19:50:14324 // network emulation layer into PeerConnection. `endpoints` - are available
Artem Titove5cc85b2019-03-28 11:11:09325 // network interfaces for PeerConnection. If endpoint is enabled, it will be
326 // immediately available for PeerConnection, otherwise user will be able to
327 // enable endpoint later to make it available for PeerConnection.
328 virtual EmulatedNetworkManagerInterface*
329 CreateEmulatedNetworkManagerInterface(
Artem Titov7bf8c7f2019-03-15 14:00:37330 const std::vector<EmulatedEndpoint*>& endpoints) = 0;
Artem Titovcf781282020-07-28 11:45:16331
Artem Titovb41568b2022-11-11 22:14:30332 // Passes combined network stats for all specified `endpoints` into specified
Artem Titov0e61fdd2021-07-25 19:50:14333 // `stats_callback`. Callback will be executed on network emulation
Artem Titov5501cef2020-08-04 09:49:19334 // internal task queue.
Artem Titove4c1b1c2022-11-09 10:54:12335 virtual void GetStats(
336 rtc::ArrayView<EmulatedEndpoint* const> endpoints,
337 std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
Jonas Oreland97050112020-11-17 20:30:33338
Artem Titovb41568b2022-11-11 22:14:30339 // Passes combined network stats for all specified `nodes` into specified
340 // `stats_callback`. Callback will be executed on network emulation
341 // internal task queue.
342 virtual void GetStats(
343 rtc::ArrayView<EmulatedNetworkNode* const> nodes,
344 std::function<void(EmulatedNetworkNodeStats)> stats_callback) = 0;
345
Jonas Oreland97050112020-11-17 20:30:33346 // Create a EmulatedTURNServer.
347 // The TURN server has 2 endpoints that need to be connected with routes,
348 // - GetClientEndpoint() - the endpoint that accepts TURN allocations.
349 // - GetPeerEndpoint() - the endpoint that is "connected to the internet".
350 virtual EmulatedTURNServerInterface* CreateTURNServer(
351 EmulatedTURNServerConfig config) = 0;
Byoungchan Leee2f2cae2022-09-26 14:44:44352
353 // Create a pair of EmulatedNetworkManagerInterfaces connected to each other.
354 std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
355 CreateEndpointPairWithTwoWayRoutes(
356 const BuiltInNetworkBehaviorConfig& config);
Artem Titov7bf8c7f2019-03-15 14:00:37357};
358
359} // namespace webrtc
360
361#endif // API_TEST_NETWORK_EMULATION_MANAGER_H_