What I made
linkprobe measures what a network does to messages between two machines: round-trip time, packet loss, and how many packets get lost in a row (bursts). It can degrade the link on purpose with 5 profiles: clean, latency-ladder, jitter, bernoulli-loss, and gilbert-elliott. I built it because robots that depend on a reply every control cycle get hurt way more by losses in a row than by random single losses, but a lot of tests assume losses are independent.
Main result
At the same 10% loss rate, Gilbert-Elliott bursts were about 4.4x longer than Bernoulli bursts (around 4.9 vs 1.1 packets), and the longest burst was 29 packets vs 5, across 3 seeds. With jitter, the deadline had to be 176 ms to get missed packets under 1%.
What was challenging
I found a bug where my client saved replies under the wrong packet. A late reply got recorded as the next packet’s reply, and every packet after that was shifted by one. Nothing crashed, the data was just wrong. I fixed it by giving every packet a deadline and only accepting the reply with the matching sequence number. Without that, every jitter run would have been garbage. Fixing Hackatime also took a lot of time.
What I’m proud of
Learning how researchers actually model packet loss, building the Gilbert-Elliott channel myself, and checking my results: a replay check across 60,000 packets found only one mismatch, and pytest tests cover the channel functions.
I also learned a lot of new coding libraries and tricks for the future
How to test it
- git clone https://github.com/AymanM-Projects/linkprobe
- pip install -r requirements.txt
- python run_all.py (runs all the profiles; the full set takes a while)
- python analyze.py, then run the plot_*.py files to make the graphs
Everything runs on one computer over loopback, so the only delay and loss are the ones linkprobe adds. Full results are in RESULTS.md.
- 25 devlogs
- 30h