pub struct NetSession { /* private fields */ }Expand description
Session state after handshake completion.
Implementations§
Source§impl NetSession
impl NetSession
Sourcepub fn new(
keys: SessionKeys,
peer_addr: SocketAddr,
pool_size: usize,
default_reliable: bool,
) -> Self
pub fn new( keys: SessionKeys, peer_addr: SocketAddr, pool_size: usize, default_reliable: bool, ) -> Self
Create a new session from handshake results
Sourcepub fn cached_node_id(&self) -> Option<u64>
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.
Sourcepub fn cache_node_id(&self, node_id: u64)
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.
Sourcepub fn next_control_tx_seq(&self) -> u64
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.
Sourcepub fn session_id(&self) -> u64
pub fn session_id(&self) -> u64
Get the session ID
Sourcepub fn peer_addr(&self) -> SocketAddr
pub fn peer_addr(&self) -> SocketAddr
Get the peer address
Sourcepub fn get_or_create_stream(
&self,
stream_id: u64,
) -> RefMut<'_, u64, StreamState>
pub fn get_or_create_stream( &self, stream_id: u64, ) -> RefMut<'_, u64, StreamState>
Get or create stream state
Sourcepub fn try_stream(&self, stream_id: u64) -> Option<Ref<'_, u64, StreamState>>
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.
Sourcepub fn try_acquire_tx_credit_guard(
self: &Arc<Self>,
stream_id: u64,
bytes: u32,
) -> TxAdmit
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::Acquiredwith aTxSlotGuardthat refundsbytesback totx_credit_remainingwhen dropped — including on async cancellation, panic, and early return — unless the caller invokesTxSlotGuard::committo 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::WindowFulliftx_credit_remainingis belowbytes.backpressure_eventshas already been bumped.TxAdmit::StreamClosedif the stream isn’t registered (never opened, closed, or idle-evicted).
Sourcepub fn try_acquire_tx_credit_matching_epoch(
self: &Arc<Self>,
stream_id: u64,
expected_epoch: u64,
bytes: u32,
) -> TxAdmit
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
impl NetSession
Sourcepub fn open_stream_with(
&self,
stream_id: u64,
reliable: bool,
fairness_weight: u8,
) -> u64
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.
Sourcepub fn open_stream_full(
&self,
stream_id: u64,
reliable: bool,
fairness_weight: u8,
tx_window: u32,
) -> u64
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.
Sourcepub fn close_stream(&self, stream_id: u64)
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.
Sourcepub fn is_grant_quarantined(&self, stream_id: u64) -> bool
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.
Sourcepub fn evict_idle_streams(
&self,
max_idle: Duration,
max_streams: usize,
reason_tag: &'static str,
) -> usize
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.
Sourcepub fn get_stream(&self, stream_id: u64) -> Option<Ref<'_, u64, StreamState>>
pub fn get_stream(&self, stream_id: u64) -> Option<Ref<'_, u64, StreamState>>
Get stream state (read-only)
Sourcepub fn thread_local_pool(&self) -> &SharedLocalPool
pub fn thread_local_pool(&self) -> &SharedLocalPool
Get the thread-local pool for zero-contention packet building
Sourcepub fn build_heartbeat(&self) -> Bytes
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.
Sourcepub fn verify_and_touch_heartbeat(&self, parsed: &ParsedPacket) -> bool
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.
Sourcepub fn last_activity_ns(&self) -> u64
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.
Sourcepub fn is_timed_out(&self, timeout: Duration) -> bool
pub fn is_timed_out(&self, timeout: Duration) -> bool
Check if session has timed out
Sourcepub fn deactivate(&self)
pub fn deactivate(&self)
Deactivate the session
Sourcepub fn stream_ids(&self) -> Vec<u64>
pub fn stream_ids(&self) -> Vec<u64>
Get all stream IDs
Sourcepub fn stream_count(&self) -> usize
pub fn stream_count(&self) -> usize
Get the number of streams