UniUDP
Unidirectional UDP transport for Rust — send messages reliably over UDP without requiring a back-channel. UniUDP handles chunking, reassembly, redundancy, forward error correction, packet authentication, and replay protection so you can focus on your application.
Why UniUDP?
Standard UDP gives you raw datagrams with no delivery guarantees. TCP gives you reliable streams but requires a bidirectional connection. UniUDP sits in between: it adds reliability mechanisms to UDP while remaining fully unidirectional — the receiver never sends packets back to the sender.
This makes UniUDP ideal for:
- Broadcast/multicast data distribution — one sender, many receivers
- Telemetry and sensor streaming — fire-and-forget with recovery
- Log shipping and event forwarding — reliable delivery without back-pressure
- Network-constrained environments — where return paths are unavailable or undesirable
Features
| Feature | Description |
|---|---|
| Chunked transport | Automatically splits messages up to 16 MB into configurable chunks (default 1024 bytes) |
| Packet redundancy | Retransmit each packet N times to survive packet loss |
| Forward error correction | Reed-Solomon erasure coding for multi-chunk recovery per group |
| Packet authentication | Optional HMAC-SHA256 per-packet auth with key ID rotation |
| Replay protection | Session tracking, message freshness windows, and deduplication |
| Source policy controls | Pin receivers to specific source addresses or IPs |
| Resource budgets | Configurable limits on pending messages, bytes, and sessions |
| Async support | Optional Tokio integration for non-blocking I/O |
| Thread-safe sender | Arc<Sender> sharing across threads with &self send methods |
| Diagnostics | Per-receive counters for packets, rejections, duplicates, and recoveries |
Installation
Add to your Cargo.toml:
[]
= "1"
For async/Tokio support:
[]
= { = "1", = ["tokio"] }
= { = "1", = ["macros", "rt", "net"] }
uniudp's tokio feature enables async APIs in this crate. Add a direct
tokio dependency when your application uses tokio::net::UdpSocket and
#[tokio::main] (as in the async example below).
Quick Start
Send and receive a message
use UdpSocket;
use Duration;
use SourcePolicy;
use ;
use Receiver;
use ;
Async with Tokio
use UdpSocket;
use Duration;
use SourcePolicy;
use ;
use Receiver;
use ;
async
Authenticated messages
use UdpSocket;
use ;
use ReceiverConfig;
use SendIdentityOverrides;
use Receiver;
use ;
#
The receiver can hold multiple keys simultaneously for seamless key rotation.
Core Concepts
Messages and Chunks
UniUDP splits each message into fixed-size chunks (default 1024 bytes), wraps each in an 84-byte header, and sends them as individual UDP datagrams. The receiver reassembles chunks back into the original message.
Reliability Without a Back-Channel
Since there is no return path, UniUDP provides two mechanisms to handle packet loss:
- Redundancy (
with_redundancy(n)) — sends each packetntimes. Simple and effective for uniform loss. - Reed-Solomon FEC (
with_fec_mode(FecMode::ReedSolomon { data_shards, parity_shards })) — generates parity shards per group, recovering up toparity_shardsmissing data chunks per group.
Both can be combined. The MessageReport tells you exactly which chunks were received, lost, or recovered via FEC.
Choosing FEC Parameters
Reed-Solomon FEC is configured with data_shards (chunks per group) and parity_shards (recovery chunks per group). More parity shards improve loss tolerance at the cost of bandwidth.
| Scenario | Config | Overhead | Recovers |
|---|---|---|---|
| General purpose | data_shards: 4, parity_shards: 2 |
50% | Up to 2 lost chunks per group |
| Bandwidth-constrained | data_shards: 8, parity_shards: 1 |
12.5% | 1 per group |
| High loss (>15%) | data_shards: 4, parity_shards: 4 |
100% | Up to 4 per group |
| Maximum resilience | data_shards: 4, parity_shards: 2 + redundancy: 2 |
3x total | FEC + full duplication |
For most workloads, data_shards: 4, parity_shards: 2 is a good starting point. See Performance for detailed tuning guidance.
Identity and Sessions
Each Sender has a 128-bit SenderId and a random session_nonce. Together with a monotonically increasing message_id, these form a MessageKey that uniquely identifies every message. The receiver uses this identity triple for deduplication, replay protection, and freshness checks.
Source Policies
Control which network sources the receiver accepts packets from:
| Policy | Behavior |
|---|---|
AnyFirstSource |
Accept from any address; pin to the first source seen |
Exact(addr) |
Only accept from a specific SocketAddr |
SameIp |
Accept any port from the first source's IP |
Timeouts and Completion
Receive operations use two timeouts:
- Inactivity timeout (default 500ms) — how long to wait with no new packets before giving up
- Overall timeout (default 5s) — maximum total wait time
The MessageReport includes a CompletionReason (Completed, InactivityTimeout, or OverallTimeout) so your application can distinguish full delivery from partial results.
Send Options
use Duration;
use FecMode;
use SendOptions;
#
Receive Options
use Duration;
use SourcePolicy;
use ReceiveOptions;
# use MessageKey;
#
Receiver Configuration
For advanced deployments, tune receiver resource budgets and security policies:
use Duration;
use ;
use ;
use Receiver;
#
Working with Results
use Duration;
use SourcePolicy;
use ReceiveOptions;
use Receiver;
# use MessageKey;
#
Diagnostics
After each receive, inspect packet-level counters:
use Receiver;
#
API Modules
| Module | Contents |
|---|---|
uniudp::sender |
Sender, SenderBuilder, SendRequest, SendFailure, MessageIdStart |
uniudp::receiver |
Receiver, ReceiveLoopControl |
uniudp::options |
SendOptions, ReceiveOptions, SendIdentityOverrides, ReceiveDiagnostics |
uniudp::message |
MessageKey, SenderId, SourcePolicy, MessageReport, CompletionReason |
uniudp::config |
ReceiverConfig, AuthMode, protocol constants |
uniudp::auth |
PacketAuth, PacketAuthKey |
uniudp::packet |
PacketHeader, encoding/decoding, ParsedPacket |
uniudp::fec |
FecMode, Reed-Solomon field encoding/decoding |
uniudp::prelude |
Common imports for quick setup |
Examples
Run the included examples:
Detailed Documentation
- Protocol — packet layout, header fields, encoding invariants
- Security — threat model, authentication, replay protection
- Performance — tuning chunking, redundancy, FEC, and receiver budgets
Benchmarks
Benchmarks cover packet encode/decode, FEC recovery, and end-to-end loopback throughput.
License
MIT