```
╔═╗╔═╗╔═╗╔╦╗╔╗╔╔═╗╔╦╗
╠╣ ╠═╣╚═╗ ║ ║║║║╣ ║ Ultra-low latency encrypted networking
╚ ╩ ╩╚═╝ ╩ ╝╚╝╚═╝ ╩ for real-time games
```
[](https://crates.io/crates/fastnet)
[](https://docs.rs/fastnet)
[](LICENSE)
**FastNet** is a high-performance networking library designed for real-time multiplayer games. It provides encrypted UDP communication with latencies as low as **15 microseconds** while maintaining strong security through TLS 1.3 and ChaCha20-Poly1305 encryption.
---
## Features
- **Ultra-Low Latency**: ~12-15µs average RTT on localhost, competitive with raw UDP
- **Built-in Encryption**: TLS 1.3 handshake + ChaCha20-Poly1305 AEAD
- **Zero-Alloc Hot Path**: Fixed buffers, no allocations in send/recv loop
- **Key Rotation**: Automatic key rotation for forward secrecy
- **Linux Tuning**: SO_BUSY_POLL, IP_TOS, sendmmsg/recvmmsg batching
- **Zero Configuration Security**: No need to understand cryptography
- **Game Engine Ready**: C/C++ FFI for Unreal Engine, Unity, Godot
- **Async/Await**: Built on Tokio for efficient I/O
- **Reliable & Unreliable Channels**: Choose the right mode for your data
- **P2P Networking**: Direct peer-to-peer connections with NAT traversal
- **TCP Fallback**: Automatic fallback when UDP is blocked
- **Asset Distribution**: Large file transfers with LZ4 compression and BLAKE3 verification
---
## Benchmarks
Tested with 50,000 packets at 10,000 packets/second on localhost:
| **Avg Latency** | 112.7 µs | **15.6 µs** | 64.0 µs |
| **P99 Latency** | 143.0 µs | **69.6 µs** | 170.0 µs |
| **Max Latency** | 323 µs | **103.6 µs** | 1868 µs |
| **Encryption** | None | ChaCha20 | TLS |
```
Average Latency (lower is better)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FastNet ██ 15.6 µs ⚡
QUIC ████████ 64.0 µs
ENet ██████████████ 112.7 µs
```
> **7x faster** than ENet with full encryption enabled
>
> *Note: Max latency spikes in FastNet/QUIC are due to TLS overhead during handshake*
---
## Quick Start
### Rust
Add to your `Cargo.toml`:
```toml
[dependencies]
fastnet = "0.1"
tokio = { version = "1", features = ["rt-multi-thread"] }
```
**Server:**
```rust
use fastnet::net::SecureSocket;
use std::net::SocketAddr;
#[tokio::main]
async fn main() -> std::io::Result<()> {
// Load TLS certificates
let certs = load_certs("cert.pem")?;
let key = load_key("key.pem")?;
let udp_addr: SocketAddr = "0.0.0.0:7777".parse().unwrap();
let tcp_addr: SocketAddr = "0.0.0.0:7778".parse().unwrap();
let mut socket = SecureSocket::bind_server(udp_addr, tcp_addr, certs, key).await?;
println!("Server listening on {}", udp_addr);
loop {
for event in socket.poll().await? {
match event {
SecureEvent::Connected(peer_id) => {
println!("Peer {} connected", peer_id);
}
SecureEvent::Data(peer_id, channel, data) => {
// Echo back
socket.send(peer_id, channel, data).await?;
}
SecureEvent::Disconnected(peer_id) => {
println!("Peer {} disconnected", peer_id);
}
}
}
}
}
```
**Client:**
```rust
use fastnet::net::SecureSocket;
#[tokio::main]
async fn main() -> std::io::Result<()> {
let server_addr = "127.0.0.1:7778".parse().unwrap();
let mut socket = SecureSocket::connect(server_addr).await?;
// Send data on channel 0
socket.send(1, 0, b"Hello, server!".to_vec()).await?;
// Receive events
for event in socket.poll().await? {
if let SecureEvent::Data(_, _, data) = event {
println!("Received: {:?}", data);
}
}
Ok(())
}
```
---
## C/C++ Integration
### Building the Library
Add the crate into your project:
```Cargo.toml
fastnet = { version = "0.1", features = ["ffi"] }
```
or clone the repo into your machine:
```fish
git clone https://github.com/filipe-freitas-dev/fastnet.git
```
then build the C/C++ wrapper with:
```fish
cargo build --release --features ffi
```
This produces:
- Linux: `target/release/libfastnet.so`
- Windows: `target/release/fastnet.dll`
- macOS: `target/release/libfastnet.dylib`
### C Example
```c
#include "fastnet.h"
int main() {
// Connect to server
FastNetClient client = fastnet_client_connect("127.0.0.1", 7778);
if (!client) {
printf("Failed to connect\n");
return 1;
}
// Send data
uint8_t data[] = {1, 2, 3, 4};
fastnet_client_send(client, 0, data, sizeof(data));
// Process events
FastNetEvent event;
while (fastnet_client_poll(client, &event)) {
switch (event.type) {
case FASTNET_EVENT_CONNECTED:
printf("Connected as peer %d\n", event.peer_id);
break;
case FASTNET_EVENT_DATA:
printf("Received %d bytes\n", event.data_len);
break;
case FASTNET_EVENT_DISCONNECTED:
printf("Disconnected\n");
break;
}
}
fastnet_client_disconnect(client);
return 0;
}
```
---
## Unreal Engine Integration
1. Copy the library to your project:
```
YourProject/
├── Binaries/
│ └── Win64/
│ └── fastnet.dll
└── Source/
└── YourGame/
├── fastnet.h
└── FastNet.h (C++ wrapper)
```
2. Update your `Build.cs`:
```csharp
PublicAdditionalLibraries.Add(
Path.Combine(ModuleDirectory, "..", "..", "Binaries", "Win64", "fastnet.dll")
);
```
3. Use in your code:
```cpp
#include "FastNet.h"
TUniquePtr<FFastNetClient> NetworkClient;
void UMyGameInstance::Init()
{
NetworkClient = MakeUnique<FFastNetClient>();
if (NetworkClient->Connect("127.0.0.1", 7778))
{
UE_LOG(LogTemp, Log, TEXT("Connected to server!"));
}
}
void UMyGameInstance::Tick(float DeltaTime)
{
FFastNetEvent Event;
while (NetworkClient->Poll(Event))
{
switch (Event.Type)
{
case EFastNetEventType::Data:
ProcessNetworkData(Event.Data);
break;
}
}
}
```
---
## P2P Networking
Direct peer-to-peer connections with NAT traversal, eliminating the need for a dedicated relay server.
```rust
use fastnet::p2p::{P2PSocket, P2PEvent};
#[tokio::main]
async fn main() -> std::io::Result<()> {
// Connect to signaling server
let mut socket = P2PSocket::connect("signaling.example.com:9000").await?;
// Join a room to discover peers
socket.join_room("game-room-123").await?;
loop {
for event in socket.poll().await? {
match event {
P2PEvent::PeerConnected(peer_id) => {
println!("Direct connection to peer {}", peer_id);
socket.send(peer_id, b"Hello!".to_vec()).await?;
}
P2PEvent::Data(peer_id, data) => {
println!("From {}: {:?}", peer_id, data);
}
P2PEvent::PeerRelayed(peer_id) => {
println!("Peer {} using relay (NAT traversal failed)", peer_id);
}
_ => {}
}
}
}
}
```
**Features:**
- UDP hole-punching for NAT traversal
- Automatic relay fallback when direct connection fails
- Room-based peer discovery
- End-to-end encryption (ChaCha20-Poly1305)
---
## TCP Fallback
Automatic fallback to TCP when UDP is blocked (corporate firewalls, some mobile networks).
```rust
use fastnet::tcp::{HybridSocket, TransportMode};
#[tokio::main]
async fn main() -> std::io::Result<()> {
// Automatically tries UDP, falls back to TCP if blocked
let mut socket = HybridSocket::connect("game.example.com:7778").await?;
match socket.transport_mode() {
TransportMode::Udp => println!("Using UDP (optimal)"),
TransportMode::Tcp => println!("Using TCP (fallback)"),
}
// API is identical regardless of transport
socket.send(1, 0, b"Hello!".to_vec()).await?;
Ok(())
}
```
---
## Asset Distribution
Efficient large file transfers with chunking, compression, and integrity verification.
```rust
use fastnet::assets::{AssetServer, AssetClient, AssetEvent};
// Server: Register and serve assets
let mut server = AssetServer::new(Default::default());
server.register("map.pak", "/game/maps/forest.pak").await?;
// Handle requests
if let Some((transfer_id, info)) = server.handle_request(peer_id, "map.pak") {
// Send chunks
while let Some(chunk) = server.get_next_chunk(transfer_id)? {
send_to_peer(peer_id, chunk);
}
}
// Client: Download assets
let mut client = AssetClient::new();
client.start_download(transfer_id, info, "/local/maps/forest.pak")?;
// Process chunks
client.receive_chunk(chunk)?;
for event in client.poll_events() {
match event {
AssetEvent::Progress { received, total, .. } => {
println!("Download: {:.1}%", (received as f64 / total as f64) * 100.0);
}
AssetEvent::Completed { path, .. } => {
println!("Downloaded: {:?}", path);
}
_ => {}
}
}
```
**Features:**
- 64KB chunked transfers
- LZ4 compression for faster transfers
- BLAKE3 hash verification (per-chunk and per-file)
- Resumable downloads with `resume_download()`
- Pause/cancel with `pause_transfer()`, `cancel_transfer()`
- Transfer statistics with `get_transfer_stats()`
- Retry tracking for failed chunks
---
## Performance Tuning
FastNet includes OS-level optimizations for minimal jitter:
```rust
use fastnet::net::fast::{SocketConfig, batch};
// Apply low-latency configuration
let config = SocketConfig::low_latency();
// - SO_RCVBUF/SO_SNDBUF: 8MB
// - SO_BUSY_POLL: 100µs
// - IP_TOS: 0xB8 (DSCP EF)
// - SO_PRIORITY: 6
// Batch sending (Linux only)
let mut send_batch = batch::SendBatch::new();
send_batch.push(&packet_data, peer_addr);
send_batch.push(&packet_data2, peer_addr2);
batch::sendmmsg(&socket, &send_batch)?;
```
**Linux Tuning Options:**
- `SO_RCVBUF`/`SO_SNDBUF`: 4-8MB buffers
- `SO_BUSY_POLL`: CPU polling for ~10µs latency reduction
- `IP_TOS`: DSCP EF (Expedited Forwarding) for QoS
- `sendmmsg`/`recvmmsg`: Batch multiple packets per syscall
---
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ Application │
├─────────────────────────────────────────────────────────────────┤
│ SecureSocket │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ TLS 1.3 │ │ ChaCha20 │ │ Channels │ │
│ │ Handshake │──│ Poly1305 │──│ (Reliable/ │ │
│ │ (~40ms) │ │ Encryption │ │ Unreliable) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ UDP Transport │ │
│ │ (Zero-copy) │ │
│ └───────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
### Security Model
1. **Connection**: Client connects via TCP for TLS 1.3 handshake
2. **Key Exchange**: Server generates unique ChaCha20 keys per client
3. **Data Transfer**: All UDP packets encrypted with AEAD
4. **Authentication**: Each packet includes authentication tag
---
## Channels
| `0` - Reliable Ordered | Chat, Commands | Guaranteed delivery & order |
| `1` - Unreliable | Position updates | Fast, may drop |
| `2` - Reliable Unordered | Item pickups | Guaranteed, any order |
| `3` - Sequenced | Input, Voice | Latest packet only |
---
## Generating Certificates
For development:
```bash
# Generate self-signed certificate (valid for 365 days)
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem \
-days 365 -nodes \
-subj "/CN=localhost"
```
For production, use certificates from Let's Encrypt or your CA.
---
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
---
<p align="center">
Made with ⚡ for game developers who demand speed and security
</p>