hightower-stun

Crates.iohightower-stun
lib.rshightower-stun
version0.1.1
created_at2025-10-07 19:48:37.111377+00
updated_at2025-10-07 20:50:17.324012+00
descriptionA lightweight STUN (Session Traversal Utilities for NAT) server and client implementation conforming to RFC 8489
homepage
repositoryhttps://github.com/chrishayen/hightower-stun
max_upload_size
id1872736
size35,336
Chris Hayen (chrishayen)

documentation

README

hightower-stun

A lightweight, RFC 8489-compliant STUN (Session Traversal Utilities for NAT) server and client implementation in Rust.

Features

  • RFC 8489 Compliant: Implements Basic STUN Server specification (Section 12)
  • Client & Server: Both client and server implementations included
  • XOR-MAPPED-ADDRESS: Proper support for reflexive address discovery
  • IPv4 & IPv6: Support for both address families
  • DNS Resolution: Client supports domain names and IP addresses
  • Cross-Platform: Works on Linux, macOS, and Windows
  • Zero Dependencies: Pure Rust implementation with only standard library
  • Lightweight: Focused on core NAT traversal without authentication overhead

Usage

As a Library

STUN Client

use hightower_stun::client::StunClient;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = StunClient::new()?;

    // Query a STUN server to discover your public IP
    let addr = client.get_public_address("stun.l.google.com:3478")?;

    println!("Your public IP: {}", addr.ip());
    println!("Your public port: {}", addr.port());

    Ok(())
}

STUN Server

use hightower_stun::server::StunServer;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let server = StunServer::bind("0.0.0.0:3478")?;

    println!("STUN server listening on {}", server.local_addr()?);

    // Run the server (blocks indefinitely)
    server.run()?;

    Ok(())
}

As Binaries

The crate includes two binaries:

Client: ht-stun-client

Query a STUN server to discover your public IP address:

# Port defaults to 3478
ht-stun-client stun.l.google.com
ht-stun-client gateway.shotgun.dev

# Or specify port explicitly
ht-stun-client 192.168.1.1:3478

Server: ht-stun-server

Run a STUN server:

# Listen on default port 3478
ht-stun-server

# Or specify custom address
ht-stun-server 0.0.0.0:3478

Building from Source

# Build library and binaries
cargo build --release

# Run tests
cargo test

# Run client
cargo run --bin ht-stun-client -- stun.l.google.com

# Run server
cargo run --bin ht-stun-server

Cross-Compilation for ARM64

To build for ARM64 (aarch64) servers:

# Install the target
rustup target add aarch64-unknown-linux-gnu

# Install the cross-compiler (Arch Linux)
sudo pacman -S aarch64-linux-gnu-gcc

# Build
cargo build --release --target aarch64-unknown-linux-gnu

The included Makefile provides a deploy target for building and deploying to a remote server.

How STUN Works

STUN helps clients discover their public IP address when behind a NAT:

  1. Client sends a Binding Request to a STUN server
  2. The NAT modifies the source IP/port of the packet
  3. Server receives the request with the public IP/port
  4. Server responds with a Binding Response containing an XOR-MAPPED-ADDRESS attribute
  5. Client extracts its public IP/port from the response

Protocol Details

  • Default Port: 3478 (UDP/TCP)
  • Magic Cookie: 0x2112A442
  • Message Types: Binding Request (0x0001), Binding Response (0x0101)
  • Attributes: XOR-MAPPED-ADDRESS (0x0020), MAPPED-ADDRESS (0x0001)

Examples

See the examples/ directory for more:

  • get_public_ip.rs - Simple client example
  • run_server.rs - Basic server example

Testing

# Run all tests
cargo test

# Test against a public STUN server
cargo run --example get_public_ip stun.l.google.com

# Test client against your own server
cargo run --bin ht-stun-server &
cargo run --bin ht-stun-client localhost

Implementation Status

This library implements a Basic STUN Server as defined in RFC 8489, Section 12. It focuses on the core functionality needed for NAT traversal and public IP discovery.

Implemented Features

  • ✅ Binding method (request/response)
  • ✅ XOR-MAPPED-ADDRESS attribute (IPv4 and IPv6)
  • ✅ MAPPED-ADDRESS attribute (fallback, decode only)
  • ✅ Transaction ID generation and validation
  • ✅ Message encoding/decoding with proper padding
  • ✅ UDP transport
  • ✅ DNS resolution

Not Implemented

Per RFC 8489 Section 12, Basic STUN Servers SHOULD NOT implement:

  • Authentication (short-term and long-term credentials)
  • ALTERNATE-SERVER mechanism

Additional features not implemented:

  • Error responses (server silently ignores invalid requests)
  • TCP/TLS/DTLS transports (UDP is sufficient for basic operation)
  • Client retransmission logic
  • FINGERPRINT attribute (optional integrity checking)
  • MESSAGE-INTEGRITY attributes

See IMPLEMENTATION.md for a complete feature breakdown.

References

Contributing

Contributions welcome! Please feel free to submit a Pull Request.

Commit count: 0

cargo fmt