Artem Titov | 1c5e63e | 2021-01-07 13:19:18 | [diff] [blame] | 1 | # Network Emulation Framework |
| 2 | |
Artem Titov | 6512af0 | 2021-03-01 16:30:29 | [diff] [blame] | 3 | <?% config.freshness.reviewed = '2021-03-01' %?> |
Artem Titov | 1c5e63e | 2021-01-07 13:19:18 | [diff] [blame] | 4 | |
| 5 | [TOC] |
| 6 | |
| 7 | ## Disclamer |
| 8 | |
| 9 | This documentation explain the implementation details of Network Emulation |
| 10 | Framework. Framework's public APIs are located in: |
| 11 | |
| 12 | * [`/api/test/network_emulation_manager.h`](https://source.chromium.org/search?q=%2Fapi%2Ftest%2Fnetwork_emulation_manager.h) |
| 13 | * [`/api/test/create_network_emulation_manager.h`](https://source.chromium.org/search?q=%2Fapi%2Ftest%2Fcreate_network_emulation_manager.h) |
| 14 | * [`/api/test/network_emulation/network_emulation_interfaces.h`](https://source.chromium.org/search?q=%2Fapi%2Ftest%2Fnetwork_emulation%2Fnetwork_emulation_interfaces.h) |
| 15 | * [`/api/test/simulated_network.h`](https://source.chromium.org/search?q=%2Fapi%2Ftest%2Fsimulated_network.h) |
| 16 | |
| 17 | ## Overview |
| 18 | |
| 19 | Network Emulation Framework provides an ability to emulate network behavior |
| 20 | between different clients, including a WebRTC PeerConnection client. To |
| 21 | configure network behavior, the user can choose different options: |
| 22 | |
| 23 | * Use predefined implementation that can be configured with parameters such as |
| 24 | packet loss, bandwidth, delay, etc. |
| 25 | * Custom implementation |
| 26 | |
| 27 | Conceptually the framework provides the ability to define multiple endpoints and |
| 28 | routes used to connect them. All network related entities are created and |
| 29 | managed by single factory class `webrtc::NetworkEmulationManager` which is |
| 30 | implemented by `webrtc::test::NetworkEmulationManagerImpl` and can work in two |
| 31 | modes: |
| 32 | |
| 33 | * Real time |
| 34 | * Simulated time |
| 35 | |
| 36 | The manager has a dedicated task queue which pipes all packets through all |
| 37 | network routes from senders to receivers. This task queue behaviour is |
| 38 | determined by `webrtc::TimeController`, which is based on either in real time or |
| 39 | simulated time mode. |
| 40 | |
| 41 | The network operates on IP level and supports only UDP for now. |
| 42 | |
| 43 | ## Abstractions |
| 44 | |
| 45 | The framework contains the following public abstractions: |
| 46 | |
| 47 | * `webrtc::NetworkBehaviorInterface` - defines how emulated network should |
| 48 | behave. It operates on packets metadata level and is responsible for telling |
| 49 | which packet at which time have to be delivered to the next receiver. |
| 50 | |
| 51 | * `webrtc::EmulatedIpPacket` - represents a single packet that can be sent or |
| 52 | received via emulated network. It has source and destination address and |
| 53 | payload to transfer. |
| 54 | |
| 55 | * `webrtc::EmulatedNetworkReceiverInterface` - generic packet receiver |
| 56 | interface. |
| 57 | |
| 58 | * `webrtc::EmulatedEndpoint` - primary user facing abstraction of the |
| 59 | framework. It represents a network interface on client's machine. It has its |
| 60 | own unique IP address and can be used to send and receive packets. |
| 61 | |
| 62 | `EmulatedEndpoint` implements `EmulatedNetworkReceiverInterface` to receive |
| 63 | packets from the network and provides an API to send packets to the network |
| 64 | and API to bind other `EmulatedNetworkReceiverInterface` which will be able |
| 65 | to receive packets from the endpoint. `EmulatedEndpoint` interface has the |
| 66 | only implementation: `webrtc::test::EmulatedEndpointImpl`. |
| 67 | |
| 68 | * `webrtc::EmulatedNetworkNode` - represents single network in the real world, |
| 69 | like a 3G network between peers, or Wi-Fi for one peer and LTE for another. |
| 70 | Each `EmulatedNetworkNode` is a single direction connetion and to form |
| 71 | bidirectional connection between endpoints two nodes should be used. |
| 72 | Multiple nodes can be joined into chain emulating a network path from one |
| 73 | peer to another. |
| 74 | |
| 75 | In public API this class is forward declared and fully accessible only by |
| 76 | the framework implementation. |
| 77 | |
| 78 | Internally consist of two parts: `LinkEmulation`, which is responsible for |
| 79 | behavior of current `EmulatedNetworkNode` and `NetworkRouterNode` which is |
| 80 | responsible for routing packets to the next node or to the endpoint. |
| 81 | |
| 82 | * `webrtc::EmulatedRoute` - represents single route from one network interface |
| 83 | on one device to another network interface on another device. |
| 84 | |
| 85 | In public API this class is forward declared and fully accessible only by |
| 86 | the framework implementation. |
| 87 | |
| 88 | It contains start and end endpoint and ordered list of `EmulatedNetworkNode` |
| 89 | which forms the single directional route between those endpoints. |
| 90 | |
| 91 | The framework has also the following private abstractions: |
| 92 | |
| 93 | * `webrtc::test::NetworkRouterNode` - an `EmulatedNetworkReceiverInterface` |
| 94 | that can route incoming packets to the next receiver based on internal IP |
| 95 | routing table. |
| 96 | |
| 97 | * `webrtc::test::LinkEmulation` - an `EmulatedNetworkReceiverInterface` that |
| 98 | can emulate network leg behavior via `webrtc::NetworkBehaviorInterface` |
| 99 | interface. |
| 100 | |
| 101 | For integrating with `webrtc::PeerConnection` there are helper abstractions: |
| 102 | |
| 103 | * `webrtc::EmulatedNetworkManagerInterface` which is implemented by |
| 104 | `webrtc::test::EmulatedNetworkManager` and provides `rtc::Thread` and |
| 105 | `rtc::NetworkManager` for WebRTC to use as network thread for |
| 106 | `PeerConnection` and for `cricket::BasicPortAllocator`. |
| 107 | |
| 108 | Implementation represent framework endpoints as `rtc::Network` to WebRTC. |
| 109 | |
| 110 | ## Architecture |
| 111 | |
| 112 | Let's take a look on how framework's abstractions are connected to each other. |
| 113 | |
| 114 | When the user wants to setup emulated network, first of all, they should create |
| 115 | an instance of `NetworkEmulationManager` using |
| 116 | `webrtc::CreateNetworkEmulationManager(...)` API. Then user should use a manager |
| 117 | to create at least one `EmulatedEndpoint` for each client. After endpoints, the |
| 118 | user should create required `EmulatedNetworkNode`s and with help of manager |
| 119 | chain them into `EmulatedRoute`s conecting desired endpoints. |
| 120 | |
| 121 | Here is a visual overview of the emulated network architecture: |
| 122 | |
| 123 |  |
| 124 | |
| 125 | When network is hooked into `PeerConnection` it is done through network thread |
| 126 | and `NetworkManager`. In the network thread the custom `rtc::SocketServer` is |
| 127 | provided: `webrtc::test::FakeNetworkSocketServer`. This custom socket server |
| 128 | will construct custom sockets (`webrtc::test::FakeNetworkSocket`), which |
| 129 | internally bind themselves to the required endpoint. All packets processing |
| 130 | inside socket have to be done on the `PeerConnection`'s network thread. When |
| 131 | packet is going from `PeerConnection` to the network it's already comming from |
| 132 | the network thread and when it's comming from the emulated network switch from |
| 133 | the Network Emulation Framework internal task queue and `PeerConnection`'s |
| 134 | network thread is done inside socket's `OnPacketReceived(...)` method. |
| 135 | |
| 136 |  |