phantomlink
looks like a multi-hop Internet path but emulates a virtual end-to-end link
phantomlink
is a tool for studying the impact of a dynamic network environment on the performance of internet protocols and applications. Written in safe Rust, the tool makes use of Linux network namespaces and virtual Ethernet devices to simulate a realistic end-to-end link. Using simple .csv
scenario files, it is possible to define the time-evolving virtual link parameters, including delay, data rate over time, and route changes.
Since the tool just opens two connected vEth in different namespaces, it is possible to combine phantomlink
with any application, such as the well-known tools like netcat or iperf but also your own custom application.
With the ability to reorder, delay, pace, and drop packets, phantomlink
can be used to test network behavior under various scenarios.
- connect two Linux network namespaces over a dynamic virtual link
- specify bottleneck data rate, link delay, and packet reordering
- set the virtual link behavior with a simple input file format
- support for all protocols using ethernet frames โก๏ธ just route the traffic to
phantomlink
Warning
Phantomlink currently only runs on Linux or the Windows Subsystem for Linux (WSL)
- Download the
phantomlink
debian package. - Install the package using (replace [version] with the downloaded version):
sudo apt install ~/downloads/phantomlink_[version].deb
To get started you have to do the following:
- Install
phantomlink
from crates.io:
cargo install phantomlink
To get started you have to do the following:
- Download the
phantomlink
binary. - Make the binary executable using:
chmod +x phantomlink_[version]
- Move the binary to
/bin
.
It is also possible to build the phantomlink
binary from source.
- Git installed on your system.
- Rust and Cargo installed (for building the binary).
- Clone the
phantomlink
repository from GitHub:
git clone https://github.com/robinohs/phantomlink
- Navigate to the cloned repository and build the binary using Cargo:
cargo build --release
- Move the binary to a directory that is in your system's PATH:
sudo mv target/release/phantomlink /bin/
- Clone the
phantomlink
repository from GitHub:
git clone https://github.com/robinohs/phantomlink
- Navigate to the repository and execute the provided
install.sh
script:
cd phantomlink
./install.sh
Verify phantomlink
is correctly installed by running:
phantomlink --version
phantomlink
provides shell completion support for multiple shells, including bash, elvish, fish, PowerShell, zsh, and nushell. It automatically detects your default shell from the environment, so you donโt need to specify it unless you want to.
To generate completions for a specific shell, use the command below. phantomlink
will output the auto-completion code to stdout, allowing you to pipe it into the auto-completion file appropriate for your shell.
phantomlink generate <shell>
- Download the input.csv file from examples.
- Setup the network environment:
phantomlink setup
- Start the main virtual link (assuming the input file is in ~/Downloads):
phantomlink start ~/Downloads/input.csv
- Start an application in the server network namespace:
phantomlink exec server iperf3 -s --port 5000
- Start an application in the client network namespace:
phantomlink exec client iperf3 -c 192.168.66.2 --port 5000
- To get informations about the client or server network namespace you can use:
phantomlink exec <client/server> ifconfig
- After the experiment has finished, you can teardown the network environment:
phantomlink teardown
phantomlink
runs on scenario filesโsimple .csv
files that contain the (time-evolving) parameters of the virtual end-to-end link. This format is motivated by the actual physical variability that an end-to-end connection can be exposed to.
Scenario files define the behavior of the virtual link over time, with parameters such as delay and data rate evolving throughout the experiment.
The RouteID
column indicates whether there is an actual route change or only updated parameters for the current route.
phantomlink
is agnostic of how the scenario file was created and whether the values are realistic. Users can create hand-crafted, synthetic scenarios or use output from any (orbital) dynamics simulator to perform systematic.
Parameters are updated at specified times, creating a step function of changes. For example given the following table:
Time [ms] | RouteID | Delay [ms] | Btldr [Mbps] |
---|---|---|---|
0 | 0 | 41.0 | 80.0 |
11 000 | 0 | 41.2 | 80.2 |
23 000 | 1 | 37.0 | 100.0 |
40 000 | 1 | 36.7 | 101.5 |
60 000 | 1 | 37.0 | 100.1 |
- From
t = 0 ms
, a route with a one-way delay of41.0 ms
and a data rate of80.0 Mbit/s
is used. - At
t = 11 s
, values are updated to41.2 ms
and80.2 Mbit/s
. - At
t = 23 s
, the route changes, as indicated by a newRouteID
.
At its core, the phantomlink
toolchain has a binary that operates in conjunction with Linux network namespaces and virtual Ethernet devices.
The toolchain architecture consists of three network namespaces created with netns
:
- Client Application Namespace
- PhantomLink Binary Namespace
- Server Application Namespace
The client and server namespaces are interconnected with the PhantomLink namespace using two virtual Ethernet devices, resulting in four virtual interfaces. For each virtual Ethernet device:
- One side is moved to the PhantomLink namespace (
sim-veth
) - The other side is moved to the client or server namespace (
veth
)
After moving the interfaces, MAC and IP addresses are assigned. For each namespace except for the PhantomLink namespace:
- A loopback device is added
veth
is configured as the default route to enable traffic flow towardsphantomlink
To allow traffic to flow from the client to the server namespace and vice-versa, the phantomlink
binary forwards packets between the two (sim-veth
) interfaces. This enables applications in the client or server namespace to send and receive traffic over the emulated virtual end-to-end link that evolves according to the scenario file.
The phantomlink
binary is implemented in safe Rust to benefit from Rustโs performance and memory safety. The internal binary structure is depicted in the picture above.
-
Namespace and Raw Sockets:
phantomlink
is started in the PhantomLink namespace.- It binds a raw sockets to the interfaces
sim-veth1
andsim-veth2
each.
-
libpnet crate:
- Using the Rust crate
libpnet
,phantomlink
creates apnet::datalink::Channel
for each interface. - This allows
phantomlink
to send and receive at the data link layer.
- Using the Rust crate
-
OnewayVirtualLink:
- All incoming traffic from the client is processed by a
OnewayVirtualLink
and forwarded to the server. - Similarly, a second
OnewayVirtualLink
instance handles all traffic from the server to the client.
- All incoming traffic from the client is processed by a
The functionality and role of each individual component is explained in the paper.
Don't hesitate to file an issue or contact one of the authors!
Please have a look at the issues or open one if you feel that something is needed.
Any contributions are very welcome!
Phantomlink
is dual-licensed under Apache License, Version 2.0 or MIT License.
This project has received funding from the European Unionโs Horizon 2020 research and innovation programme under the Marie Skลodowska-Curie grant agreement No 101008233 (MISSION).
We look forward to any kind of contributions!
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.
Robin Ohs ๐ป ๐ ๐ค ๐ง ๐ฌ |
Gregory ๐ป ๐ ๐ค ๐ฌ |
Andreas Schmidt ๐ป ๐จ ๐ ๐ค ๐ฌ ๐งโ๐ซ |
This project follows the all-contributors specification. Contributions of any kind are welcome ๐.