Skip to content

Commit 99f21a0

Browse files
committed
Add bandwidth quota example
1 parent 24afd4b commit 99f21a0

File tree

4 files changed

+387
-1
lines changed

4 files changed

+387
-1
lines changed

examples/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- [turn-server](#turn-server)
44
- [add-software-attribute](#add-software-attribute) - Add custom SOFTWARE attribute to STUN packets
5+
- [bw-quota](#bw-quota) - TURN server with per-user bandwidth rate limiting
56
- [log](#log) - Log all inbound/outbound STUN packets
67
- [simple](#simple) - Minimal TURN server implementation
78
- [simple-quota](#simple-quota) - TURN server with per-user allocation limits
@@ -49,6 +50,29 @@ if you want to add debug info to your outbound packets.
4950

5051
You could also use this same pattern to filter/modify packets if needed.
5152

53+
#### bw-quota
54+
55+
This example demonstrates per-user bandwidth rate limiting. Each user
56+
(identified by username+realm) gets their own token bucket rate limiter
57+
that caps total bandwidth usage across all their relay connections.
58+
59+
The implementation wraps the relay `PacketConn` with a rate-limited
60+
connection that silently drops packets when the quota is exceeded. Both
61+
upload and download traffic share the same rate limit.
62+
63+
``` sh
64+
$ cd bw-quota
65+
$ go build
66+
$ ./bw-quota -public-ip 127.0.0.1 -users user1=pass1 -bw-limit 12500
67+
```
68+
69+
The `-bw-limit` flag sets bytes/sec per user (default: 12500 = 100 Kbps).
70+
Use `-test` to start a built-in TURN client and UDP echo server for
71+
testing with tools like `iperf`.
72+
73+
See the [bw-quota README](turn-server/bw-quota/README.md) for detailed
74+
testing instructions with parallel iperf sessions.
75+
5276
#### log
5377

5478
This example logs all inbound/outbound STUN packets. This could be
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Bandwidth Quota TURN Server Example
2+
3+
This example demonstrates how to implement per-user bandwidth quotas in the TURN server. Each user (identified by username+realm) gets their own rate limiter that caps their total bandwidth usage across all relay connections.
4+
5+
``` mermaid
6+
flowchart LR
7+
A[iperf-client] -->|testPort\n5000| B[TURN client-proxy]
8+
B --> C[TURN server]
9+
C -->|peerAddr\nlocalhost:5001| D[iperf server]
10+
```
11+
12+
## Usage
13+
14+
### Start the Server
15+
16+
```bash
17+
go run main.go -public-ip=<YOUR_PUBLIC_IP> -users=user1=pass1,user2=pass2 -bw-limit=12500
18+
```
19+
20+
**Flags:**
21+
- `-public-ip`: Server's public IP address (required)
22+
- `-port`: TURN server port (default: 3478)
23+
- `-users`: Comma-separated list of user=password pairs (required)
24+
- `-realm`: Authentication realm (default: "pion.ly")
25+
- `-bw-limit`: Bandwidth limit in bytes/sec per user (default: 12500 = 100 Kbps)
26+
- `-test`: Enable test mode with built-in TURN client and UDP echo server
27+
- `-test-port`: UDP port for test echo server (default: 15000)
28+
29+
### Test Mode
30+
31+
The `-test` flag starts a built-in TURN client that allocates a relay and exposes a UDP echo server for easy testing:
32+
33+
```bash
34+
go run main.go -public-ip=127.0.0.1 -users=testuser=testpass -bw-limit=12500 -test
35+
```
36+
37+
## Testing with iperf
38+
39+
You can verify the bandwidth quota is working using `iperf` UDP mode.
40+
41+
### Setup
42+
43+
1. Start the TURN server, `-test` means to also start a TURN client that serves as a proxy for the
44+
load generator (`iperf` in this case):
45+
```bash
46+
go run main.go -public-ip=127.0.0.1 -users=user1=pass1 -bw-limit=12500 -test
47+
```
48+
49+
2. Start iperf server (simulates a peer):
50+
```bash
51+
iperf -s -u -p 5001
52+
```
53+
54+
3. Run a TURN client that connects to the peer through the relay. This will run for 10 seconds,
55+
generating 1 Mbps load traffic. The summary log however shows only ~100 Kbps throughput instead
56+
of the requested 1 Mbps as the rate-limiter drops traffic exceeding the bandwidth quota.
57+
```bash
58+
iperf -c <proxy-address> -u -p <proxy-port> -b 1M -t 10
59+
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
60+
[ 1] 0.0000-10.0596 sec 135 KBytes 110 Kbits/sec 0.000 ms 804/898 (0%)
61+
```
62+
63+
64+

0 commit comments

Comments
 (0)