Skip to main content
The router is a logical UDP packet dispatcher that simulates real-world network conditions by introducing packet loss and delay. It’s essential for testing the Selective Repeat protocol implementation.

Overview

The router receives UDP packets from clients and servers, then dispatches them to their destinations. During delivery, it can simulate adverse network conditions:

Packet Loss

Randomly drop packets based on a configured probability

Network Delay

Introduce variable delays up to a maximum duration
The router changes the peer address value from toAddr to fromAddr during packet delivery, enabling proper bidirectional communication.

Command Syntax

router --port int --drop-rate float --max-delay duration --seed int

Configuration Parameters

--port
integer
default:"3000"
Port number that the router listens on for incoming packets.
router --port 3000
Both client and server must communicate through this port. Choose a port that doesn’t conflict with your server port.
--drop-rate
float
default:"0.0"
Probability (0.0 to 1.0) that any given packet will be dropped during transmission.
router --port 3000 --drop-rate 0.2
A drop rate of 0.2 means 20% of packets will be dropped. Use 0 to disable packet loss.
Common values:
  • 0.0 - No packet loss (ideal network)
  • 0.05 - 5% loss (good network)
  • 0.1 - 10% loss (typical Wi-Fi)
  • 0.2 - 20% loss (poor network)
  • 0.3+ - High loss (stress testing)
--max-delay
duration
default:"0"
Maximum duration that any packet can be delayed. Each packet receives a random delay between 0 and this value.
router --port 3000 --max-delay 100ms
Use 0 to route packets immediately without delay. Format: 5s, 100ms, 1m, etc.
Common values:
  • 0 - No delay (instant delivery)
  • 10ms - Minimal delay (LAN)
  • 50ms - Moderate delay (internet)
  • 100ms - High delay (poor connection)
  • 500ms+ - Very high delay (extreme testing)
--seed
integer
default:"current time"
Seed value for the random number generator. Using the same seed produces repeatable random behaviors.
router --port 3000 --drop-rate 0.2 --seed 42
Use a fixed seed for reproducible tests. Omit this parameter for different behavior each run.

Basic Configurations

Ideal Network (No Loss, No Delay)

Test basic functionality without network issues:
router --port 3000
Output:
config: drop-rate=0.00, max-delay=0s, seed=1709503245123
router is listening at :3000
This configuration is useful for verifying that your client and server work correctly before introducing network issues.

Light Packet Loss

Simulate a good network with occasional packet loss:
router --port 3000 --drop-rate 0.05 --max-delay 10ms
Output:
config: drop-rate=0.05, max-delay=10ms, seed=1709503267890
router is listening at :3000
5% packet loss with 10ms delay simulates typical Wi-Fi conditions.

Moderate Network Conditions

Test resilience with noticeable packet loss and delay:
router --port 3000 --drop-rate 0.1 --max-delay 50ms
Output:
config: drop-rate=0.10, max-delay=50ms, seed=1709503289456
router is listening at :3000

Poor Network Conditions

Stress test with high packet loss:
router --port 3000 --drop-rate 0.2 --max-delay 100ms
Output:
config: drop-rate=0.20, max-delay=100ms, seed=1709503301234
router is listening at :3000
20% packet loss represents a very poor network. Your Selective Repeat implementation should handle this gracefully with retransmissions.

Extreme Testing

Test protocol limits with severe network issues:
router --port 3000 --drop-rate 0.3 --max-delay 200ms
Output:
config: drop-rate=0.30, max-delay=200ms, seed=1709503312567
router is listening at :3000
30% loss may cause timeouts and slow transfers. This tests the robustness of your implementation.

Reproducible Testing

Using Fixed Seeds

For reproducible test scenarios, use the same seed value:
router --port 3000 --drop-rate 0.2 --max-delay 50ms --seed 42
With the same seed, the exact same packets will be dropped and delayed in the same way. This is crucial for debugging specific issues.

Variable Testing

For different behavior each time, omit the seed or use different values:
router --port 3000 --drop-rate 0.15 --max-delay 75ms
The seed will default to the current timestamp, ensuring unique behavior.

Router Logging

The router logs all activity to both console and router.log file.

Log Format

