pub struct VCLConnection { /* private fields */ }Expand description
A secure VCL Protocol connection over UDP.
Each connection manages its own cryptographic state: independent send/receive hash chains, nonce tracking, shared secret, Ed25519 key pair, flow controller, and fragment reassembler.
§Example — Server
use vcl_protocol::connection::VCLConnection;
#[tokio::main]
async fn main() {
let mut server = VCLConnection::bind("127.0.0.1:8080").await.unwrap();
server.accept_handshake().await.unwrap();
loop {
match server.recv().await {
Ok(packet) => println!("{}", String::from_utf8_lossy(&packet.payload)),
Err(e) => { eprintln!("{}", e); break; }
}
}
}§Example — Client
use vcl_protocol::connection::VCLConnection;
#[tokio::main]
async fn main() {
let mut client = VCLConnection::bind("127.0.0.1:0").await.unwrap();
client.connect("127.0.0.1:8080").await.unwrap();
client.send(b"Hello!").await.unwrap();
client.close().unwrap();
}Implementations§
Source§impl VCLConnection
impl VCLConnection
Sourcepub async fn bind(addr: &str) -> Result<Self, VCLError>
pub async fn bind(addr: &str) -> Result<Self, VCLError>
Bind a new VCL connection to a local UDP address using the default config.
Use "127.0.0.1:0" to let the OS assign a port (typical for clients).
§Errors
Returns VCLError::IoError if the socket cannot be bound.
Sourcepub async fn bind_with_config(
addr: &str,
config: VCLConfig,
) -> Result<Self, VCLError>
pub async fn bind_with_config( addr: &str, config: VCLConfig, ) -> Result<Self, VCLError>
Bind a new VCL connection with a specific VCLConfig.
The config controls fragmentation threshold, flow window size, reliability mode, and transport selection.
§Errors
Returns VCLError::IoError if the socket cannot be bound.
Sourcepub fn subscribe(&mut self) -> Receiver<VCLEvent>
pub fn subscribe(&mut self) -> Receiver<VCLEvent>
Subscribe to connection events.
Returns an async mpsc::Receiver<VCLEvent> with a channel capacity of 64.
Call this before connect() or accept_handshake() to receive
the VCLEvent::Connected event.
Events are sent with try_send — if the channel is full, events are dropped silently.
Sourcepub fn set_timeout(&mut self, secs: u64)
pub fn set_timeout(&mut self, secs: u64)
Set the inactivity timeout in seconds (default: 60).
Set to 0 to disable the timeout.
Sourcepub fn get_timeout(&self) -> u64
pub fn get_timeout(&self) -> u64
Get the current inactivity timeout in seconds.
Sourcepub fn last_activity(&self) -> Instant
pub fn last_activity(&self) -> Instant
Get the Instant of the last send() or recv() activity.
Sourcepub fn get_config(&self) -> &VCLConfig
pub fn get_config(&self) -> &VCLConfig
Get a reference to the current VCLConfig.
Sourcepub fn flow(&self) -> &FlowController
pub fn flow(&self) -> &FlowController
Get a reference to the FlowController for inspecting flow stats.
Sourcepub fn ack_packet(&mut self, sequence: u64) -> bool
pub fn ack_packet(&mut self, sequence: u64) -> bool
Manually acknowledge a sent packet by sequence number.
Returns true if the packet was found and removed from the in-flight window.
Override the Ed25519 signing key with a pre-shared key.
⚠️ For testing only. Never use a pre-shared key in production.
Sourcepub async fn connect(&mut self, addr: &str) -> Result<(), VCLError>
pub async fn connect(&mut self, addr: &str) -> Result<(), VCLError>
Connect to a remote VCL server and perform the X25519 handshake.
After this returns Ok(()), the connection is ready to send() and recv().
Emits VCLEvent::Connected if subscribed.
§Errors
VCLError::IoError— socket or address errorVCLError::HandshakeFailed— key exchange failedVCLError::ExpectedServerHello— unexpected handshake message
Sourcepub async fn accept_handshake(&mut self) -> Result<(), VCLError>
pub async fn accept_handshake(&mut self) -> Result<(), VCLError>
Accept an incoming X25519 handshake from a client (server side).
Blocks until a ClientHello is received.
After this returns Ok(()), the connection is ready to send() and recv().
Emits VCLEvent::Connected if subscribed.
§Errors
VCLError::IoError— socket errorVCLError::HandshakeFailed— key exchange failedVCLError::ExpectedClientHello— unexpected handshake message
Sourcepub async fn send(&mut self, data: &[u8]) -> Result<(), VCLError>
pub async fn send(&mut self, data: &[u8]) -> Result<(), VCLError>
Encrypt, sign, and send a data packet to the peer.
If the payload exceeds config.fragment_size, it is automatically split
into PacketType::Fragment packets and reassembled transparently on the receiver.
§Errors
VCLError::ConnectionClosed— connection was closedVCLError::Timeout— inactivity timeout exceededVCLError::NoSharedSecret— handshake not completedVCLError::NoPeerAddress— peer address unknownVCLError::IoError— socket error
Sourcepub async fn ping(&mut self) -> Result<(), VCLError>
pub async fn ping(&mut self) -> Result<(), VCLError>
Send a ping to the peer to check liveness and measure round-trip latency.
The pong reply is handled transparently inside recv().
Subscribe to events to receive VCLEvent::PongReceived { latency }.
⚠️ You must keep calling recv() for the pong to be processed.
Sourcepub async fn rotate_keys(&mut self) -> Result<(), VCLError>
pub async fn rotate_keys(&mut self) -> Result<(), VCLError>
Initiate a mid-session key rotation using a fresh X25519 ephemeral exchange.
Emits VCLEvent::KeyRotated on success.
⚠️ The peer must be actively calling recv() during rotation.
⚠️ Do not call send() while rotate_keys() is awaiting a response.
Sourcepub async fn recv(&mut self) -> Result<VCLPacket, VCLError>
pub async fn recv(&mut self) -> Result<VCLPacket, VCLError>
Receive the next data packet from the peer.
Control packets (Ping, Pong, KeyRotation) and fragment packets are handled
transparently — this method loops internally until a complete Data packet arrives.
Large payloads that were fragmented by the sender are reassembled automatically.
On success, packet.payload contains the decrypted (and reassembled) data.
§Errors
VCLError::ConnectionClosed— connection was closedVCLError::Timeout— inactivity timeout exceededVCLError::ReplayDetected— duplicate sequence or nonceVCLError::ChainValidationFailed— hash chain brokenVCLError::SignatureInvalid— Ed25519 signature mismatchVCLError::CryptoError— decryption failedVCLError::IoError— socket error
Sourcepub fn close(&mut self) -> Result<(), VCLError>
pub fn close(&mut self) -> Result<(), VCLError>
Gracefully close the connection and clear all cryptographic state.
After calling close(), all further operations return VCLError::ConnectionClosed.
Emits VCLEvent::Disconnected if subscribed.
§Errors
Returns VCLError::ConnectionClosed if already closed.
Sourcepub fn get_public_key(&self) -> Vec<u8> ⓘ
pub fn get_public_key(&self) -> Vec<u8> ⓘ
Get the local Ed25519 public key (32 bytes).
Get the current X25519 shared secret, or None if the handshake
has not completed or the connection is closed.