Skip to main content

VCLConnection

Struct VCLConnection 

Source
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

Source

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.

Source

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.

Source

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.

Source

pub fn set_timeout(&mut self, secs: u64)

Set the inactivity timeout in seconds (default: 60).

Set to 0 to disable the timeout.

Source

pub fn get_timeout(&self) -> u64

Get the current inactivity timeout in seconds.

Source

pub fn last_activity(&self) -> Instant

Get the Instant of the last send() or recv() activity.

Source

pub fn get_config(&self) -> &VCLConfig

Get a reference to the current VCLConfig.

Source

pub fn flow(&self) -> &FlowController

Get a reference to the FlowController for inspecting flow stats.

Source

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.

Source

pub fn set_shared_key(&mut self, private_key: &[u8])

Override the Ed25519 signing key with a pre-shared key.

⚠️ For testing only. Never use a pre-shared key in production.

Source

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
Source

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
Source

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
Source

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.

Source

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.

Source

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
Source

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.

Source

pub fn is_closed(&self) -> bool

Returns true if the connection has been closed.

Source

pub fn get_public_key(&self) -> Vec<u8>

Get the local Ed25519 public key (32 bytes).

Source

pub fn get_shared_secret(&self) -> Option<[u8; 32]>

Get the current X25519 shared secret, or None if the handshake has not completed or the connection is closed.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more