Skip to main content

hydra_sync/
lib.rs

1//! # hydra-sync: A Lightweight Zero-Copy E2E SPMC Relay Network Library
2//!
3//! `hydra-sync` is a high-performance, end-to-end encrypted relay library for single producer,
4//! multiple consumer (SPMC) network architectures. It provides a simple yet powerful abstraction
5//! for building distributed systems where one producer broadcasts encrypted data to many consumers
6//! with minimal latency and memory overhead.
7//!
8//! ### Overview
9//!
10//! The library is organized around two main components:
11//!
12//! - **Server** ([`server`]): Manages relay state, maintains active sessions, and routes encrypted frames
13//!   from producers to their respective consumers. Uses `DashMap` for thread-safe session storage.
14//!
15//! - **Client** ([`client`]): Connects to the relay server as either a producer or consumer. Producers
16//!   broadcast encrypted frames, while consumers receive and decrypt them from the internal memory pool.
17//!
18//! ### Protocol
19//!
20//! The protocol consists of two phases:
21//!
22//! 1. **Handshake**: Client and server establish a transport key via X25519 Diffie-Hellman key & nonce exchange.
23//!    This transport key encrypts join and control frames.
24//!
25//! 2. **Data Transfer**: Producers encrypt broadcast frames using AES-GCM with a session-specific key.
26//!    Consumers decrypt received frames using the same session key. Each frame includes an AEAD tag
27//!    for integrity verification. (NO SERVER INTERVENTION IN DATA TRANSFER, SERVER ONLY RELAYS ENCRYPTED FRAMES)
28//!
29//!
30//! #### Quick Example
31//!
32//! ```no_run
33//!use hydra_sync::client::{HydraClient, Producer, Consumer};
34//!use hydra_sync::server::HydraServer;
35//!use anyhow::Result;
36//!
37//!#[tokio::main]
38//!async fn main() -> anyhow::Result<()> {
39//!    let (server, server_addr) = HydraServer::bind_default().await?; // bind to os-assigned port
40//!    let session_id = [0xFFu8; 64];
41//!    let session_key = [0xAAu8; 32];
42//!
43//!    tokio::spawn(async move { server.run(500).await }); // run in background
44//!
45//!    // Producer; sends data to all consumers in the session
46//!    let mut producer =
47//!        HydraClient::<Producer>::connect(server_addr, &session_id, session_key).await?;
48//!    producer.broadcast(b"you are an idiot").await?;
49//!
50//!    // Consumer; receives and decrypts frames from the producer
51//!    let mut consumer =
52//!        HydraClient::<Consumer>::connect(server_addr, &session_id, session_key).await?;
53//!
54//!    loop {
55//!        let data = consumer.recv().await?;
56//!        println!("received {} bytes: {:?}", data.len(), data);
57//!
58//!        // `data` borrows from `consumer`'s internal memory pool and is
59//!        // only valid until the next `recv()` call.
60//!        // Copy it out (e.g. `data.to_vec()`) if you need to keep it longer.
61//!        break;
62//!     }
63//!     producer.close().await?; // clean shutdown
64//!
65//!     Ok(())
66//!}
67//! ```
68//!
69//! ### Memory Overhead
70//!
71//! Each client maintains a 18 MB internal memory pool (`BytesMut`) for:
72//! - Buffering encrypted frames during read/write operations
73//! - In-place encryption and decryption without allocating new buffers
74//! - Reusing memory across multiple `recv()`/`broadcast()` calls
75//!
76//! This zero-copy design minimizes garbage collection pressure and reduces latency for
77//! high-throughput scenarios.
78//!
79pub mod client;
80pub mod crypto;
81pub(crate) mod log;
82pub(crate) mod protocol;
83pub mod server;
84pub(crate) mod session;
85
86/// Buffer size for `BufReader` and `BufWriter` in TCP operations (6 MB)
87pub const BUFFER_SIZE: usize = 1024 * 1024 * 6;