Skip to content

Custom reliable UDP protocol with sliding window, three-way handshake, flow control, and packet loss handling in C

Notifications You must be signed in to change notification settings

dawnbliss-coder/networking

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RUDP - Reliable UDP Implementation

A custom reliable data transfer protocol built on top of UDP with support for file transfer, chat mode, three-way handshake, four-way connection termination, sliding window flow control, and configurable packet loss simulation.

Overview

This project implements a reliable transport protocol called S.H.A.M. (Simple Handshake and Messaging) over UDP, featuring:

  • Three-way handshake for connection establishment
  • Four-way handshake for graceful connection termination
  • Sliding window protocol with Go-Back-N ARQ for reliable data transfer
  • Flow control with dynamic window advertisement
  • Timeout and retransmission mechanism
  • Packet loss simulation for testing reliability
  • File transfer mode with MD5 checksum verification
  • Interactive chat mode for real-time messaging
  • Comprehensive logging for debugging and analysis

Protocol Header (S.H.A.M.)

struct sham_header {
    uint32_t seq_num;       // Sequence Number
    uint32_t ack_num;       // Acknowledgment Number
    uint16_t flags;         // Control flags (SYN, ACK, FIN)
    uint16_t window_size;   // Flow control window size
};

Flags

  • SYN_FLAG (0x1): Synchronize sequence numbers (connection establishment)
  • ACK_FLAG (0x2): Acknowledgment
  • FIN_FLAG (0x4): Finish connection (graceful termination)

Features

Connection Management

  • Three-Way Handshake: SYN → SYN-ACK → ACK sequence for reliable connection establishment
  • Four-Way Handshake: FIN → ACK → FIN → ACK sequence for graceful connection termination
  • Retransmission: Automatic retransmission on timeout with configurable RTO (500ms default)

Reliable Data Transfer

  • Sliding Window Protocol: Client uses 4-packet window, server buffers up to 20 packets
  • Selective Acknowledgment: Cumulative ACKs with duplicate detection
  • Out-of-Order Buffering: Server buffers out-of-order packets for efficient delivery
  • Flow Control: Dynamic window advertisement prevents receiver buffer overflow

Packet Loss Handling

  • Configurable Loss Rate: Simulate packet loss with rates between 0.0 and 1.0
  • Timeout Detection: Detect lost packets using RTO timer
  • Automatic Retransmission: Retransmit unacknowledged packets on timeout

Logging

  • Event Logging: Detailed logs for all protocol events (send, receive, drop, timeout)
  • Timestamped Entries: Microsecond-precision timestamps for debugging
  • Environment Variable Control: Enable logging with RUDP_LOG=1

Project Structure

.
├── client.c        # Client implementation (sender)
├── server.c        # Server implementation (receiver)
├── sham.c          # Protocol helper functions (byte order conversion)
├── sham.h          # Protocol header definitions
├── Makefile        # Build configuration
├── test.txt        # Sample test file
├── client_log.txt  # Client event log (generated)
└── server_log.txt  # Server event log (generated)

Compilation

Using Makefile (Recommended)

# Build both client and server
make

# Clean build artifacts
make clean

The Makefile automatically:

  • Detects OpenSSL installation via Homebrew (macOS)
  • Links with OpenSSL's crypto library for MD5 checksums
  • Compiles with C11 standard and warning flags

Manual Compilation

# On macOS with Homebrew OpenSSL
gcc -Wall -Wextra -std=c11 -I$(brew --prefix openssl)/include     -L$(brew --prefix openssl)/lib server.c sham.c -o server -lcrypto

gcc -Wall -Wextra -std=c11 -I$(brew --prefix openssl)/include     -L$(brew --prefix openssl)/lib client.c sham.c -o client -lcrypto

# On Linux (standard OpenSSL paths)
gcc -Wall -Wextra -std=c11 server.c sham.c -o server -lcrypto
gcc -Wall -Wextra -std=c11 client.c sham.c -o client -lcrypto

Usage

File Transfer Mode

Server

# Basic usage
./server <port>

