Skip to main content

PhantomSession

Struct PhantomSession 

Source
pub struct PhantomSession { /* private fields */ }
Expand description

Client-first session — instant connect(), non-blocking send().

§Design

  let session = PhantomSession::connect("server:443");  // instant!
  session.send(data).await;   // queued until handshake completes
  session.send(data2).await;  // also queued
  // ... handshake completes in background ...
  // queued data auto-flushed, new sends go directly

The session progresses through states: Connecting → ClassicalReady → PqcUpgrading → PqcReady → Connected

Implementations§

Source§

impl PhantomSession

Source

pub fn connect_with_transport<T: SessionTransport>( peer_addr: &str, transport: T, expected_server_key: HybridVerifyingKey, ) -> Self

Create a new session and start the background handshake task.

Requires expected_server_key for MITM resistance — the client will abort the handshake unless the server presents this exact verifying key. Callers obtain this key out-of-band (e.g. from PhantomListener::verifying_key_bytes).

The handshake runs in the background:

  1. Exchange hybrid PQC ClientHello/ServerHello.
  2. Verify server identity against expected_server_key.
  3. Derive AEAD keys; flush queued sends as encrypted packets.

All network I/O goes through the provided SessionTransport. The task that drives the handshake + data pump runs on the default TokioRuntime; use connect_with_transport_with_runtime to substitute a different Runtime.

Source

pub fn connect_with_transport_with_runtime<T: SessionTransport>( peer_addr: &str, transport: T, expected_server_key: HybridVerifyingKey, runtime: Arc<dyn Runtime>, ) -> Self

Like connect_with_transport but runs the background task on the supplied Runtime. Intended for WASM / embedded / test backends that don’t drive tokio::spawn.

Source

pub fn connect_with_resumption<T: SessionTransport>( peer_addr: &str, transport: T, expected_server_key: HybridVerifyingKey, resumption_hint: ([u8; 32], [u8; 32]), early_data: Vec<u8>, ) -> Result<Self, CoreError>

Connect with a 0-RTT resumption attempt.

resumption_hint is the (session_id, resumption_secret) tuple from a prior session’s PhantomSession::resumption_hint. early_data (≤ EARLY_DATA_MAX_LEN bytes) is sealed and carried inside the resuming ClientHello so it reaches the server on the very first flight — saving a round-trip versus 1-RTT.

Acceptance is best-effort: a stale/unknown ticket or an AEAD failure leaves early_data_accepted at Some(false) and the handshake completes as a normal 1-RTT exchange — the caller must then send that payload over the normal channel. Returns Err only when early_data exceeds the cap.

Runs on the default TokioRuntime.

Source§

impl PhantomSession

Source

pub fn observability(&self) -> Arc<Observability>

Session observability handle (Rust-only — Observability is not a UniFFI type). For a server-accepted session this is the PhantomListener’s shared instance; for a client it is the session’s own. Read .snapshot() for the lock-free metric counters.

Source§

impl PhantomSession

Source

pub fn connect(peer_addr: String) -> Arc<Self>

Create a new session — returns instantly.

Handshake is not started until a transport is provided. Use connect_with_transport() for full integration.

Source

pub fn open_stream(&self) -> Arc<PhantomStream>

Open a new multiplexed stream

Source

pub async fn send(&self, data: Vec<u8>) -> Result<(), CoreError>

Send data through the session.

  • If the session is connected: sends immediately
  • If still handshaking: queues the data for auto-flush later
Source

pub async fn recv(&self) -> Result<Vec<u8>, CoreError>

Receive data from the session.

Internally the recv pipeline keeps payloads as Bytes to avoid the per-packet Vec clone that used to fan out to the stream demux. The FFI surface still hands callers a Vec<u8>; if this is the last refcount the Vec is moved out of the underlying buffer, otherwise Bytes::to_vec copies.

Source

pub fn connection_state(&self) -> ConnectionState

Get the current connection state (lock-free).

Source

pub fn is_data_ready(&self) -> bool

Whether the session is ready for data transmission.

Source

pub fn is_pqc_ready(&self) -> bool

Whether the session has full PQC protection.

Source

pub async fn flush_queue(&self) -> Result<u32, CoreError>

Flush all queued messages (called when handshake completes).

Source

pub async fn queued_count(&self) -> u32

Number of messages queued (waiting for handshake).

Source

pub fn id(&self) -> String

Session identifier.

Source

pub fn peer_addr(&self) -> String

Target peer address.

Source

pub async fn early_data_accepted(&self) -> Option<bool>

The 0-RTT verdict for this session.

  • None — still handshaking, the handshake failed, or the client sent no early-data on this connect.
  • Some(true) — the server consumed the 0-RTT early-data.
  • Some(false) — the client sent early-data and the server rejected it (stale/unknown ticket, oversized blob, or AEAD failure). The caller must re-send that payload over the normal channel.
Source

pub async fn resumption_hint(&self) -> Option<ResumptionHint>

Extract a ResumptionHint for a future 0-RTT reconnect.

Returns Some after a successful handshake; None while still handshaking, after a failure, or before the inner session has been published.

Store the hint alongside the pinned HybridVerifyingKey of the server it was negotiated against and feed it back to connect_pinned_with_resumption. Reusing a hint across servers is a configuration bug — the resumption_secret is server-pinned.

Source

pub async fn current_epoch(&self) -> Option<u8>

Current rekey epoch of the established session (None while still connecting). Rust-only — used by soak / integration tests to confirm that automatic mid-session rekey (C1) advanced the epoch.

Source

pub async fn set_rekey_threshold(&self, n: u64) -> bool

Override the automatic-rekey send-invocation high-watermark on the established session (default REKEY_SOFT_LIMIT). Returns false if the session is still connecting. Rust-only — primarily for soak/load harnesses that need to exercise mid-session rekey without sending 2^47 packets.

Source

pub async fn disconnect(&self) -> Result<(), CoreError>

Send the graceful close frame and shut the session down.

Named disconnect rather than close because UniFFI’s Kotlin generator unconditionally adds AutoCloseable.close() to every object, and a Rust-side close here would conflict with it.

Source§

impl PhantomSession

Source

pub fn demux(&self) -> Arc<StreamDemultiplexer>

Get the stream demultiplexer (internal use, not exposed to UniFFI)

Trait Implementations§

Source§

impl Debug for PhantomSession

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<UT> LiftRef<UT> for PhantomSession

Source§

impl<UT> LowerError<UT> for PhantomSession

Source§

fn lower_error(obj: Self) -> RustBuffer

Lower this value for scaffolding function return Read more
Source§

impl<UT> LowerReturn<UT> for PhantomSession

Source§

type ReturnType = <Arc<PhantomSession> as LowerReturn<UniFfiTag>>::ReturnType

The type that should be returned by scaffolding functions for this type. Read more
Source§

fn lower_return(obj: Self) -> Result<Self::ReturnType, RustCallError>

Lower the return value from an scaffolding call Read more
Source§

fn handle_failed_lift( error: LiftArgsError, ) -> Result<Self::ReturnType, RustCallError>

Lower the return value for failed argument lifts Read more
Source§

impl<UT> TypeId<UT> for PhantomSession

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CompatExt for T

Source§

fn compat(self) -> Compat<T>
where T: Sized,

Applies the Compat adapter by value. Read more
Source§

fn compat_ref(&self) -> Compat<&T>

Applies the Compat adapter by shared reference. Read more
Source§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the Compat adapter by mutable reference. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

Source§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
Source§

unsafe fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
Source§

unsafe fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<> Read more
Source§

unsafe fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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