A python project to help find the optimal MTU values that maximize upload or download speeds between a peer and server. It also helps find bandwidth dead zones caused due to a poor choice of MTUs.
I built the project to help myself find the right MTU values for my WG server and peer. I inadvertently found that the default MTU values for the server and peer in my case put my WG connection in a bandwidth dead zone. [Related reddit post](https://www.reddit.com/r/WireGuard/comments/plm8y7/finding_the_optimal_mtu_for_wg_server_and_wg_peer/).
* Two python scripts need to be running simultaneously, one of the WG server and one on the WG peer. Let's call them *server script* and *peer script*.
* The both scripts use `subprocess.Popen` to run shell commands. The following commands are used and expected to be pre-installed if not already available:
*`ping`
*`iperf3`
*`wg-quick`
*`sed`
* The server script also runs a `flask` server and the peer script uses `requests` to communicate with the flask server.
### How does the server script work?
1. The flow for the server script is defined in the method `MTUFinder.run_server_mode()`.
1. First, a flask server called a `sync_server` is run is the background on a separate process.
* The `sync_server's` listens for requests and commands from the peer script so that they can synchronize with each other.
* The peer script waits for the `sync_server` to be available before running any upload or download tests.
* The peer scripts get the status and MTU of the server script from the `sync_server`.
* The peer script tells the `sync_server` that it is done with its cycling through all of its MTUs and is ready for the server script to change its MTU so that it can start a fresh cycle.
* The `sync_server` informs the peer script that the server script is finished with cycling through all MTUs and that it is going to shut itself down. The peer script uses this signal to shut itself down as well.
1. When the server script receives an `INTIALIZE` signal, it runs the following shell commands
* First, terminate an `iperf3` server process if it is already running.
* Spin down the WG interface
```
wg-quick down wg0
```
* Replace the MTU in the WG conf file with the next MTU in the list
```
# 1421 is the new MTU
sed -i s/MTU.*/MTU = 1421/ /etc/wireguard/wg0.conf
1. If the server has finishing cycling through all of its MTUs and then receives a request from peer script that it is ready for a new cycle, then the server sends a `SHUTDOWN` signal to the peer script via the `sync_server`.
* On start, the peer script checks if the `sync_server` is reachable. Once it is reachable, it sends a `peer/ready` request to the server script.
* The peer script then waits for the `iperf3` server to start on the server side. Once it recognizes that the iperf3 server has started, and then the peer script starts cycling through each of its MTUs.
* For each MTU, the peer script runs an upload and download test using the following command
```
# Upload test
iperf3 -c 10.2.0.1 -J -t 5 -i 5
# Download test
iperf3 -c 10.2.0.1 -J -t 5 -i 5 -R
```
* After each download and upload test, the peer script parses the output and stores the bandwidth results in a bandwidth log file.
* Once the peer script is finished cycling through all of its MTU, it sends another `peer/ready` request to the server script and restarts the whole process again with the next server MTU.
* If the server script is finished cycling through all of its MTUs, then it sends a `SHUTDOWN` signal to the peer script as a reply to the `peer/ready` request. The server shuts down after a short delay as does the peer script.
* Finall the user can check the bandwidth log file to see the results.