Skip to main content

NetSession

Struct NetSession 

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

Session state after handshake completion.

Implementations§

Source§

impl NetSession

Source

pub fn new( keys: SessionKeys, peer_addr: SocketAddr, pool_size: usize, default_reliable: bool, ) -> Self

Create a new session from handshake results

Source

pub fn cached_node_id(&self) -> Option<u64>

Read the cached peer NodeId resolution. Returns None until the dispatcher’s first resolution call publishes a value via Self::cache_node_id. See the field doc for the perf rationale.

Source

pub fn cache_node_id(&self, node_id: u64)

Publish the resolved peer NodeId for subsequent calls. Idempotent — concurrent first-resolution callers all write the same value (the resolver is deterministic for a given session_id), so a store over an existing identical value is correct. Callers should pass non-zero node_id; 0 is the reserved “unresolved” sentinel and is a no-op.

Source

pub fn next_control_tx_seq(&self) -> u64

Allocate the next sequence number for a subprotocol control packet. Uses a session-level counter separate from any user stream’s sequence space — see CONTROL_STREAM_ID.

Source

pub fn session_id(&self) -> u64

Get the session ID

Source

pub fn peer_addr(&self) -> SocketAddr

Get the peer address

Source

pub fn rx_cipher(&self) -> &PacketCipher

Get the RX cipher

Source

pub fn get_or_create_stream( &self, stream_id: u64, ) -> RefMut<'_, u64, StreamState>

Get or create stream state

Source

pub fn try_stream(&self, stream_id: u64) -> Option<Ref<'_, u64, StreamState>>

Look up stream state without creating it. Returns None if the stream was never opened or has been closed.

Source

pub fn try_acquire_tx_credit_guard( self: &Arc<Self>, stream_id: u64, bytes: u32, ) -> TxAdmit

Try to acquire bytes of send credit on stream_id with RAII refund semantics.

Returns:

  • TxAdmit::Acquired with a TxSlotGuard that refunds bytes back to tx_credit_remaining when dropped — including on async cancellation, panic, and early return — unless the caller invokes TxSlotGuard::commit to suppress the refund after a successful socket send. This is the cure for the credit-leak that a plain “decrement / await / maybe-refund” shape would hit when the sending future is dropped mid-.await (e.g., tokio::select! cancel).
  • TxAdmit::WindowFull if tx_credit_remaining is below bytes. backpressure_events has already been bumped.
  • TxAdmit::StreamClosed if the stream isn’t registered (never opened, closed, or idle-evicted).
Source

pub fn try_acquire_tx_credit_matching_epoch( self: &Arc<Self>, stream_id: u64, expected_epoch: u64, bytes: u32, ) -> TxAdmit

Like Self::try_acquire_tx_credit_guard, but additionally rejects the admission if the live StreamState’s epoch differs from expected_epoch.

Use from the typed-handle send_on_stream path so a handle held across a close+reopen cycle doesn’t admit against the new stream’s state.

Source§

impl NetSession

Source

pub fn open_stream_with( &self, stream_id: u64, reliable: bool, fairness_weight: u8, ) -> u64

Open a stream with an explicit reliability mode and fair-scheduler weight.

Idempotent: if the stream already exists, this is a no-op and the caller’s config is ignored with a warning log — the first open wins. Callers that want to change a stream’s config must close + re-open it.

Source

pub fn open_stream_full( &self, stream_id: u64, reliable: bool, fairness_weight: u8, tx_window: u32, ) -> u64

Extended open that also sets the per-stream TX window for backpressure. tx_window == 0 keeps the pre-backpressure behavior (unbounded local queue).

Returns the epoch of the live StreamState for stream_id — either the fresh one created for a new stream, or the existing one if the stream is already open (first-open-wins). Callers embed this in their Stream handle so later sends can reject stale handles after close+reopen.

Source

pub fn close_stream(&self, stream_id: u64)

Close a stream: mark it inactive and remove its state.

Idempotent — closing a non-existent stream is a no-op. After close, a subsequent open_stream_with creates a fresh stream.

Also records stream_id in the grant-quarantine set so that any StreamWindow grant still in flight from a peer who was communicating with the just-closed lifetime is dropped rather than spuriously crediting a later reopen — see GRANT_QUARANTINE_WINDOW and Self::is_grant_quarantined.

Source

pub fn is_grant_quarantined(&self, stream_id: u64) -> bool

Whether a StreamWindow grant for stream_id should be dropped because the stream was closed within GRANT_QUARANTINE_WINDOW. Lazily garbage-collects expired entries on call.

Source

pub fn evict_idle_streams( &self, max_idle: Duration, max_streams: usize, reason_tag: &'static str, ) -> usize

Remove streams whose last_activity is older than max_idle, keeping the active count at or below max_streams by LRU-evicting the oldest if still over cap. Returns the number of streams evicted. Called from the session owner’s heartbeat loop.

Source

pub fn get_stream(&self, stream_id: u64) -> Option<Ref<'_, u64, StreamState>>

Get stream state (read-only)

Source

pub fn thread_local_pool(&self) -> &SharedLocalPool

Get the thread-local pool for zero-contention packet building

Source

pub fn build_heartbeat(&self) -> Bytes

Build an AEAD-authenticated heartbeat packet for this session.

Routes through thread_local_pool so the heartbeat shares its TX counter with data-path packets — heartbeats and data interleave cleanly on the wire, and the receiver’s replay window admits them in either order.

Wrapping heartbeat construction in this method removes the surface that would otherwise let callers build heartbeats with a fresh PacketBuilder::new(&[0u8; 32], session_id), which (a) would use the wrong key so the receiver’s AEAD verify would reject every heartbeat, and (b) would reuse counter=0 across successive heartbeats so the replay window would reject every heartbeat after the first.

Source

pub fn verify_and_touch_heartbeat(&self, parsed: &ParsedPacket) -> bool

Verify an inbound heartbeat’s AEAD tag against this session’s RX cipher, commit the counter into the replay window, and refresh last_activity. Returns true if the packet was accepted; the session is mutated only on success.

Verify and touch are fused into a single call so callers cannot get the order wrong (verify-then-touch, never the reverse) or forget to touch (which would defeat session idle-timeout for legitimate heartbeats).

Source-address validation (legacy adapter: 1:1 source per session) and any post-accept observation (mesh: failure_detector.heartbeat) remain the caller’s responsibility — those policies vary by adapter and don’t belong inside the helper.

Heartbeats MUST decrypt the AEAD tag rather than be fast- pathed through to failure_detector.heartbeat and session.touch() based on is_heartbeat() alone — without the decrypt step, an off-path attacker who observed the cleartext session_id and source UDP address could spoof heartbeats indefinitely.

Source

pub fn touch(&self)

Update last activity timestamp

Source

pub fn last_activity_ns(&self) -> u64

Nanoseconds since epoch of the last activity. Useful for tests / diagnostics that need to observe whether touch has been called.

Source

pub fn is_timed_out(&self, timeout: Duration) -> bool

Check if session has timed out

Source

pub fn is_active(&self) -> bool

Check if session is active

Source

pub fn deactivate(&self)

Deactivate the session

Source

pub fn stream_ids(&self) -> Vec<u64>

Get all stream IDs

Source

pub fn stream_count(&self) -> usize

Get the number of streams

Trait Implementations§

Source§

impl Debug for NetSession

Source§

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

Formats the value using the given formatter. Read more

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<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