2 releases
| 0.1.1 | Oct 7, 2025 |
|---|---|
| 0.1.0 | Oct 7, 2025 |
#2006 in Network programming
Used in 2 crates
(via hightower-client)
29KB
537 lines
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:
- Client sends a Binding Request to a STUN server
- The NAT modifies the source IP/port of the packet
- Server receives the request with the public IP/port
- Server responds with a Binding Response containing an XOR-MAPPED-ADDRESS attribute
- 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 examplerun_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.