[queue=5] packet #123, 192.168.1.100:5000 -> 192.168.1.101:8080, sz=1024 is delayed for 45ms

Understanding Log Entries

1

Queue Size

[queue=5] shows the number of packets currently waiting for delivery.
2

Packet Info

#123 is the sequence number of the packet.
3

Source and Destination

192.168.1.100:5000 -> 192.168.1.101:8080 shows the packet route.
4

Packet Size

sz=1024 indicates the packet payload size in bytes.
5

Action

The final part indicates what happened: delayed, delivered, or dropped.

Viewing Logs

Logs are displayed in real-time on the console:
router --port 3000 --drop-rate 0.1
You’ll see packet activity as it happens.

Testing Scenarios

Verify basic protocol correctness:
# No packet loss or delay
router --port 3000 --seed 1
Expected:
  • All packets delivered in order
  • No retransmissions needed
  • Fast transfer times

Advanced Configuration

Multi-Client Testing

The router handles multiple clients simultaneously:
router --port 3000 --drop-rate 0.1 --max-delay 50ms
1

Start Router

One router instance can serve multiple clients and servers.
2

Start Multiple Servers

# Terminal 1
httpfs -p 8080

# Terminal 2
httpfs -p 8081
3

Connect Multiple Clients

Each client can connect independently:
httpc get http://localhost:8080/get
httpc get http://localhost:8081/get
The router maintains separate packet queues and applies drop/delay rules independently to each packet.

Performance Tuning

Delay Distribution

Delay is uniformly distributed between 0 and max-delay. Each packet gets a random delay value.
delay := rand.Intn(100) * maxDelay / 100

Queue Management

The router tracks queue size for delayed packets. High queue sizes indicate network congestion.
[queue=50] packet #456 is delayed for 89ms

Packet Format

Understanding the packet structure helps with debugging:
type Packet struct {
    Type     uint8      // 1 byte: ACK (1), DATA (0), etc.
    SeqNum   uint32     // 4 bytes: sequence number
    ToAddr   *net.UDPAddr
    FromAddr *net.UDPAddr
    Payload  []byte     // up to 1024 bytes total
}
Packets smaller than 11 bytes or larger than 1024 bytes are rejected as invalid.

Troubleshooting

Check if the port is already in use:
# Check port usage
lsof -i :3000

# Use a different port
router --port 3001
If transfers are failing, reduce the drop rate:
# From 30% to 10%
router --port 3000 --drop-rate 0.1 --max-delay 50ms
Check router logs to see actual drop statistics:
grep -c "is dropped" router.log
grep -c "is delivered" router.log
Reduce max-delay or increase client timeout values:
# Reduce delay from 200ms to 50ms
router --port 3000 --drop-rate 0.1 --max-delay 50ms
Use a fixed seed to reproduce the same packet loss pattern:
# This will always drop the same packets
router --port 3000 --drop-rate 0.2 --seed 42
Truncate or rotate the log file:
# Clear the log
> router.log

# Or move it
mv router.log router.log.old

Complete Testing Example

Here’s a comprehensive test setup:
1

Start Router with Logging

router --port 3000 --drop-rate 0.15 --max-delay 50ms --seed 42 | tee test-router.log
This saves console output to a file while displaying it.
2

Monitor Router Activity

In another terminal:
watch -n 1 'tail -20 router.log'
This shows the last 20 log lines, updating every second.
3

Start Server

cd Server
mvn exec:java -Dexec.mainClass="Server.ServerCommand"
# Enter: httpfs -v -p 8080
4

Run Client Tests

cd Client
mvn exec:java -Dexec.mainClass="client.CLient"
# Enter: httpc get -v http://localhost:8080/get
5

Analyze Results

After testing, analyze the logs:
# Count packets
grep -c "is delivered" router.log
grep -c "is dropped" router.log
grep -c "is delayed" router.log

# Calculate actual drop rate
echo "scale=2; $(grep -c 'is dropped' router.log) * 100 / ($(grep -c 'is delivered' router.log) + $(grep -c 'is dropped' router.log))" | bc

Next Steps

Client Usage

Test your router configuration with the client

Server Setup

Configure the server to work with the router

Build docs developers (and LLMs) love