# With packet loss simulation
./server <port> <loss_rate>

# Examples
./server 8080
./server 8080 0.1    # 10% packet loss

Client

# Basic usage
./client <server_ip> <port> <input_file> <output_filename>

# With packet loss simulation
./client <server_ip> <port> <input_file> <output_filename> <loss_rate>

# Examples
./client 127.0.0.1 8080 test.txt received.txt
./client 127.0.0.1 8080 test.txt received.txt 0.15    # 15% packet loss

Chat Mode

Server

# Start server in chat mode
./server <port> --chat [loss_rate]

# Examples
./server 8080 --chat
./server 8080 --chat 0.05    # 5% packet loss

Client

# Connect to server in chat mode
./client <server_ip> <port> --chat [loss_rate]

# Examples
./client 127.0.0.1 8080 --chat
./client 127.0.0.1 8080 --chat 0.1    # 10% packet loss

Chat Commands:

  • Type message and press Enter to send
  • Type /quit to exit chat mode and close connection

Enabling Logging

# Set environment variable before running
export RUDP_LOG=1

# Run client/server
./client 127.0.0.1 8080 test.txt output.txt
./server 8080

# Logs will be written to client_log.txt and server_log.txt

Implementation Details

Client (Sender)

Window Management:

  • Maintains sliding window of 4 packets (configurable with WINDOW_SIZE)
  • Tracks base sequence number and next sequence to send
  • Implements dynamic timeout calculation based on oldest unacknowledged packet

Flow Control:

  • Monitors receiver's advertised window size
  • Suspends transmission when receiver buffer is full
  • Resumes transmission when window opens

Retransmission:

  • 500ms RTO (Retransmission Timeout)
  • Retransmits oldest unacknowledged packet on timeout
  • Uses non-blocking socket with select() for multiplexing

Server (Receiver)

Buffer Management:

  • Buffers up to 20 out-of-order packets (2× window size)
  • Delivers packets to application in order
  • Dynamically updates advertised window based on buffer occupancy

ACK Generation:

  • Sends cumulative ACK for next expected sequence number
  • Sends duplicate ACKs for out-of-order packets
  • Includes current window size in every ACK

File Reception:

  • Writes received data to file as it arrives in order
  • Calculates MD5 checksum after complete file reception
  • Displays checksum for verification

Chat Mode

Bidirectional Communication:

  • Uses select() to multiplex between stdin and socket
  • Sends messages as data packets with S.H.A.M. header
  • Real-time display of incoming and outgoing messages

Connection Termination:

  • Client initiates termination with /quit command
  • Four-way handshake ensures graceful shutdown
  • Both sides can detect premature disconnection

Protocol Flow

Connection Establishment (Three-Way Handshake)

Client                          Server
   |                               |
   |  SYN (seq=1000)              |
   |----------------------------->|
   |                               |
   |  SYN-ACK (seq=5000, ack=1001)|
   |<-----------------------------|
   |                               |
   |  ACK (ack=5001)              |
   |----------------------------->|
   |                               |
   |  [Connection Established]    |

Data Transfer

Client                          Server
   |                               |
   |  DATA (seq=X, len=1024)      |
   |----------------------------->|
   |                               |
   |  ACK (ack=X+1024)            |
   |<-----------------------------|
   |                               |
   |  DATA (seq=X+1024, len=512)  |
   |----------------------------->|
   |                               |
   |  ACK (ack=X+1536)            |
   |<-----------------------------|

Connection Termination (Four-Way Handshake)

Client                          Server
   |                               |
   |  FIN (seq=Y)                 |
   |----------------------------->|
   |                               |
   |  ACK (ack=Y+1)               |
   |<-----------------------------|
   |                               |
   |  FIN (seq=Z)                 |
   |<-----------------------------|
   |                               |
   |  ACK (ack=Z+1)               |
   |----------------------------->|
   |                               |
   |  [Connection Closed]         |

Configuration Parameters

