Skip to content

Instantly share code, notes, and snippets.

@gmcabrita
Last active June 3, 2024 10:51
Show Gist options
  • Save gmcabrita/2d72cb6583951cca7192aec145af5c41 to your computer and use it in GitHub Desktop.
Save gmcabrita/2d72cb6583951cca7192aec145af5c41 to your computer and use it in GitHub Desktop.

If you’re an app developer reading this, can you tell me, off the top of your head, how your app behaves on a link with 40 kbps available bandwidth, 1,000 ms latency, occasional jitter of up to 2,000 ms, packet loss of 10%, and a complete 15-second connectivity dropout every few minutes?

https://chatgpt.com/share/13e444bc-f16e-4ce7-841f-e8362f366da4

macOS

1. Create a configuration file for pfctl

sudo nano /etc/pf.conf:

dummynet-anchor "shaping"
anchor "shaping"

2. Create the dummynet rules

sudo nano /etc/pf.anchors/shaping:

dummynet out proto tcp from any to any pipe 1
dummynet out proto udp from any to any pipe 1

# Define the pipe with bandwidth, delay, and packet loss
pipe 1 config bw 40Kbit/s delay 1000ms plr 0.1 queue 50

3. Enable pfctl and load the configuration

sudo pfctl -e
sudo pfctl -f /etc/pf.conf
sudo dnctl -f flush
sudo dnctl pipe 1 config bw 40Kbit/s delay 1000ms plr 0.1

4. Simulate jitter and periodic connectivity dropouts

To simulate jitter and dropouts, you can use a looped script that periodically changes the conditions. Create a script network_simulation.sh:

#!/usr/bin/env bash

while true; do
  # Simulate jitter
  sudo dnctl pipe 1 config bw 40Kbit/s delay $((1000 + RANDOM % 2000))ms plr 0.1
  sleep 30

  # Simulate connectivity dropout
  sudo dnctl pipe 1 config bw 40Kbit/s delay 1000ms plr 1
  sleep 15

  # Restore normal conditions
  sudo dnctl pipe 1 config bw 40Kbit/s delay 1000ms plr 0.1
  sleep $(( RANDOM % 120 + 60 ))
done

5. Make the script executable and run it

chmod +x network_simulation.sh
./network_simulation.sh

This setup will simulate the specified network conditions, including bandwidth limitations, latency, jitter, packet loss, and periodic connectivity dropouts.

6. Restoring network conditions

#!/usr/bin/env bash

# Flush all dummynet configurations
sudo dnctl -f flush

# Disable pfctl
sudo pfctl -d

echo "Network conditions restored to normal."

Linux

To achieve the same network conditions on Linux, you can use tc (Traffic Control) along with netem for network emulation. Here's how to set it up:

1. Install necessary tools

sudo apt-get update
sudo apt-get install iproute2

2. Set up the basic network conditions

sudo tc qdisc add dev eth0 root handle 1: htb default 30
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 40kbps
sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 1000ms loss 10%

Replace eth0 with your network interface name, which you can find using ifconfig or ip a.

3. Simulate jitter and periodic connectivity dropouts

Create a script network_simulation.sh:

#!/usr/bin/env bash

while true; do
  # Simulate jitter
  sudo tc qdisc change dev eth0 root handle 1: htb default 30
  sudo tc class change dev eth0 parent 1: classid 1:1 htb rate 40kbps
  sudo tc qdisc change dev eth0 parent 1:1 handle 10: netem delay $((1000 + RANDOM % 2000))ms loss 10%
  sleep 30

  # Simulate connectivity dropout
  sudo tc qdisc change dev eth0 root handle 1: htb default 30
  sudo tc class change dev eth0 parent 1:1 htb rate 40kbps
  sudo tc qdisc change dev eth0 parent 1:1 handle 10: netem delay 1000ms loss 100%
  sleep 15

  # Restore normal conditions
  sudo tc qdisc change dev eth0 root handle 1: htb default 30
  sudo tc class change dev eth0 parent 1:1 htb rate 40kbps
  sudo tc qdisc change dev eth0 parent 1:1 handle 10: netem delay 1000ms loss 10%
  sleep $(( RANDOM % 120 + 60 ))
done

Replace eth0 with your network interface name, which you can find using ifconfig or ip a.

4. Make the script executable and run it

chmod +x network_simulation.sh
./network_simulation.sh

This script periodically changes the network conditions to include jitter and simulate complete connectivity dropouts as specified.

5. Restoring network conditions

#!/usr/bin/env bash

# Delete all tc configurations
sudo tc qdisc del dev eth0 root

echo "Network conditions restored to normal."

Replace eth0 with your network interface name, which you can find using ifconfig or ip a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment