first commit

pull/6/head
nitred 3 years ago
commit 5110239526

140
.gitignore vendored

@ -0,0 +1,140 @@
.idea
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/

@ -0,0 +1,5 @@
# Changelog
This project adheres to [Semantic Versioning](http://semver.org/).
## tag: 0.1.0 / 2021-09-14
- First working release

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Nitish K Reddy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,36 @@
.DEFAULT_GOAL := help
help: ## Show available options with this Makefile
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
.PHONY : test
test: ## Run all the tests
test:
python setup.py test
.PHONY : recreate_pyenv
recreate_pyenv: ## Create the python environment. Recreates if the env exists already.
recreate_pyenv:
conda env create --force -f dev_environment.yml
.PHONY : readme_to_rst
readme_to_rst: ## Convert README.md to README.rst for the sake of pip documentation.
readme_to_rst:
m2r --overwrite README.md
.PHONY : upload_test_pypi
upload_test_pypi: ## Build and upload distribution to testpypi server
upload_test_pypi: readme_to_rst
python setup.py bdist_wheel --dist-dir dist && \
twine upload --skip-existing --repository testpypi dist/*
.PHONY : upload_pypi
upload_pypi: ## Build and upload distribution to pypi server
upload_pypi: readme_to_rst
python setup.py bdist_wheel --dist-dir dist && \
twine upload --skip-existing --repository pypi dist/*
.PHONY : lint
lint: ## Run flake8 linter
lint:
flake8 nr_pypackage

@ -0,0 +1,161 @@
# About
A python 3 project to help find optimal MTUs for a Wireguard peer and server.
***Please read the following documentation carefully, especially the WARNING section***.
* This project offers no warranties, therefore do not use in production. Ideally trying using two VMs that are similar to your production setup.
* The project was developed and tested against a WG peer and WG server running Ubuntu 20.04.
# Warning
***WARNING: This project contains scripts that run shell commands using root access. DO NOT USE IN PRODUCTION.***
***WARNING: This project tears down and spins up the Wireguard interface in the order of a thousand times. DO NOT USE IN PRODUCTION.***
That being said, if you're an experienced python developer, please go through the code to verify that it meets your security standards.
# Example Bandwidth Plot
![Bandwidth Plot](./examples/example.png)
# Installation
Install the following on both the WG server and WG peer
* Install `ping`
```bash
# Ubuntu
sudo apt install iputils-ping
```
* Install `iperf3`
```bash
# Source: https://iperf.fr/iperf-download.php
```
* Install `sed`
```bash
# Ubuntu
sudo apt install sed
```
* Install `wg-quick`
```bash
# Should come installed when you install Wireguard
```
* Install the project
```bash
# Use your environment manager of choice like virtualenv or conda to pre-create an environment
# This package has the following dependencies: pandas, matplotlib, pydantic, requests, flask
pip install git+https://github.com/nitred/nr-wg-mtu-finder.git --upgrade
```
# Usage
### Prerequisites
1. Follow the installation instructions above for both WG server and WG peer
1. The project assumes that you already have a working WG installation on both the WG peer and WG server.
1. The project assumes that you already have a WG interface like `wg0`.
1. The project assumes that you already have a WG conf file like `/etc/wireguard/wg0.conf`. ***Take a backup of these files***.
1. Start the WG server script before the WG peer script
### On the WG Server
1. Let your firewall accept connections on port 5201 from IPs within your WG interface. This port is used by the iperf3 server.
```text
# Replace 10.2.0.0/24 with your interface's IP range
ufw allow proto tcp from 10.2.0.0/24 to any port 5201
```
1. Let your firewall accept connections on port 5000 from IPs within your WG interface. This port is used by the flask server.
```text
# Replace 10.2.0.0/24 with your interface's IP range
ufw allow proto tcp from 10.2.0.0/24 to any port 5000
```
1. Add the MTU setting to the WG conf file i.e. `/etc/wireguard/wg0.conf`. Choose any random MTU, it will be replaced by the script anyway:
```text
[Interface]
...
MTU = 1420 # <----- ADD THIS LINE IF NOT ALREADY EXISTS
[Peer]
...
```
1. Start the server script with the following command.
```bash
# Example: The script cycles peer MTUs from 1280 to 1290 in steps of 2
nr-wg-mtu-finder --mode server --mtu-min 1280 --mtu-max 1290 --mtu-step 2 --server-ip 10.2.0.1
```
### On the WG Peer
1. Add the MTU setting to the WG conf file i.e. `/etc/wireguard/wg0.conf`. Choose any random MTU, it will be replaced by the script anyway:
```text
[Interface]
...
MTU = 1420 # <----- ADD THIS LINE IF NOT ALREADY EXISTS
[Peer]
...
```
1. Start the server script with the following command.
```bash
# Example: The script cycles peer MTUs from 1280 to 1290 in steps of 2
nr-wg-mtu-finder --mode peer --mtu-min 1280 --mtu-max 1290 --mtu-step 2 --server-ip 10.2.0.1
```
# How it works?
* 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
```
* Spin up the WG interface
```
wg-quick up wg0
```
* Run iperf3 in server mode
```
iperf3 -s
```
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`.
### How does the server script work?
* 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.
## License
MIT

@ -0,0 +1,530 @@
server_mtu,peer_mtu,upload_rcv_mbps,upload_send_mbps,download_rcv_mbps,download_send_mbps
1280,1280,20.737,21.706,357.680,361.111
1280,1290,14.765,14.975,452.098,454.813
1280,1300,23.878,25.598,441.084,443.618
1280,1310,24.075,26.939,347.185,351.830
1280,1320,22.004,23.316,427.644,431.565
1280,1330,17.544,18.535,358.896,362.756
1280,1340,28.138,28.864,454.672,459.084
1280,1350,32.121,35.410,422.873,427.440
1280,1360,21.791,22.495,357.659,361.045
1280,1370,23.719,24.942,385.588,389.351
1280,1380,21.030,22.956,383.594,388.121
1280,1390,26.248,27.473,386.102,390.638
1280,1400,23.327,24.402,362.564,365.865
1280,1410,16.620,18.005,214.110,216.537
1280,1420,20.246,21.264,374.027,377.710
1280,1430,19.317,20.879,401.521,404.392
1280,1440,22.405,23.765,461.278,464.945
1280,1450,22.616,23.532,371.722,375.896
1280,1460,30.835,31.758,402.537,405.522
1280,1470,21.576,23.630,401.294,403.768
1280,1480,19.692,21.963,422.196,424.874
1280,1490,23.925,25.043,445.973,449.313
1280,1500,19.811,21.244,347.357,350.900
1290,1280,35.771,36.419,359.940,363.446
1290,1290,14.878,15.232,348.246,352.510
1290,1300,20.231,23.871,373.139,376.295
1290,1310,19.999,21.902,370.460,374.907
1290,1320,29.591,31.197,391.984,395.072
1290,1330,18.162,19.165,442.891,446.690
1290,1340,15.905,16.341,440.876,444.084
1290,1350,37.672,41.055,398.939,402.280
1290,1360,24.898,25.466,432.273,436.181
1290,1370,23.111,23.450,395.508,398.189
1290,1380,32.917,34.623,456.721,460.339
1290,1390,21.104,21.620,391.805,396.177
1290,1400,19.260,20.488,382.249,387.130
1290,1410,18.015,19.383,319.812,322.884
1290,1420,15.490,15.991,360.272,363.151
1290,1430,15.413,17.090,317.617,320.606
1290,1440,14.045,14.497,371.438,376.006
1290,1450,20.657,22.855,374.898,379.608
1290,1460,14.877,15.531,368.144,371.331
1290,1470,20.951,22.841,386.190,390.560
1290,1480,18.031,19.109,371.938,375.809
1290,1490,10.701,11.142,344.828,347.840
1290,1500,11.389,11.762,349.931,354.006
1300,1280,13.912,14.242,368.976,372.335
1300,1290,16.644,17.094,378.847,382.403
1300,1300,14.438,15.614,370.253,374.128
1300,1310,18.677,20.098,454.495,457.000
1300,1320,17.009,17.821,493.933,498.110
1300,1330,17.590,19.050,395.682,400.577
1300,1340,16.146,16.976,346.854,350.555
1300,1350,11.636,12.014,378.019,380.927
1300,1360,13.592,13.829,436.955,441.551
1300,1370,17.050,17.547,463.782,467.986
1300,1380,19.308,20.228,384.729,387.436
1300,1390,17.105,18.469,351.818,356.274
1300,1400,18.335,19.690,400.307,404.786
1300,1410,20.246,21.018,477.726,480.120
1300,1420,21.012,21.693,384.489,388.038
1300,1430,17.447,18.867,475.123,477.586
1300,1440,19.544,20.909,375.938,379.178
1300,1450,20.206,21.519,371.267,374.434
1300,1460,13.834,14.221,454.383,457.228
1300,1470,23.662,25.031,377.847,381.450
1300,1480,21.179,22.387,407.507,411.387
1300,1490,22.752,24.140,464.428,468.342
1300,1500,20.137,21.153,407.764,410.721
1310,1280,24.554,25.418,450.094,453.958
1310,1290,32.799,34.445,334.064,338.373
1310,1300,18.880,19.592,450.908,453.416
1310,1310,20.892,21.180,455.059,458.640
1310,1320,11.837,12.268,391.793,394.896
1310,1330,21.693,22.963,398.557,403.305
1310,1340,15.346,15.806,376.985,380.019
1310,1350,10.285,10.521,359.544,363.674
1310,1360,16.308,17.094,436.644,440.071
1310,1370,20.998,21.963,395.040,397.771
1310,1380,25.056,26.647,356.214,360.911
1310,1390,21.321,22.030,363.237,367.955
1310,1400,20.981,21.657,393.627,396.955
1310,1410,20.216,21.856,366.811,370.610
1310,1420,21.114,22.476,358.938,362.589
1310,1430,25.139,27.542,409.005,412.270
1310,1440,23.208,24.030,422.830,427.122
1310,1450,16.493,17.245,429.245,433.080
1310,1460,21.970,23.217,472.925,476.874
1310,1470,16.617,16.947,395.209,397.926
1310,1480,25.573,27.158,389.331,394.088
1310,1490,16.971,17.310,348.305,352.080
1310,1500,20.932,22.227,240.437,245.590
1320,1280,22.555,23.129,347.619,350.488
1320,1290,17.876,18.358,453.234,457.504
1320,1300,21.877,22.309,392.929,396.702
1320,1310,11.208,11.362,463.303,465.583
1320,1320,26.435,27.986,374.603,377.338
1320,1330,21.705,23.432,390.230,393.351
1320,1340,19.203,20.336,416.539,421.234
1320,1350,21.474,22.404,422.342,426.601
1320,1360,19.118,19.786,370.611,375.007
1320,1370,19.497,20.164,359.026,363.846
1320,1380,24.963,25.694,490.747,494.928
1320,1390,23.934,24.712,400.657,404.155
1320,1400,13.130,13.527,380.067,383.977
1320,1410,19.924,20.442,366.813,371.311
1320,1420,23.818,26.556,469.225,473.164
1320,1430,22.512,24.571,406.034,408.337
1320,1440,19.834,21.557,422.145,426.182
1320,1450,16.514,16.869,398.187,402.474
1320,1460,26.042,28.406,370.707,373.627
1320,1470,20.684,21.048,396.256,399.315
1320,1480,21.472,22.134,386.412,389.312
1320,1490,25.173,26.481,375.125,378.413
1320,1500,18.153,18.715,374.005,378.667
1330,1280,20.093,20.868,403.183,407.583
1330,1290,14.580,15.093,344.065,348.965
1330,1300,36.932,39.153,421.392,425.640
1330,1310,24.103,25.515,427.476,430.501
1330,1320,27.390,28.713,482.112,485.813
1330,1330,26.995,28.842,344.585,348.289
1330,1340,16.882,17.327,405.615,409.948
1330,1350,18.251,19.114,371.292,374.626
1330,1360,38.493,39.926,346.768,351.425
1330,1370,15.419,15.928,373.667,377.447
1330,1380,17.419,17.822,395.268,399.278
1330,1390,37.203,40.082,381.329,384.662
1330,1400,28.339,29.352,417.808,420.815
1330,1410,22.143,22.930,312.897,317.504
1330,1420,21.320,22.567,353.455,356.800
1330,1430,22.229,22.991,414.613,418.926
1330,1440,23.547,24.781,409.729,412.782
1330,1450,18.566,19.112,403.791,406.411
1330,1460,46.150,47.614,397.481,401.810
1330,1470,44.288,47.172,364.955,368.548
1330,1480,42.831,45.948,380.175,384.812
1330,1490,43.132,45.724,384.511,388.324
1330,1500,42.910,46.234,377.012,380.413
1340,1280,40.970,43.932,384.070,387.031
1340,1290,43.337,46.401,462.216,465.164
1340,1300,44.782,47.163,375.905,380.045
1340,1310,46.314,49.230,447.525,452.002
1340,1320,43.528,45.867,340.500,345.585
1340,1330,46.099,49.260,366.380,369.329
1340,1340,47.438,49.624,377.512,382.420
1340,1350,42.376,44.671,367.266,371.305
1340,1360,44.972,47.974,374.273,378.996
1340,1370,47.177,49.416,430.201,432.883
1340,1380,42.313,44.696,389.294,392.299
1340,1390,41.436,44.065,454.095,456.777
1340,1400,41.991,44.780,468.950,473.464
1340,1410,47.348,50.726,409.560,414.111
1340,1420,44.536,47.657,486.635,490.753
1340,1430,47.298,50.350,400.488,404.877
1340,1440,43.741,46.008,376.270,379.751
1340,1450,45.536,48.624,290.047,293.968
1340,1460,43.048,46.014,412.570,416.066
1340,1470,43.631,46.594,443.560,446.974
1340,1480,47.208,50.441,401.051,404.399
1340,1490,43.400,46.435,395.608,399.117
1340,1500,44.388,47.259,436.558,440.839
1350,1280,47.135,50.406,331.239,335.948
1350,1290,46.615,49.222,379.506,383.526
1350,1300,47.373,48.545,416.031,420.804
1350,1310,43.271,45.530,428.074,431.355
1350,1320,45.384,48.386,358.959,363.826
1350,1330,43.518,45.720,384.338,388.132
1350,1340,43.564,46.047,350.386,354.929
1350,1350,46.288,48.670,461.497,464.137
1350,1360,43.749,46.049,381.902,385.044
1350,1370,46.941,49.384,413.764,417.004
1350,1380,47.234,50.546,385.482,388.407
1350,1390,42.600,45.327,347.027,351.447
1350,1400,46.934,49.908,401.345,404.402
1350,1410,43.787,46.729,421.364,425.265
1350,1420,43.569,46.089,433.664,437.179
1350,1430,43.453,45.653,418.746,422.000
1350,1440,46.947,49.610,466.914,471.127
1350,1450,46.873,49.084,362.836,366.796
1350,1460,43.974,47.215,345.236,348.277
1350,1470,45.248,47.831,406.501,410.286
1350,1480,44.284,46.920,394.578,397.082
1350,1490,43.874,46.473,391.074,394.978
1350,1500,46.366,49.011,409.418,413.614
1360,1280,46.606,49.073,413.245,417.799
1360,1290,47.184,50.474,373.364,376.969
1360,1300,44.819,47.350,391.410,395.155
1360,1310,43.253,45.511,459.712,462.539
1360,1320,46.719,49.520,386.740,391.172
1360,1330,46.544,49.689,388.020,392.924
1360,1340,47.355,50.336,465.833,469.530
1360,1350,47.016,49.851,296.911,300.098
1360,1360,47.488,49.803,391.799,394.708
1360,1370,47.286,49.702,420.187,423.353
1360,1380,47.794,50.218,362.679,366.414
1360,1390,47.006,49.912,413.945,417.139
1360,1400,47.669,50.107,482.327,486.410
1360,1410,47.351,50.008,455.142,458.010
1360,1420,47.341,50.732,443.398,446.091
1360,1430,47.666,49.890,411.488,415.658
1360,1440,47.137,49.708,489.588,492.898
1360,1450,46.444,49.634,357.538,361.253
1360,1460,43.260,45.937,355.947,359.599
1360,1470,46.710,49.494,372.000,375.415
1360,1480,46.479,49.112,381.690,386.446
1360,1490,46.814,49.443,348.627,352.467
1360,1500,45.926,48.908,489.397,493.555
1370,1280,46.079,49.217,341.215,346.083
1370,1290,46.324,49.333,354.585,358.135
1370,1300,45.948,49.007,325.264,328.921
1370,1310,45.760,48.819,402.222,405.064
1370,1320,41.845,43.926,439.608,443.271
1370,1330,43.544,45.916,362.986,367.136
1370,1340,44.261,47.049,358.705,362.964
1370,1350,47.638,50.211,339.365,342.812
1370,1360,46.072,48.675,344.933,348.692
1370,1370,44.038,46.339,325.494,330.452
1370,1380,46.809,47.801,380.272,383.394
1370,1390,44.417,47.149,398.422,401.229
1370,1400,46.917,49.615,377.657,382.451
1370,1410,47.453,49.923,374.671,378.186
1370,1420,47.578,50.772,457.411,461.173
1370,1430,44.567,47.322,363.931,367.982
1370,1440,43.752,46.977,403.047,405.826
1370,1450,41.883,44.379,382.507,385.486
1370,1460,43.066,45.629,407.615,411.008
1370,1470,47.484,50.120,399.682,402.568
1370,1480,44.844,47.582,402.227,405.917
1370,1490,43.137,45.268,404.491,408.429
1370,1500,39.914,42.826,390.582,393.641
1380,1280,47.054,50.305,375.697,379.837
1380,1290,47.243,50.164,361.712,365.192
1380,1300,43.303,45.753,379.332,382.083
1380,1310,47.166,49.422,373.085,376.683
1380,1320,39.164,41.863,428.841,432.676
1380,1330,44.732,47.537,391.169,394.933
1380,1340,44.493,47.739,483.757,486.409
1380,1350,45.202,47.964,413.985,417.853
1380,1360,40.612,43.343,505.719,509.206
1380,1370,46.763,49.657,369.036,373.138
1380,1380,42.127,45.232,492.606,495.466
1380,1390,44.039,47.137,390.771,394.201
1380,1400,44.837,47.133,419.354,422.332
1380,1410,46.748,48.894,468.828,472.945
1380,1420,45.195,47.964,406.479,410.919
1380,1430,43.412,46.124,419.994,424.013
1380,1440,24.789,25.478,438.730,443.086
1380,1450,46.675,49.598,468.888,471.852
1380,1460,47.209,50.218,420.342,423.961
1380,1470,47.403,50.535,434.837,438.704
1380,1480,44.192,46.901,489.425,491.684
1380,1490,46.814,49.507,439.317,442.391
1380,1500,43.724,46.862,361.066,365.678
1390,1280,42.911,45.507,406.398,410.654
1390,1290,46.795,49.158,364.768,368.048
1390,1300,43.435,46.346,343.994,347.175
1390,1310,44.852,47.265,366.856,370.823
1390,1320,45.848,48.477,389.515,392.635
1390,1330,47.126,49.378,354.994,357.823
1390,1340,42.225,45.023,375.905,379.187
1390,1350,41.725,44.251,382.117,385.106
1390,1360,44.995,47.614,432.551,435.303
1390,1370,43.850,46.213,450.180,453.250
1390,1380,44.317,47.477,402.016,406.168
1390,1390,47.798,50.054,391.631,394.646
1390,1400,44.562,47.465,404.887,408.516
1390,1410,47.752,50.316,393.029,396.575
1390,1420,44.435,46.676,346.765,351.394
1390,1430,42.803,45.276,466.015,469.179
1390,1440,46.385,48.688,430.222,434.576
1390,1450,41.577,44.052,395.744,399.414
1390,1460,45.516,48.374,488.142,490.588
1390,1470,47.181,49.237,393.392,397.167
1390,1480,46.888,49.944,400.137,404.074
1390,1490,43.894,46.102,378.468,381.859
1390,1500,43.907,46.912,395.456,398.778
1400,1280,46.104,48.460,359.593,362.682
1400,1290,43.489,46.718,367.730,370.555
1400,1300,42.327,44.667,416.976,419.959
1400,1310,46.524,49.534,367.941,371.630
1400,1320,42.031,44.275,462.915,466.266
1400,1330,47.160,50.219,317.624,321.332
1400,1340,43.276,45.653,391.912,396.419
1400,1350,45.284,46.558,417.397,420.441
1400,1360,46.616,49.617,485.362,487.805
1400,1370,47.180,50.361,434.505,438.943
1400,1380,46.935,49.849,448.249,452.473
1400,1390,47.865,49.164,441.358,444.339
1400,1400,47.402,50.056,420.547,422.776
1400,1410,0.002,0.116,447.504,450.294
1400,1420,0.002,0.116,487.645,490.899
1400,1430,0.002,0.116,429.633,432.702
1400,1440,0.000,0.116,395.876,400.381
1400,1450,0.002,0.116,392.369,397.164
1400,1460,0.002,0.116,433.513,436.706
1400,1470,0.002,0.116,368.857,372.625
1400,1480,0.002,0.116,382.472,386.120
1400,1490,0.002,0.116,432.998,436.962
1400,1500,0.002,0.116,459.141,462.302
1410,1280,42.989,46.367,442.547,445.498
1410,1290,46.365,49.114,332.335,336.748
1410,1300,47.163,49.815,444.285,448.088
1410,1310,37.480,39.737,333.152,336.146
1410,1320,45.235,48.091,400.229,404.294
1410,1330,46.520,48.732,355.929,359.483
1410,1340,46.149,49.215,398.291,402.335
1410,1350,46.775,49.807,475.651,478.461
1410,1360,46.371,49.075,356.632,359.879
1410,1370,47.111,50.241,364.984,368.451
1410,1380,47.058,49.229,387.655,392.184
1410,1390,43.873,46.028,392.432,396.199
1410,1400,47.655,50.580,98.980,100.422
1410,1410,0.002,0.117,200.022,205.480
1410,1420,0.000,0.117,133.354,136.554
1410,1430,0.002,0.117,305.256,308.611
1410,1440,0.002,0.117,118.640,120.651
1410,1450,0.002,0.117,229.342,234.068
1410,1460,0.000,0.117,97.275,102.622
1410,1470,0.000,0.117,173.014,178.180
1410,1480,0.002,0.117,146.648,152.365
1410,1490,0.000,0.117,196.239,201.461
1410,1500,0.002,0.117,296.940,301.425
1420,1280,44.282,46.680,383.941,387.031
1420,1290,47.374,50.846,354.061,357.530
1420,1300,46.821,49.491,420.790,423.298
1420,1310,41.964,44.671,472.767,475.471
1420,1320,46.513,49.140,343.647,348.050
1420,1330,46.020,48.255,426.009,430.308
1420,1340,46.884,50.156,388.693,392.733
1420,1350,46.894,49.139,444.956,448.583
1420,1360,47.474,50.502,457.816,460.175
1420,1370,44.183,46.871,396.187,400.121
1420,1380,47.738,49.948,380.511,384.911
1420,1390,47.782,50.110,397.849,402.594
1420,1400,47.522,50.287,174.540,178.564
1420,1410,0.002,0.113,223.213,227.528
1420,1420,0.000,0.114,114.871,116.596
1420,1430,0.002,0.114,89.193,90.702
1420,1440,0.002,0.114,251.005,255.191
1420,1450,0.002,0.114,209.876,214.953
1420,1460,0.000,0.114,164.545,168.716
1420,1470,0.000,0.114,200.798,204.326
1420,1480,0.002,0.114,213.964,218.615
1420,1490,0.002,0.114,83.747,87.399
1420,1500,0.002,0.114,96.928,100.633
1430,1280,46.594,49.298,364.530,367.544
1430,1290,43.464,45.882,338.075,343.091
1430,1300,45.593,48.437,401.153,404.951
1430,1310,43.348,45.899,339.975,343.794
1430,1320,42.838,45.082,349.725,354.740
1430,1330,46.583,49.481,401.968,404.797
1430,1340,47.388,49.843,430.043,432.719
1430,1350,47.740,49.912,335.411,339.093
1430,1360,43.761,46.099,358.030,361.012
1430,1370,47.807,50.792,439.497,443.603
1430,1380,46.835,49.789,388.182,391.607
1430,1390,47.802,50.616,501.649,503.888
1430,1400,33.385,36.691,309.061,312.914
1430,1410,0.002,0.113,318.991,323.005
1430,1420,0.002,0.114,78.752,80.259
1430,1430,0.000,0.115,284.417,288.465
1430,1440,0.000,0.115,143.378,144.648
1430,1450,0.002,0.115,200.704,204.512
1430,1460,0.002,0.115,197.756,202.444
1430,1470,0.002,0.115,54.259,56.274
1430,1480,0.002,0.115,328.764,332.320
1430,1490,0.002,0.115,237.407,241.869
1430,1500,0.002,0.115,209.705,213.681
1440,1280,42.074,44.501,406.357,410.903
1440,1290,46.385,49.328,412.699,416.557
1440,1300,44.579,47.315,398.179,401.939
1440,1310,47.453,50.454,408.335,411.398
1440,1320,47.493,50.236,448.419,451.166
1440,1330,47.094,49.362,418.514,422.355
1440,1340,44.521,46.795,401.347,404.221
1440,1350,43.905,47.317,420.556,423.635
1440,1360,47.740,50.280,406.278,410.948
1440,1370,43.983,46.206,386.788,389.480
1440,1380,47.509,50.661,486.314,489.483
1440,1390,39.922,42.185,429.133,432.874
1440,1400,47.557,49.842,243.538,248.218
1440,1410,0.002,0.117,122.151,124.606
1440,1420,0.002,0.114,208.142,212.654
1440,1430,0.002,0.115,331.651,335.410
1440,1440,0.000,0.115,368.121,372.060
1440,1450,0.000,0.115,110.465,114.932
1440,1460,0.002,0.115,295.627,299.630
1440,1470,0.002,0.115,220.861,225.743
1440,1480,0.002,0.115,66.580,68.696
1440,1490,0.000,0.115,217.765,221.178
1440,1500,0.000,0.115,209.181,213.834
1450,1280,46.175,51.393,327.369,332.297
1450,1290,47.383,52.631,410.074,412.935
1450,1300,46.219,51.205,349.221,353.839
1450,1310,47.379,53.607,408.749,411.850
1450,1320,47.561,53.506,390.459,393.384
1450,1330,47.133,52.920,344.771,349.021
1450,1340,45.378,50.812,374.855,379.606
1450,1350,46.815,52.474,376.302,379.277
1450,1360,45.127,50.739,428.621,431.826
1450,1370,44.750,49.395,423.730,428.298
1450,1380,44.515,49.418,447.861,452.282
1450,1390,43.850,45.547,440.119,444.401
1450,1400,46.162,51.550,262.339,267.229
1450,1410,0.002,0.163,230.559,235.369
1450,1420,0.002,0.164,241.786,246.065
1450,1430,0.002,0.165,289.238,292.380
1450,1440,0.000,0.166,295.184,299.770
1450,1450,37.938,40.089,19.853,21.148
1450,1460,41.110,44.118,8.600,9.087
1450,1470,38.742,40.944,17.073,19.671
1450,1480,38.429,40.829,12.197,13.490
1450,1490,33.310,34.765,9.039,9.531
1450,1500,38.997,41.829,8.692,8.962
1460,1280,43.509,47.887,451.779,454.999
1460,1290,42.584,47.424,485.101,488.950
1460,1300,44.387,49.034,509.394,512.145
1460,1310,47.436,53.484,496.417,499.625
1460,1320,40.401,45.530,462.502,465.300
1460,1330,46.312,50.769,425.412,428.465
1460,1340,45.085,51.029,469.161,471.493
1460,1350,47.656,51.454,534.816,537.539
1460,1360,47.056,51.987,408.523,412.333
1460,1370,45.192,50.867,395.506,399.835
1460,1380,47.665,51.989,72.788,73.925
1460,1390,47.783,52.151,516.615,520.145
1460,1400,46.494,51.692,134.252,137.861
1460,1410,0.002,0.163,285.622,290.335
1460,1420,0.002,0.164,95.419,96.763
1460,1430,0.002,0.165,334.494,337.763
1460,1440,0.000,0.166,283.256,286.536
1460,1450,39.177,42.046,12.626,13.806
1460,1460,37.356,39.928,14.528,16.183
1460,1470,37.672,40.817,7.526,8.012
1460,1480,37.605,39.720,7.288,7.780
1460,1490,40.869,43.941,15.936,18.340
1460,1500,37.051,39.339,7.276,7.906
1470,1280,43.361,48.700,411.680,416.226
1470,1290,42.887,48.857,506.792,510.003
1470,1300,46.596,51.133,443.212,446.737
1470,1310,42.926,47.469,339.886,344.595
1470,1320,44.740,50.418,444.137,447.900
1470,1330,47.335,51.939,406.395,410.032
1470,1340,47.501,52.632,417.795,422.391
1470,1350,46.801,51.984,470.573,473.815
1470,1360,44.855,50.619,379.513,383.737
1470,1370,47.153,51.313,374.597,378.850
1470,1380,43.283,49.471,402.552,406.743
1470,1390,47.852,52.600,361.754,364.733
1470,1400,47.142,51.334,321.534,325.217
1470,1410,0.002,0.169,262.148,265.686
1470,1420,0.002,0.164,225.842,229.224
1470,1430,0.000,0.165,271.334,275.624
1470,1440,0.002,0.166,220.754,225.484
1470,1450,35.827,37.228,7.388,8.015
1470,1460,38.572,40.810,6.776,7.244
1470,1470,41.453,44.202,8.394,9.355
1470,1480,36.455,38.593,8.378,9.045
1470,1490,39.469,42.335,9.610,10.446
1470,1500,26.675,27.821,8.623,9.425
1480,1280,41.379,47.404,386.087,389.791
1480,1290,47.116,52.921,372.710,376.986
1480,1300,43.591,48.554,441.520,444.398
1480,1310,44.763,49.952,419.570,422.882
1480,1320,46.656,52.989,475.603,479.614
1480,1330,39.676,45.840,358.419,362.049
1480,1340,43.780,49.423,384.640,388.027
1480,1350,47.621,52.558,518.682,521.277
1480,1360,45.319,51.154,446.399,450.470
1480,1370,45.888,50.197,442.774,445.599
1480,1380,47.074,53.112,529.057,532.387
1480,1390,47.739,52.665,392.739,397.445
1480,1400,47.815,51.894,154.429,156.783
1480,1410,0.002,0.163,59.773,60.546
1480,1420,0.002,0.164,272.349,277.010
1480,1430,0.002,0.165,100.013,101.855
1480,1440,0.002,0.166,269.456,272.814
1480,1450,38.350,41.022,18.162,20.158
1480,1460,36.197,38.729,8.087,8.880
1480,1470,38.112,40.513,10.513,11.547
1480,1480,38.360,40.842,15.024,16.395
1480,1490,38.981,41.590,15.305,17.625
1480,1500,34.672,36.138,17.419,19.126
1490,1280,47.125,51.977,376.595,381.008
1490,1290,46.827,51.365,435.473,439.195
1490,1300,39.790,45.828,356.390,361.268
1490,1310,47.100,52.067,356.747,360.857
1490,1320,46.172,50.884,435.792,440.180
1490,1330,47.401,53.229,407.655,411.750
1490,1340,46.210,50.751,371.442,375.445
1490,1350,46.564,51.538,381.831,384.885
1490,1360,38.658,44.039,452.159,455.878
1490,1370,38.329,42.662,401.988,406.855
1490,1380,40.187,43.111,485.876,488.792
1490,1390,36.109,41.719,445.349,449.066
1490,1400,38.746,44.183,153.668,155.962
1490,1410,0.002,0.163,57.885,58.614
1490,1420,0.002,0.164,217.184,221.444
1490,1430,0.002,0.165,81.774,82.932
1490,1440,0.000,0.166,246.123,250.524
1490,1450,37.250,41.590,7.605,8.391
1490,1460,36.461,38.006,11.789,12.702
1490,1470,37.499,40.086,12.297,13.536
1490,1480,39.907,42.394,7.958,8.584
1490,1490,37.969,42.336,12.657,14.180
1490,1500,35.612,37.221,9.601,10.411
1500,1280,45.898,51.074,381.356,385.851
1500,1290,46.155,51.279,447.346,450.937
1500,1300,47.081,53.054,455.394,458.827
1500,1310,45.750,50.849,472.877,476.415
1500,1320,46.826,51.109,403.040,407.518
1500,1330,41.654,46.665,384.903,388.987
1500,1340,45.405,50.982,422.598,425.510
1500,1350,47.062,53.009,367.359,372.020
1500,1360,33.811,38.690,432.314,436.518
1500,1370,33.253,38.044,460.230,464.132
1500,1380,46.189,50.603,448.953,451.416
1500,1390,46.487,50.754,405.929,408.691
1500,1400,47.207,51.748,280.478,284.156
1500,1410,0.000,0.163,164.343,169.619
1500,1420,0.000,0.164,233.938,238.295
1500,1430,0.000,0.165,144.196,147.032
1500,1440,0.002,0.166,134.236,135.898
1500,1450,37.032,39.162,7.104,7.501
1500,1460,40.111,42.441,9.935,11.265
1500,1470,37.090,38.387,14.869,16.335
1500,1480,40.173,43.382,17.456,19.305
1500,1490,39.987,42.603,14.543,16.166
1500,1500,40.490,43.420,11.558,12.189
1 server_mtu peer_mtu upload_rcv_mbps upload_send_mbps download_rcv_mbps download_send_mbps
2 1280 1280 20.737 21.706 357.680 361.111
3 1280 1290 14.765 14.975 452.098 454.813
4 1280 1300 23.878 25.598 441.084 443.618
5 1280 1310 24.075 26.939 347.185 351.830
6 1280 1320 22.004 23.316 427.644 431.565
7 1280 1330 17.544 18.535 358.896 362.756
8 1280 1340 28.138 28.864 454.672 459.084
9 1280 1350 32.121 35.410 422.873 427.440
10 1280 1360 21.791 22.495 357.659 361.045
11 1280 1370 23.719 24.942 385.588 389.351
12 1280 1380 21.030 22.956 383.594 388.121
13 1280 1390 26.248 27.473 386.102 390.638
14 1280 1400 23.327 24.402 362.564 365.865
15 1280 1410 16.620 18.005 214.110 216.537
16 1280 1420 20.246 21.264 374.027 377.710
17 1280 1430 19.317 20.879 401.521 404.392
18 1280 1440 22.405 23.765 461.278 464.945
19 1280 1450 22.616 23.532 371.722 375.896
20 1280 1460 30.835 31.758 402.537 405.522
21 1280 1470 21.576 23.630 401.294 403.768
22 1280 1480 19.692 21.963 422.196 424.874
23 1280 1490 23.925 25.043 445.973 449.313
24 1280 1500 19.811 21.244 347.357 350.900
25 1290 1280 35.771 36.419 359.940 363.446
26 1290 1290 14.878 15.232 348.246 352.510
27 1290 1300 20.231 23.871 373.139 376.295
28 1290 1310 19.999 21.902 370.460 374.907
29 1290 1320 29.591 31.197 391.984 395.072
30 1290 1330 18.162 19.165 442.891 446.690
31 1290 1340 15.905 16.341 440.876 444.084
32 1290 1350 37.672 41.055 398.939 402.280
33 1290 1360 24.898 25.466 432.273 436.181
34 1290 1370 23.111 23.450 395.508 398.189
35 1290 1380 32.917 34.623 456.721 460.339
36 1290 1390 21.104 21.620 391.805 396.177
37 1290 1400 19.260 20.488 382.249 387.130
38 1290 1410 18.015 19.383 319.812 322.884
39 1290 1420 15.490 15.991 360.272 363.151
40 1290 1430 15.413 17.090 317.617 320.606
41 1290 1440 14.045 14.497 371.438 376.006
42 1290 1450 20.657 22.855 374.898 379.608
43 1290 1460 14.877 15.531 368.144 371.331
44 1290 1470 20.951 22.841 386.190 390.560
45 1290 1480 18.031 19.109 371.938 375.809
46 1290 1490 10.701 11.142 344.828 347.840
47 1290 1500 11.389 11.762 349.931 354.006
48 1300 1280 13.912 14.242 368.976 372.335
49 1300 1290 16.644 17.094 378.847 382.403
50 1300 1300 14.438 15.614 370.253 374.128
51 1300 1310 18.677 20.098 454.495 457.000
52 1300 1320 17.009 17.821 493.933 498.110
53 1300 1330 17.590 19.050 395.682 400.577
54 1300 1340 16.146 16.976 346.854 350.555
55 1300 1350 11.636 12.014 378.019 380.927
56 1300 1360 13.592 13.829 436.955 441.551
57 1300 1370 17.050 17.547 463.782 467.986
58 1300 1380 19.308 20.228 384.729 387.436
59 1300 1390 17.105 18.469 351.818 356.274
60 1300 1400 18.335 19.690 400.307 404.786
61 1300 1410 20.246 21.018 477.726 480.120
62 1300 1420 21.012 21.693 384.489 388.038
63 1300 1430 17.447 18.867 475.123 477.586
64 1300 1440 19.544 20.909 375.938 379.178
65 1300 1450 20.206 21.519 371.267 374.434
66 1300 1460 13.834 14.221 454.383 457.228
67 1300 1470 23.662 25.031 377.847 381.450
68 1300 1480 21.179 22.387 407.507 411.387
69 1300 1490 22.752 24.140 464.428 468.342
70 1300 1500 20.137 21.153 407.764 410.721
71 1310 1280 24.554 25.418 450.094 453.958
72 1310 1290 32.799 34.445 334.064 338.373
73 1310 1300 18.880 19.592 450.908 453.416
74 1310 1310 20.892 21.180 455.059 458.640
75 1310 1320 11.837 12.268 391.793 394.896
76 1310 1330 21.693 22.963 398.557 403.305
77 1310 1340 15.346 15.806 376.985 380.019
78 1310 1350 10.285 10.521 359.544 363.674
79 1310 1360 16.308 17.094 436.644 440.071
80 1310 1370 20.998 21.963 395.040 397.771
81 1310 1380 25.056 26.647 356.214 360.911
82 1310 1390 21.321 22.030 363.237 367.955
83 1310 1400 20.981 21.657 393.627 396.955
84 1310 1410 20.216 21.856 366.811 370.610
85 1310 1420 21.114 22.476 358.938 362.589
86 1310 1430 25.139 27.542 409.005 412.270
87 1310 1440 23.208 24.030 422.830 427.122
88 1310 1450 16.493 17.245 429.245 433.080
89 1310 1460 21.970 23.217 472.925 476.874
90 1310 1470 16.617 16.947 395.209 397.926
91 1310 1480 25.573 27.158 389.331 394.088
92 1310 1490 16.971 17.310 348.305 352.080
93 1310 1500 20.932 22.227 240.437 245.590
94 1320 1280 22.555 23.129 347.619 350.488
95 1320 1290 17.876 18.358 453.234 457.504
96 1320 1300 21.877 22.309 392.929 396.702
97 1320 1310 11.208 11.362 463.303 465.583
98 1320 1320 26.435 27.986 374.603 377.338
99 1320 1330 21.705 23.432 390.230 393.351
100 1320 1340 19.203 20.336 416.539 421.234
101 1320 1350 21.474 22.404 422.342 426.601
102 1320 1360 19.118 19.786 370.611 375.007
103 1320 1370 19.497 20.164 359.026 363.846
104 1320 1380 24.963 25.694 490.747 494.928
105 1320 1390 23.934 24.712 400.657 404.155
106 1320 1400 13.130 13.527 380.067 383.977
107 1320 1410 19.924 20.442 366.813 371.311
108 1320 1420 23.818 26.556 469.225 473.164
109 1320 1430 22.512 24.571 406.034 408.337
110 1320 1440 19.834 21.557 422.145 426.182
111 1320 1450 16.514 16.869 398.187 402.474
112 1320 1460 26.042 28.406 370.707 373.627
113 1320 1470 20.684 21.048 396.256 399.315
114 1320 1480 21.472 22.134 386.412 389.312
115 1320 1490 25.173 26.481 375.125 378.413
116 1320 1500 18.153 18.715 374.005 378.667
117 1330 1280 20.093 20.868 403.183 407.583
118 1330 1290 14.580 15.093 344.065 348.965
119 1330 1300 36.932 39.153 421.392 425.640
120 1330 1310 24.103 25.515 427.476 430.501
121 1330 1320 27.390 28.713 482.112 485.813
122 1330 1330 26.995 28.842 344.585 348.289
123 1330 1340 16.882 17.327 405.615 409.948
124 1330 1350 18.251 19.114 371.292 374.626
125 1330 1360 38.493 39.926 346.768 351.425
126 1330 1370 15.419 15.928 373.667 377.447
127 1330 1380 17.419 17.822 395.268 399.278
128 1330 1390 37.203 40.082 381.329 384.662
129 1330 1400 28.339 29.352 417.808 420.815
130 1330 1410 22.143 22.930 312.897 317.504
131 1330 1420 21.320 22.567 353.455 356.800
132 1330 1430 22.229 22.991 414.613 418.926
133 1330 1440 23.547 24.781 409.729 412.782
134 1330 1450 18.566 19.112 403.791 406.411
135 1330 1460 46.150 47.614 397.481 401.810
136 1330 1470 44.288 47.172 364.955 368.548
137 1330 1480 42.831 45.948 380.175 384.812
138 1330 1490 43.132 45.724 384.511 388.324
139 1330 1500 42.910 46.234 377.012 380.413
140 1340 1280 40.970 43.932 384.070 387.031
141 1340 1290 43.337 46.401 462.216 465.164
142 1340 1300 44.782 47.163 375.905 380.045
143 1340 1310 46.314 49.230 447.525 452.002
144 1340 1320 43.528 45.867 340.500 345.585
145 1340 1330 46.099 49.260 366.380 369.329
146 1340 1340 47.438 49.624 377.512 382.420
147 1340 1350 42.376 44.671 367.266 371.305
148 1340 1360 44.972 47.974 374.273 378.996
149 1340 1370 47.177 49.416 430.201 432.883
150 1340 1380 42.313 44.696 389.294 392.299
151 1340 1390 41.436 44.065 454.095 456.777
152 1340 1400 41.991 44.780 468.950 473.464
153 1340 1410 47.348 50.726 409.560 414.111
154 1340 1420 44.536 47.657 486.635 490.753
155 1340 1430 47.298 50.350 400.488 404.877
156 1340 1440 43.741 46.008 376.270 379.751
157 1340 1450 45.536 48.624 290.047 293.968
158 1340 1460 43.048 46.014 412.570 416.066
159 1340 1470 43.631 46.594 443.560 446.974
160 1340 1480 47.208 50.441 401.051 404.399
161 1340 1490 43.400 46.435 395.608 399.117
162 1340 1500 44.388 47.259 436.558 440.839
163 1350 1280 47.135 50.406 331.239 335.948
164 1350 1290 46.615 49.222 379.506 383.526
165 1350 1300 47.373 48.545 416.031 420.804
166 1350 1310 43.271 45.530 428.074 431.355
167 1350 1320 45.384 48.386 358.959 363.826
168 1350 1330 43.518 45.720 384.338 388.132
169 1350 1340 43.564 46.047 350.386 354.929
170 1350 1350 46.288 48.670 461.497 464.137
171 1350 1360 43.749 46.049 381.902 385.044
172 1350 1370 46.941 49.384 413.764 417.004
173 1350 1380 47.234 50.546 385.482 388.407
174 1350 1390 42.600 45.327 347.027 351.447
175 1350 1400 46.934 49.908 401.345 404.402
176 1350 1410 43.787 46.729 421.364 425.265
177 1350 1420 43.569 46.089 433.664 437.179
178 1350 1430 43.453 45.653 418.746 422.000
179 1350 1440 46.947 49.610 466.914 471.127
180 1350 1450 46.873 49.084 362.836 366.796
181 1350 1460 43.974 47.215 345.236 348.277
182 1350 1470 45.248 47.831 406.501 410.286
183 1350 1480 44.284 46.920 394.578 397.082
184 1350 1490 43.874 46.473 391.074 394.978
185 1350 1500 46.366 49.011 409.418 413.614
186 1360 1280 46.606 49.073 413.245 417.799
187 1360 1290 47.184 50.474 373.364 376.969
188 1360 1300 44.819 47.350 391.410 395.155
189 1360 1310 43.253 45.511 459.712 462.539
190 1360 1320 46.719 49.520 386.740 391.172
191 1360 1330 46.544 49.689 388.020 392.924
192 1360 1340 47.355 50.336 465.833 469.530
193 1360 1350 47.016 49.851 296.911 300.098
194 1360 1360 47.488 49.803 391.799 394.708
195 1360 1370 47.286 49.702 420.187 423.353
196 1360 1380 47.794 50.218 362.679 366.414
197 1360 1390 47.006 49.912 413.945 417.139
198 1360 1400 47.669 50.107 482.327 486.410
199 1360 1410 47.351 50.008 455.142 458.010
200 1360 1420 47.341 50.732 443.398 446.091
201 1360 1430 47.666 49.890 411.488 415.658
202 1360 1440 47.137 49.708 489.588 492.898
203 1360 1450 46.444 49.634 357.538 361.253
204 1360 1460 43.260 45.937 355.947 359.599
205 1360 1470 46.710 49.494 372.000 375.415
206 1360 1480 46.479 49.112 381.690 386.446
207 1360 1490 46.814 49.443 348.627 352.467
208 1360 1500 45.926 48.908 489.397 493.555
209 1370 1280 46.079 49.217 341.215 346.083
210 1370 1290 46.324 49.333 354.585 358.135
211 1370 1300 45.948 49.007 325.264 328.921
212 1370 1310 45.760 48.819 402.222 405.064
213 1370 1320 41.845 43.926 439.608 443.271
214 1370 1330 43.544 45.916 362.986 367.136
215 1370 1340 44.261 47.049 358.705 362.964
216 1370 1350 47.638 50.211 339.365 342.812
217 1370 1360 46.072 48.675 344.933 348.692
218 1370 1370 44.038 46.339 325.494 330.452
219 1370 1380 46.809 47.801 380.272 383.394
220 1370 1390 44.417 47.149 398.422 401.229
221 1370 1400 46.917 49.615 377.657 382.451
222 1370 1410 47.453 49.923 374.671 378.186
223 1370 1420 47.578 50.772 457.411 461.173
224 1370 1430 44.567 47.322 363.931 367.982
225 1370 1440 43.752 46.977 403.047 405.826
226 1370 1450 41.883 44.379 382.507 385.486
227 1370 1460 43.066 45.629 407.615 411.008
228 1370 1470 47.484 50.120 399.682 402.568
229 1370 1480 44.844 47.582 402.227 405.917
230 1370 1490 43.137 45.268 404.491 408.429
231 1370 1500 39.914 42.826 390.582 393.641
232 1380 1280 47.054 50.305 375.697 379.837
233 1380 1290 47.243 50.164 361.712 365.192
234 1380 1300 43.303 45.753 379.332 382.083
235 1380 1310 47.166 49.422 373.085 376.683
236 1380 1320 39.164 41.863 428.841 432.676
237 1380 1330 44.732 47.537 391.169 394.933
238 1380 1340 44.493 47.739 483.757 486.409
239 1380 1350 45.202 47.964 413.985 417.853
240 1380 1360 40.612 43.343 505.719 509.206
241 1380 1370 46.763 49.657 369.036 373.138
242 1380 1380 42.127 45.232 492.606 495.466
243 1380 1390 44.039 47.137 390.771 394.201
244 1380 1400 44.837 47.133 419.354 422.332
245 1380 1410 46.748 48.894 468.828 472.945
246 1380 1420 45.195 47.964 406.479 410.919
247 1380 1430 43.412 46.124 419.994 424.013
248 1380 1440 24.789 25.478 438.730 443.086
249 1380 1450 46.675 49.598 468.888 471.852
250 1380 1460 47.209 50.218 420.342 423.961
251 1380 1470 47.403 50.535 434.837 438.704
252 1380 1480 44.192 46.901 489.425 491.684
253 1380 1490 46.814 49.507 439.317 442.391
254 1380 1500 43.724 46.862 361.066 365.678
255 1390 1280 42.911 45.507 406.398 410.654
256 1390 1290 46.795 49.158 364.768 368.048
257 1390 1300 43.435 46.346 343.994 347.175
258 1390 1310 44.852 47.265 366.856 370.823
259 1390 1320 45.848 48.477 389.515 392.635
260 1390 1330 47.126 49.378 354.994 357.823
261 1390 1340 42.225 45.023 375.905 379.187
262 1390 1350 41.725 44.251 382.117 385.106
263 1390 1360 44.995 47.614 432.551 435.303
264 1390 1370 43.850 46.213 450.180 453.250
265 1390 1380 44.317 47.477 402.016 406.168
266 1390 1390 47.798 50.054 391.631 394.646
267 1390 1400 44.562 47.465 404.887 408.516
268 1390 1410 47.752 50.316 393.029 396.575
269 1390 1420 44.435 46.676 346.765 351.394
270 1390 1430 42.803 45.276 466.015 469.179
271 1390 1440 46.385 48.688 430.222 434.576
272 1390 1450 41.577 44.052 395.744 399.414
273 1390 1460 45.516 48.374 488.142 490.588
274 1390 1470 47.181 49.237 393.392 397.167
275 1390 1480 46.888 49.944 400.137 404.074
276 1390 1490 43.894 46.102 378.468 381.859
277 1390 1500 43.907 46.912 395.456 398.778
278 1400 1280 46.104 48.460 359.593 362.682
279 1400 1290 43.489 46.718 367.730 370.555
280 1400 1300 42.327 44.667 416.976 419.959
281 1400 1310 46.524 49.534 367.941 371.630
282 1400 1320 42.031 44.275 462.915 466.266
283 1400 1330 47.160 50.219 317.624 321.332
284 1400 1340 43.276 45.653 391.912 396.419
285 1400 1350 45.284 46.558 417.397 420.441
286 1400 1360 46.616 49.617 485.362 487.805
287 1400 1370 47.180 50.361 434.505 438.943
288 1400 1380 46.935 49.849 448.249 452.473
289 1400 1390 47.865 49.164 441.358 444.339
290 1400 1400 47.402 50.056 420.547 422.776
291 1400 1410 0.002 0.116 447.504 450.294
292 1400 1420 0.002 0.116 487.645 490.899
293 1400 1430 0.002 0.116 429.633 432.702
294 1400 1440 0.000 0.116 395.876 400.381
295 1400 1450 0.002 0.116 392.369 397.164
296 1400 1460 0.002 0.116 433.513 436.706
297 1400 1470 0.002 0.116 368.857 372.625
298 1400 1480 0.002 0.116 382.472 386.120
299 1400 1490 0.002 0.116 432.998 436.962
300 1400 1500 0.002 0.116 459.141 462.302
301 1410 1280 42.989 46.367 442.547 445.498
302 1410 1290 46.365 49.114 332.335 336.748
303 1410 1300 47.163 49.815 444.285 448.088
304 1410 1310 37.480 39.737 333.152 336.146
305 1410 1320 45.235 48.091 400.229 404.294
306 1410 1330 46.520 48.732 355.929 359.483
307 1410 1340 46.149 49.215 398.291 402.335
308 1410 1350 46.775 49.807 475.651 478.461
309 1410 1360 46.371 49.075 356.632 359.879
310 1410 1370 47.111 50.241 364.984 368.451
311 1410 1380 47.058 49.229 387.655 392.184
312 1410 1390 43.873 46.028 392.432 396.199
313 1410 1400 47.655 50.580 98.980 100.422
314 1410 1410 0.002 0.117 200.022 205.480
315 1410 1420 0.000 0.117 133.354 136.554
316 1410 1430 0.002 0.117 305.256 308.611
317 1410 1440 0.002 0.117 118.640 120.651
318 1410 1450 0.002 0.117 229.342 234.068
319 1410 1460 0.000 0.117 97.275 102.622
320 1410 1470 0.000 0.117 173.014 178.180
321 1410 1480 0.002 0.117 146.648 152.365
322 1410 1490 0.000 0.117 196.239 201.461
323 1410 1500 0.002 0.117 296.940 301.425
324 1420 1280 44.282 46.680 383.941 387.031
325 1420 1290 47.374 50.846 354.061 357.530
326 1420 1300 46.821 49.491 420.790 423.298
327 1420 1310 41.964 44.671 472.767 475.471
328 1420 1320 46.513 49.140 343.647 348.050
329 1420 1330 46.020 48.255 426.009 430.308
330 1420 1340 46.884 50.156 388.693 392.733
331 1420 1350 46.894 49.139 444.956 448.583
332 1420 1360 47.474 50.502 457.816 460.175
333 1420 1370 44.183 46.871 396.187 400.121
334 1420 1380 47.738 49.948 380.511 384.911
335 1420 1390 47.782 50.110 397.849 402.594
336 1420 1400 47.522 50.287 174.540 178.564
337 1420 1410 0.002 0.113 223.213 227.528
338 1420 1420 0.000 0.114 114.871 116.596
339 1420 1430 0.002 0.114 89.193 90.702
340 1420 1440 0.002 0.114 251.005 255.191
341 1420 1450 0.002 0.114 209.876 214.953
342 1420 1460 0.000 0.114 164.545 168.716
343 1420 1470 0.000 0.114 200.798 204.326
344 1420 1480 0.002 0.114 213.964 218.615
345 1420 1490 0.002 0.114 83.747 87.399
346 1420 1500 0.002 0.114 96.928 100.633
347 1430 1280 46.594 49.298 364.530 367.544
348 1430 1290 43.464 45.882 338.075 343.091
349 1430 1300 45.593 48.437 401.153 404.951
350 1430 1310 43.348 45.899 339.975 343.794
351 1430 1320 42.838 45.082 349.725 354.740
352 1430 1330 46.583 49.481 401.968 404.797
353 1430 1340 47.388 49.843 430.043 432.719
354 1430 1350 47.740 49.912 335.411 339.093
355 1430 1360 43.761 46.099 358.030 361.012
356 1430 1370 47.807 50.792 439.497 443.603
357 1430 1380 46.835 49.789 388.182 391.607
358 1430 1390 47.802 50.616 501.649 503.888
359 1430 1400 33.385 36.691 309.061 312.914
360 1430 1410 0.002 0.113 318.991 323.005
361 1430 1420 0.002 0.114 78.752 80.259
362 1430 1430 0.000 0.115 284.417 288.465
363 1430 1440 0.000 0.115 143.378 144.648
364 1430 1450 0.002 0.115 200.704 204.512
365 1430 1460 0.002 0.115 197.756 202.444
366 1430 1470 0.002 0.115 54.259 56.274
367 1430 1480 0.002 0.115 328.764 332.320
368 1430 1490 0.002 0.115 237.407 241.869
369 1430 1500 0.002 0.115 209.705 213.681
370 1440 1280 42.074 44.501 406.357 410.903
371 1440 1290 46.385 49.328 412.699 416.557
372 1440 1300 44.579 47.315 398.179 401.939
373 1440 1310 47.453 50.454 408.335 411.398
374 1440 1320 47.493 50.236 448.419 451.166
375 1440 1330 47.094 49.362 418.514 422.355
376 1440 1340 44.521 46.795 401.347 404.221
377 1440 1350 43.905 47.317 420.556 423.635
378 1440 1360 47.740 50.280 406.278 410.948
379 1440 1370 43.983 46.206 386.788 389.480
380 1440 1380 47.509 50.661 486.314 489.483
381 1440 1390 39.922 42.185 429.133 432.874
382 1440 1400 47.557 49.842 243.538 248.218
383 1440 1410 0.002 0.117 122.151 124.606
384 1440 1420 0.002 0.114 208.142 212.654
385 1440 1430 0.002 0.115 331.651 335.410
386 1440 1440 0.000 0.115 368.121 372.060
387 1440 1450 0.000 0.115 110.465 114.932
388 1440 1460 0.002 0.115 295.627 299.630
389 1440 1470 0.002 0.115 220.861 225.743
390 1440 1480 0.002 0.115 66.580 68.696
391 1440 1490 0.000 0.115 217.765 221.178
392 1440 1500 0.000 0.115 209.181 213.834
393 1450 1280 46.175 51.393 327.369 332.297
394 1450 1290 47.383 52.631 410.074 412.935
395 1450 1300 46.219 51.205 349.221 353.839
396 1450 1310 47.379 53.607 408.749 411.850
397 1450 1320 47.561 53.506 390.459 393.384
398 1450 1330 47.133 52.920 344.771 349.021
399 1450 1340 45.378 50.812 374.855 379.606
400 1450 1350 46.815 52.474 376.302 379.277
401 1450 1360 45.127 50.739 428.621 431.826
402 1450 1370 44.750 49.395 423.730 428.298
403 1450 1380 44.515 49.418 447.861 452.282
404 1450 1390 43.850 45.547 440.119 444.401
405 1450 1400 46.162 51.550 262.339 267.229
406 1450 1410 0.002 0.163 230.559 235.369
407 1450 1420 0.002 0.164 241.786 246.065
408 1450 1430 0.002 0.165 289.238 292.380
409 1450 1440 0.000 0.166 295.184 299.770
410 1450 1450 37.938 40.089 19.853 21.148
411 1450 1460 41.110 44.118 8.600 9.087
412 1450 1470 38.742 40.944 17.073 19.671
413 1450 1480 38.429 40.829 12.197 13.490
414 1450 1490 33.310 34.765 9.039 9.531
415 1450 1500 38.997 41.829 8.692 8.962
416 1460 1280 43.509 47.887 451.779 454.999
417 1460 1290 42.584 47.424 485.101 488.950
418 1460 1300 44.387 49.034 509.394 512.145
419 1460 1310 47.436 53.484 496.417 499.625
420 1460 1320 40.401 45.530 462.502 465.300
421 1460 1330 46.312 50.769 425.412 428.465
422 1460 1340 45.085 51.029 469.161 471.493
423 1460 1350 47.656 51.454 534.816 537.539
424 1460 1360 47.056 51.987 408.523 412.333
425 1460 1370 45.192 50.867 395.506 399.835
426 1460 1380 47.665 51.989 72.788 73.925
427 1460 1390 47.783 52.151 516.615 520.145
428 1460 1400 46.494 51.692 134.252 137.861
429 1460 1410 0.002 0.163 285.622 290.335
430 1460 1420 0.002 0.164 95.419 96.763
431 1460 1430 0.002 0.165 334.494 337.763
432 1460 1440 0.000 0.166 283.256 286.536
433 1460 1450 39.177 42.046 12.626 13.806
434 1460 1460 37.356 39.928 14.528 16.183
435 1460 1470 37.672 40.817 7.526 8.012
436 1460 1480 37.605 39.720 7.288 7.780
437 1460 1490 40.869 43.941 15.936 18.340
438 1460 1500 37.051 39.339 7.276 7.906
439 1470 1280 43.361 48.700 411.680 416.226
440 1470 1290 42.887 48.857 506.792 510.003
441 1470 1300 46.596 51.133 443.212 446.737
442 1470 1310 42.926 47.469 339.886 344.595
443 1470 1320 44.740 50.418 444.137 447.900
444 1470 1330 47.335 51.939 406.395 410.032
445 1470 1340 47.501 52.632 417.795 422.391
446 1470 1350 46.801 51.984 470.573 473.815
447 1470 1360 44.855 50.619 379.513 383.737
448 1470 1370 47.153 51.313 374.597 378.850
449 1470 1380 43.283 49.471 402.552 406.743
450 1470 1390 47.852 52.600 361.754 364.733
451 1470 1400 47.142 51.334 321.534 325.217
452 1470 1410 0.002 0.169 262.148 265.686
453 1470 1420 0.002 0.164 225.842 229.224
454 1470 1430 0.000 0.165 271.334 275.624
455 1470 1440 0.002 0.166 220.754 225.484
456 1470 1450 35.827 37.228 7.388 8.015
457 1470 1460 38.572 40.810 6.776 7.244
458 1470 1470 41.453 44.202 8.394 9.355
459 1470 1480 36.455 38.593 8.378 9.045
460 1470 1490 39.469 42.335 9.610 10.446
461 1470 1500 26.675 27.821 8.623 9.425
462 1480 1280 41.379 47.404 386.087 389.791
463 1480 1290 47.116 52.921 372.710 376.986
464 1480 1300 43.591 48.554 441.520 444.398
465 1480 1310 44.763 49.952 419.570 422.882
466 1480 1320 46.656 52.989 475.603 479.614
467 1480 1330 39.676 45.840 358.419 362.049
468 1480 1340 43.780 49.423 384.640 388.027
469 1480 1350 47.621 52.558 518.682 521.277
470 1480 1360 45.319 51.154 446.399 450.470
471 1480 1370 45.888 50.197 442.774 445.599
472 1480 1380 47.074 53.112 529.057 532.387
473 1480 1390 47.739 52.665 392.739 397.445
474 1480 1400 47.815 51.894 154.429 156.783
475 1480 1410 0.002 0.163 59.773 60.546
476 1480 1420 0.002 0.164 272.349 277.010
477 1480 1430 0.002 0.165 100.013 101.855
478 1480 1440 0.002 0.166 269.456 272.814
479 1480 1450 38.350 41.022 18.162 20.158
480 1480 1460 36.197 38.729 8.087 8.880
481 1480 1470 38.112 40.513 10.513 11.547
482 1480 1480 38.360 40.842 15.024 16.395
483 1480 1490 38.981 41.590 15.305 17.625
484 1480 1500 34.672 36.138 17.419 19.126
485 1490 1280 47.125 51.977 376.595 381.008
486 1490 1290 46.827 51.365 435.473 439.195
487 1490 1300 39.790 45.828 356.390 361.268
488 1490 1310 47.100 52.067 356.747 360.857
489 1490 1320 46.172 50.884 435.792 440.180
490 1490 1330 47.401 53.229 407.655 411.750
491 1490 1340 46.210 50.751 371.442 375.445
492 1490 1350 46.564 51.538 381.831 384.885
493 1490 1360 38.658 44.039 452.159 455.878
494 1490 1370 38.329 42.662 401.988 406.855
495 1490 1380 40.187 43.111 485.876 488.792
496 1490 1390 36.109 41.719 445.349 449.066
497 1490 1400 38.746 44.183 153.668 155.962
498 1490 1410 0.002 0.163 57.885 58.614
499 1490 1420 0.002 0.164 217.184 221.444
500 1490 1430 0.002 0.165 81.774 82.932
501 1490 1440 0.000 0.166 246.123 250.524
502 1490 1450 37.250 41.590 7.605 8.391
503 1490 1460 36.461 38.006 11.789 12.702
504 1490 1470 37.499 40.086 12.297 13.536
505 1490 1480 39.907 42.394 7.958 8.584
506 1490 1490 37.969 42.336 12.657 14.180
507 1490 1500 35.612 37.221 9.601 10.411
508 1500 1280 45.898 51.074 381.356 385.851
509 1500 1290 46.155 51.279 447.346 450.937
510 1500 1300 47.081 53.054 455.394 458.827
511 1500 1310 45.750 50.849 472.877 476.415
512 1500 1320 46.826 51.109 403.040 407.518
513 1500 1330 41.654 46.665 384.903 388.987
514 1500 1340 45.405 50.982 422.598 425.510
515 1500 1350 47.062 53.009 367.359 372.020
516 1500 1360 33.811 38.690 432.314 436.518
517 1500 1370 33.253 38.044 460.230 464.132
518 1500 1380 46.189 50.603 448.953 451.416
519 1500 1390 46.487 50.754 405.929 408.691
520 1500 1400 47.207 51.748 280.478 284.156
521 1500 1410 0.000 0.163 164.343 169.619
522 1500 1420 0.000 0.164 233.938 238.295
523 1500 1430 0.000 0.165 144.196 147.032
524 1500 1440 0.002 0.166 134.236 135.898
525 1500 1450 37.032 39.162 7.104 7.501
526 1500 1460 40.111 42.441 9.935 11.265
527 1500 1470 37.090 38.387 14.869 16.335
528 1500 1480 40.173 43.382 17.456 19.305
529 1500 1490 39.987 42.603 14.543 16.166
530 1500 1500 40.490 43.420 11.558 12.189

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

@ -0,0 +1 @@
__version__ = "0.1.0"

@ -0,0 +1,105 @@
import argparse
import signal
import time
import sys
from pydantic import BaseModel, StrictStr, StrictInt, root_validator
from typing_extensions import Literal
from .mtu_finder import MTUFinder
def signal_handler(sig, frame):
"""Handle ctrl+c interrupt.
Without this handler, everytime a ctrl+c interrupt is received, the server shutdowns and
proceeds to the next iteration in the loop rather than exiting the program altogether.
"""
print("************Received CTRL-C. Will exit in 1 second************")
time.sleep(1)
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
class ArgsModel(BaseModel):
mode: Literal["server", "peer"]
mtu_min: int
mtu_max: int
mtu_step: int
server_ip: StrictStr
server_port: int = 5000
interface: StrictStr = "wg0"
conf_file: StrictStr = "/etc/wireguard/wg0.conf"
@root_validator(pre=False)
def validate(cls, values):
"""Generic validations."""
mtu_min, mtu_max, mtu_step = (
values.get("mtu_min", None),
values.get("mtu_max", None),
values.get("mtu_step", None),
)
if not (1280 <= mtu_min <= 1500):
raise ValueError(f"mtu_min: {mtu_min} must be in range [1280, 1500].")
if not (1280 <= mtu_max <= 1500):
raise ValueError(f"mtu_max: {mtu_max} must be in range [1280, 1500].")
if not (mtu_min <= mtu_max):
raise ValueError(f"mtu_min: {mtu_min} must be less than or equal to mtu_max: {mtu_max}")
return values
class Config:
orm_mode = True
def setup_args():
"""Setup args."""
parser = argparse.ArgumentParser(
description="nr-wg-mtu-finder - Helps find the optimal Wireguard MTU between Server and Peer."
)
parser.add_argument(
"--mode",
help=(
"Mode is 'server' if you are running this script on the WG Server, "
"else the mode is 'peer' if you are running this script on the WG Peer."
),
required=True,
)
parser.add_argument(
"--mtu-min", help="Min MTU.", required=True,
)
parser.add_argument(
"--mtu-max", help="Max MTU.", required=True,
)
parser.add_argument(
"--mtu-step", help="By how much to increment the MTU between loops.", required=True,
)
parser.add_argument(
"--server-ip", help="The IP address of the WG server and flask server.", required=True,
)
parser.add_argument(
"--server-port", help="The port for the flask server.", required=False, default=5000,
)
parser.add_argument(
"--interface", help="The WG interface name. Default: 'wg0'", required=False, default="wg0"
)
parser.add_argument(
"--conf-file",
help="The WG interface name. Default: '/etc/wireguard/wg0.conf'",
required=False,
default="/etc/wireguard/wg0.conf",
)
args = parser.parse_args()
return args
def run():
args = setup_args()
args = ArgsModel.from_orm(args)
MTUFinder(**args.dict())

@ -0,0 +1,397 @@
import subprocess
import time
import sys
import json
from datetime import datetime
import requests
# Set to either client or server
from nr_wg_mtu_finder.sync_server import run_sync_server
from nr_wg_mtu_finder.plot import plot_log
class MTUFinder(object):
def __init__(
self, mode, server_ip, server_port, interface, conf_file, mtu_max, mtu_min, mtu_step
):
"""Init."""
self.mode = mode
self.server_ip = server_ip
self.server_port = server_port
self.interface = interface
self.conf_file = conf_file
self.mtu_max = mtu_max
self.mtu_min = mtu_min
self.mtu_step = mtu_step
self.peer_mtu = None
self.server_mtu = None
self.current_mtu = None
self.log_filename = (
f"wg_mtu_finder_{self.mode}_{datetime.now().strftime('%Y%m%dT%H%M%S')}.csv"
)
self.plot_filename = (
f"wg_mtu_finder_{self.mode}_{datetime.now().strftime('%Y%m%dT%H%M%S')}.png"
)
if self.mode == "server":
self.run_server_mode()
elif self.mode == "peer":
self.run_peer_mode()
else:
raise NotImplementedError()
def create_log(self):
"""Create an empty CSV log file with the headers.
This log file will be used to store all bandwidth information for each MTU test.
"""
msg = f"Creating log file: {self.log_filename}"
print(f"{msg:<50s}", end=": ")
with open(self.log_filename, "w") as f:
f.write(
f"server_mtu,"
f"peer_mtu,"
f"upload_rcv_mbps,"
f"upload_send_mbps,"
f"download_rcv_mbps,"
f"download_send_mbps\n"
)
print("SUCCESS")
def append_log_with_bandwidth_info(self, up_rcv_bps, up_snd_bps, down_rcv_bps, down_snd_bps):
"""Append the bandwidth information to the log file."""
if self.mode == "server":
raise NotImplementedError()
msg = f"Appending log for MTU: {self.current_mtu}"
print(f"{msg:<50s}", end=": ")
with open(self.log_filename, "a") as f:
f.write(
f"{self.server_mtu},"
f"{self.peer_mtu},"
f"{up_rcv_bps / 1000000:0.3f},"
f"{up_snd_bps / 1000000:0.3f},"
f"{down_rcv_bps / 1000000:0.3f},"
f"{down_snd_bps / 1000000:0.3f}\n"
)
print("SUCCESS")
def wg_quick_down(self):
"""Spin down the interface using wg-quick."""
msg = "WG Interface Down"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["wg-quick", "down", f"{self.interface}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
def wg_quick_up(self):
"""Spin up the interface using wg-quick."""
msg = "WG Interface Up"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["wg-quick", "up", f"{self.interface}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
def __validate_conf_file(self):
"""Validate that a line `MTU =` exists in the wireguard conf."""
with open(self.conf_file, "r") as f:
for line in f.readlines():
if line.startswith("MTU ="):
return
# If no line starts with "MTU = ", then raise an error.
raise ValueError(
f"Expected to find a line that begins with 'MTU =' in {self.conf_file} file."
)
def update_mtu_in_conf_file(self):
"""Update the MTU setting in the WG Conf.
Find a line that starts with 'MTU =***' and replace it with 'MTU = <current_mtu>'
"""
self.__validate_conf_file()
msg = f"Setting MTU to {self.current_mtu} in /etc/wireguard/wg0.conf"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["sed", "-i", f"s/MTU.*/MTU = {self.current_mtu}/", f"{self.conf_file}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
def run_iperf3_upload_test(self):
"""Run iperf3 upload test."""
msg = f"Running peer upload"
print(f"{msg:<50s}", end=": ")
command = ["iperf3", "-c", f"{self.server_ip}", "-J", "-t", "5", "-i", "5"]
# print(f"command: {' '.join(command)}")
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,
)
# Wait iperf3 test to be done.
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
# load iperf3 output json which results from the -J flag
output = json.loads(stdout)
return (
output["end"]["streams"][0]["receiver"]["bits_per_second"],
output["end"]["streams"][0]["sender"]["bits_per_second"],
)
def run_iperf3_download_test(self):
"""Run iperf3 upload test."""
msg = f"Running peer download"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["iperf3", "-c", f"{self.server_ip}", "-J", "-t", "5", "-i", "5", "-R"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
# Wait iperf3 test to be done.
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
# load iperf3 output json which results from the -J flag
output = json.loads(stdout)
return (
output["end"]["streams"][0]["receiver"]["bits_per_second"],
output["end"]["streams"][0]["sender"]["bits_per_second"],
)
def __peer_mode__wait_for_server_init(self):
"""Get server mtu.
Raises:
- requests.Timeout, requests.ConnectionError or KeyError if there is something wrong
with the Flask server running on the WG server.
"""
while True:
msg = f"Waiting for server init and status"
print(f"{msg:<50s}", end=": ")
try:
resp = requests.get(
f"http://{self.server_ip}:{self.server_port}/server/status",
verify=False,
timeout=5,
)
server_mtu, server_status = resp.json()["server_mtu"], resp.json()["server_status"]
if (server_status == "INITIALIZED") or (server_status == "SHUTDOWN"):
print(f"SUCCESS, SERVER_MTU: {server_mtu}, SERVER_STATUS: {server_status}")
return server_mtu, server_status
else:
print(f"FAILED, SERVER_STATUS: {server_status}, Retrying...")
time.sleep(1)
continue
except requests.exceptions.ConnectTimeout:
print("FAILED, ConnectTimeout, Retrying...")
time.sleep(1)
continue
def __peer_mode__send_server_peer_ready(self):
"""Send restart signal to flask server and get back server status."""
msg = f"Send peer ready for next loop to server"
print(f"{msg:<50s}", end=": ")
resp = requests.get(
f"http://{self.server_ip}:{self.server_port}/peer/ready", verify=False, timeout=5
)
server_mtu, server_status = resp.json()["server_mtu"], resp.json()["server_status"]
print("SUCCESS")
return server_mtu, server_status
def __peer_mode__ping_server(self):
"""Ping server to reestablish connection between peer and server.
After server interface is spun down and spun up again, the peer is not guaranteed to be
connected to the server. Therefore we force a ping to make sure peer sends packets
on this network.
"""
msg = f"Pinging server to establish connection"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["ping", "-c", "1", f"{self.server_ip}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = process.communicate()
print("SUCCESS" if process.returncode == 0 else f"FAILED with code {process.returncode}")
def run_peer_mode(self):
"""Run all steps for peer mode.
1. Peer is the one that logs bandwidth
"""
self.create_log()
while True:
# Ping IP address of server to flush connection
self.__peer_mode__ping_server()
# Tell server that peer is ready for next loop.
self.__peer_mode__send_server_peer_ready()
# Ping IP address of server to flush connection
self.__peer_mode__ping_server()
# Start a fresh loop of cycling through all peer MTUs
# At start, find what the current server_mtu is.
self.server_mtu, server_status = self.__peer_mode__wait_for_server_init()
if server_status == "INITIALIZED":
pass
elif server_status == "SHUTDOWN":
print(f"Server has shutdown... Shutting down peer script.")
print(f"Check final bandwidth log: {self.log_filename}")
plot_log(log_filename=self.log_filename, plot_filename=self.plot_filename)
print(f"Check final bandwidth plot: {self.plot_filename}")
sys.exit(0)
else:
raise NotImplementedError()
for current_mtu in range(self.mtu_min, self.mtu_max + 1, self.mtu_step):
if self.server_mtu is None:
raise NotImplementedError()
self.current_mtu = current_mtu
self.peer_mtu = current_mtu
print("-" * 80)
self.wg_quick_down()
self.update_mtu_in_conf_file()
self.wg_quick_up()
# Wait a short while after interface is spun up.
time.sleep(1)
up_rcv_bps, up_snd_bps = self.run_iperf3_upload_test()
time.sleep(1)
down_rcv_bps, down_snd_bps = self.run_iperf3_download_test()
self.append_log_with_bandwidth_info(
up_rcv_bps, up_snd_bps, down_rcv_bps, down_snd_bps
)
def run_iperf3_server_test(self):
"""Run iperf3 upload test."""
msg = f"Running iperf3 server"
print(f"{msg:<50s}", end=": ")
process = subprocess.Popen(
["iperf3", "-s"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
time.sleep(1)
print("SUCCESS")
return process
def run_server_mode(self):
"""Run all steps for server mode."""
import multiprocessing as mp
pool = mp.Pool(1)
manager = mp.Manager()
to_server_queue = manager.Queue(5)
from_server_queue = manager.Queue(5)
pool.apply_async(
run_sync_server,
kwds={
"host": self.server_ip,
"port": self.server_port,
"to_server_queue": to_server_queue,
"from_server_queue": from_server_queue,
},
)
iperf3_server_process = None
mtu_range = list(range(self.mtu_min, self.mtu_max + 1, self.mtu_step))
mtu_range_iter = iter(mtu_range)
while True:
print("-" * 80)
# Wait for init command from sync server
sync_server_status = from_server_queue.get(block=True)
# Any time a message is received from the sync_server, the iperf3 server
# must be terminated.
if iperf3_server_process:
iperf3_server_process.terminate()
if sync_server_status == "INITIALIZE":
# We receive INITIALIZE from the peer but sometimes the connection is spun down too
# quickly before a response could be sent. Therefore we'll wait for a little while
# until the request has been handled.
time.sleep(1)
try:
self.current_mtu = next(mtu_range_iter)
except StopIteration:
# Done with cycling through all MTUs
# Send Shutdown signal to the sync_server
# And go back to waiting for shutdown signal from sync_server
to_server_queue.put(
{"server_mtu": self.server_mtu, "server_status": "SHUTDOWN"}
)
continue
self.server_mtu = self.current_mtu
self.wg_quick_down()
self.update_mtu_in_conf_file()
self.wg_quick_up()
iperf3_server_process = self.run_iperf3_server_test()
# Wait a short while after interface is spun up.
time.sleep(1)
to_server_queue.put({"server_mtu": self.server_mtu, "server_status": "INITIALIZED"})
# Now wait for peer to ping our server
# Peer will get a response that tells it that the iperf3 server is ready with
# the current_mtu
# Peer will start cycling through all of its MTUs
# Peer will send another "init" command if it needs the server to
elif sync_server_status == "SHUTDOWN":
time.sleep(2)
print("Received 'SHUTDOWN' signal from sync server. Shutting down.")
sys.exit(0)
else:
raise NotImplementedError()
# Code should not reach here.
raise NotImplementedError()

@ -0,0 +1,84 @@
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
def plot_log(log_filename, plot_filename):
f, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))
df = pd.read_csv(log_filename)
ax = axes[0, 0]
dfx = df.pivot(index="server_mtu", columns="peer_mtu", values="upload_rcv_mbps",)
sns.heatmap(
dfx.values,
linewidth=0.5,
ax=ax,
cmap="Greens_r",
xticklabels=list(dfx.index),
yticklabels=list(dfx.columns),
)
ax.tick_params(axis="x", rotation=45)
ax.tick_params(axis="y", rotation=0)
ax.set(xlabel="Server MTU", ylabel="Peer MTU")
ax.set_title("Upload Rcv Bandwidth (Mbps)")
ax.invert_yaxis()
ax = axes[0, 1]
dfx = df.pivot(index="server_mtu", columns="peer_mtu", values="upload_send_mbps")
sns.heatmap(
dfx.values,
linewidth=0.5,
ax=ax,
cmap="Greens_r",
xticklabels=list(dfx.index),
yticklabels=list(dfx.columns),
)
ax.tick_params(axis="x", rotation=45)
ax.tick_params(axis="y", rotation=0)
ax.set(xlabel="Server MTU", ylabel="Peer MTU")
ax.set_title("Upload Send Bandwidth (Mbps)")
ax.invert_yaxis()
ax = axes[1, 0]
dfx = df.pivot(index="server_mtu", columns="peer_mtu", values="download_rcv_mbps")
sns.heatmap(
dfx.values,
linewidth=0.5,
ax=ax,
cmap="Greens_r",
xticklabels=list(dfx.index),
yticklabels=list(dfx.columns),
)
ax.tick_params(axis="x", rotation=45)
ax.tick_params(axis="y", rotation=0)
ax.set(xlabel="Server MTU", ylabel="Peer MTU")
ax.set_title("Download Rcv Bandwidth (Mbps)")
ax.invert_yaxis()
ax = axes[1, 1]
dfx = df.pivot(index="server_mtu", columns="peer_mtu", values="download_send_mbps")
sns.heatmap(
dfx.values,
linewidth=0.5,
ax=ax,
cmap="Greens_r",
xticklabels=list(dfx.index),
yticklabels=list(dfx.columns),
)
ax.tick_params(axis="x", rotation=45)
ax.tick_params(axis="y", rotation=0)
ax.set(xlabel="Server MTU", ylabel="Peer MTU")
ax.set_title("Download Send Bandwidth (Mbps)")
ax.invert_yaxis()
f.suptitle("Peer MTU vs Server MTU Bandwidth (Mbps)")
f.tight_layout()
f.savefig(plot_filename, dpi=300)
if __name__ == "__main__":
plot_log(
"/home/nitred/projects/group-nr/nr-wg-mtu-finder/examples/example.csv",
"/home/nitred/projects/group-nr/nr-wg-mtu-finder/examples/example.png",
)

@ -0,0 +1,64 @@
import traceback
from flask import Flask, jsonify, request
from typing_extensions import Literal
from typing import Optional
status: Literal["NOT_INITIALIZED", "INITIALIZED", "SHUTDOWN"] = "NOT_INITIALIZED"
mtu: Optional[int] = None
def run_sync_server(host, port, to_server_queue, from_server_queue):
"""Run a temporary flask/http server that returns server mtu and status and restarts server."""
app = Flask(__name__)
def shutdown_server():
shutdown = request.environ.get("werkzeug.server.shutdown")
if shutdown is None:
raise RuntimeError("Not running with the Werkzeug Server")
shutdown()
@app.route("/server/status", methods=["GET"])
def server_status():
global mtu, status
print("RECEIVED REQUEST /server/status")
msg = None if to_server_queue.empty() else to_server_queue.get()
if msg:
# Update global state
mtu, status = msg["server_mtu"], msg["server_status"]
if status == "SHUTDOWN":
# App will shutdown after sending one last response
shutdown_server()
from_server_queue.put("SHUTDOWN")
elif status == "INITIALIZED":
pass
else:
raise NotImplementedError()
return jsonify({"server_mtu": mtu, "server_status": status})
else:
# Return current state
return jsonify({"server_mtu": mtu, "server_status": status})
@app.route("/peer/ready", methods=["GET"])
def peer_ready():
"""Peer is done with its cycle and is waiting for next cycle."""
global mtu, status
print("RECEIVED REQUEST /peer/ready")
status = "NOT_INITIALIZED"
from_server_queue.put("INITIALIZE")
return jsonify({"server_mtu": mtu, "server_status": status})
# @app.route("/server/shutdown", methods=["GET"])
# def server_restart():
# from_server_queue.put("shutdown")
# shutdown_server()
# return jsonify(jsonify({"server_mtu": mtu, "server_status": "shutdown"}))
# Blocking call until the server received a GET request on /server/shutdown after which
# the flask server is shutdown
app.run(host=host, port=port)

@ -0,0 +1,50 @@
import re
from codecs import open # To use a consistent encoding
from os import path
from setuptools import find_packages, setup
here = path.abspath(path.dirname(__file__))
# Get the long description from the relevant file
with open(path.join(here, "README.md"), encoding="utf-8") as f:
long_description = f.read()
# Get version without importing, which avoids dependency issues
def get_version():
with open("nr_wg_mtu_finder/__init__.py") as version_file:
return re.search(
r"""__version__\s+=\s+(['"])(?P<version>.+?)\1""", version_file.read()
).group("version")
install_requires = [
"pandas>=0.23.4",
"matplotlib",
"seaborn",
"pydantic",
"requests",
"flask",
]
setup(
name="nr-wg-mtu-finder",
description="Scripts to find the optimal MTU for Wireguard server and peers.",
long_description=long_description,
version=get_version(),
include_package_data=True,
install_requires=install_requires,
setup_requires=["pytest-runner"],
entry_points="""
[console_scripts]
nr-wg-mtu-finder=nr_wg_mtu_finder.main:run
""",
packages=find_packages(),
zip_safe=False,
author="Nitish K Reddy",
author_email="nitish.k.reddy@gmail.com",
# download_url="github.com/nitred/nr-wg-mtu-finder/archive/{}.tar.gz".format(get_version()),
classifiers=["Programming Language :: Python :: 3.7"],
)
Loading…
Cancel
Save