Client

  • WINDOW_SIZE: 4 packets
  • RTO_MS: 500 milliseconds
  • PAYLOAD_SIZE: 1024 bytes
  • BUFFER_SIZE: 1040 bytes (header + payload)

Server

  • WINDOW_SIZE: 10 packets (buffer = 2× window)
  • PAYLOAD_SIZE: 1024 bytes
  • BUFFER_SIZE: 1040 bytes

Build Configuration

Makefile Settings

  • Compiler: GCC with C11 standard
  • Flags: -Wall -Wextra (strict warnings)
  • OpenSSL: Automatic detection via Homebrew (macOS)
  • Library: -lcrypto for MD5 checksums
  • Targets: server and client executables

Dependencies

  • GCC compiler with C11 support
  • OpenSSL library (libssl-dev on Ubuntu/Debian, openssl via Homebrew on macOS)
  • Standard POSIX headers: sys/socket.h, netinet/in.h, arpa/inet.h

Error Handling

  • Socket creation/binding failures with descriptive error messages
  • File open/read/write errors with errno reporting
  • Handshake timeout and automatic retransmission
  • Packet loss detection and recovery via timeout mechanism
  • Graceful handling of unexpected disconnections
  • Invalid command-line argument validation

Testing

Basic File Transfer Test

# Terminal 1: Start server
./server 8080

# Terminal 2: Send file
./client 127.0.0.1 8080 test.txt received.txt

# Verify transfer
md5sum test.txt received.txt    # Linux
md5 test.txt received.txt        # macOS

Packet Loss Simulation Test

# Terminal 1: Server with 20% loss
export RUDP_LOG=1
./server 8080 0.2

# Terminal 2: Client with 20% loss
export RUDP_LOG=1
./client 127.0.0.1 8080 test.txt received.txt 0.2

# Check logs
tail -f client_log.txt
tail -f server_log.txt

Chat Mode Test

# Terminal 1: Server in chat mode
./server 8080 --chat

# Terminal 2: Client in chat mode
./client 127.0.0.1 8080 --chat

# Exchange messages, then type /quit on client

Large File Transfer Test

# Create a large test file (10 MB)
dd if=/dev/urandom of=largefile.bin bs=1024 count=10240

# Transfer the file
./server 8080
./client 127.0.0.1 8080 largefile.bin received_large.bin

# Verify integrity
diff largefile.bin received_large.bin

Log File Format

[2025-11-15 01:30:45.123456] [LOG] SND SYN SEQ=1000
[2025-11-15 01:30:45.234567] [LOG] RCV SYN-ACK SEQ=5000 ACK=1001
[2025-11-15 01:30:45.345678] [LOG] SND DATA SEQ=1001 LEN=1024
[2025-11-15 01:30:45.456789] [LOG] RCV ACK=2025
[2025-11-15 01:30:46.567890] [LOG] TIMEOUT SEQ=2025
[2025-11-15 01:30:46.678901] [LOG] RETX DATA SEQ=2025 LEN=512
[2025-11-15 01:30:46.789012] [LOG] DROP DATA SEQ=3000

Troubleshooting

OpenSSL Not Found (macOS)

# Install OpenSSL via Homebrew
brew install openssl

# Update Makefile or set paths manually
export OPENSSL_ROOT=$(brew --prefix openssl)

OpenSSL Not Found (Linux)

# Install OpenSSL development package
sudo apt-get install libssl-dev      # Ubuntu/Debian
sudo yum install openssl-devel       # CentOS/RHEL

Port Already in Use

# Find process using the port
lsof -i :8080           # macOS/Linux
netstat -ano | grep 8080  # Linux

# Kill the process or use a different port
./server 8081

Limitations

  • Fixed payload size of 1024 bytes per packet
  • No congestion control (only flow control)
  • Simple Go-Back-N retransmission (not selective repeat)
  • Single-threaded server (handles one client at a time)
  • No encryption or authentication
  • No adaptive RTO calculation (fixed 500ms timeout)

Author

dawnbliss-coder

About

Custom reliable UDP protocol with sliding window, three-way handshake, flow control, and packet loss handling in C

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published