IdentitySlot

Struct IdentitySlot 

Source
pub struct IdentitySlot<I: NodeIdentity, const PEERS: usize, const ACKS: usize, const FRAME: usize = MAX_RESEND_FRAME_LEN> { /* private fields */ }
Expand description

Per-identity runtime state owned by the Mac coordinator.

There is exactly one IdentitySlot per registered local identity (LocalIdentityId). The slot bundles everything the coordinator needs to send, receive, and authenticate on behalf of a single local keypair:

  • The LocalIdentity (public key + ECDH capability).
  • A PeerCryptoMap mapping each known remote peer to its established umsh_crypto::PairwiseKeys and replay window. Entries are populated on first secure contact, or through the advanced manual-install escape hatch.
  • A monotonically increasing frame counter stamped into SECINFO of every sealed packet, plus the bookkeeping needed to persist it safely (see below).
  • A LinearMap of in-flight PendingAck records keyed by SendReceipt, one entry per ACK-requested send awaiting either forwarding confirmation or a final transport ACK.
  • An internal next_receipt counter used to issue unique SendReceipt values without allocation.

§Frame-counter persistence

UMSH uses a monotonic frame counter instead of a timestamp for replay protection. If the counter resets to a previously-seen value after a reboot, replayed old frames might be accepted. To prevent this, the coordinator “reserves” counter ranges by writing boundary values to the umsh_hal::CounterStore before using them. The slot tracks three values:

  • frame_counter — the live in-use value, advanced on every secured send.
  • persisted_counter — the last boundary safely committed to the store.
  • pending_persist_target — a scheduled future boundary written on the next call to Mac::service_counter_persistence.

If the live counter reaches persisted_counter + COUNTER_PERSIST_BLOCK_SIZE without a successful flush, secure sends on that identity are blocked (SendError::CounterPersistenceLag) until the store catches up. Ephemeral identities opt out of this mechanism entirely.

Implementations§

Source§

impl<I: NodeIdentity, const PEERS: usize, const ACKS: usize, const FRAME: usize> IdentitySlot<I, PEERS, ACKS, FRAME>

Source

pub fn new( identity: LocalIdentity<I>, frame_counter: u32, pfs_parent: Option<LocalIdentityId>, ) -> Self

Create a new identity slot.

Source

pub fn identity(&self) -> &LocalIdentity<I>

Borrow the underlying identity.

Source

pub fn peer_crypto(&self) -> &PeerCryptoMap<PEERS>

Borrow the per-peer secure-state map.

Source

pub fn peer_crypto_mut(&mut self) -> &mut PeerCryptoMap<PEERS>

Mutably borrow the per-peer secure-state map.

Source

pub fn frame_counter(&self) -> u32

Return the current frame counter.

Source

pub fn persisted_counter(&self) -> u32

Return the persisted frame-counter reservation boundary.

Source

pub fn pending_persist_target(&self) -> Option<u32>

Return the next scheduled persist target, if any.

Source

pub fn counter_persistence_enabled(&self) -> bool

Return whether counter persistence is enabled for this identity.

Source

pub fn load_persisted_counter(&mut self, value: u32)

Load a persisted counter boundary for this identity.

Source

pub fn next_receipt(&mut self) -> SendReceipt

Allocate the next send receipt.

Source

pub fn try_insert_pending_ack( &mut self, receipt: SendReceipt, pending: PendingAck<FRAME>, ) -> Result<Option<PendingAck<FRAME>>, PendingAckError>

Insert or replace pending-ACK state for a send receipt.

Source

pub fn pending_ack(&self, receipt: &SendReceipt) -> Option<&PendingAck<FRAME>>

Borrow pending-ACK state by receipt.

Source

pub fn pending_ack_mut( &mut self, receipt: &SendReceipt, ) -> Option<&mut PendingAck<FRAME>>

Mutably borrow pending-ACK state by receipt.

Source

pub fn remove_pending_ack( &mut self, receipt: &SendReceipt, ) -> Option<PendingAck<FRAME>>

Remove pending-ACK state by receipt.

Source

pub fn pfs_parent(&self) -> Option<LocalIdentityId>

Return the parent long-term identity if this slot is ephemeral.

Auto Trait Implementations§

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> Freeze for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: Freeze,

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> RefUnwindSafe for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: RefUnwindSafe,

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> Send for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: Send,

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> Sync for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: Sync,

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> Unpin for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: Unpin,

§

impl<I, const PEERS: usize, const ACKS: usize, const FRAME: usize> UnwindSafe for IdentitySlot<I, PEERS, ACKS, FRAME>
where I: UnwindSafe,

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

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
§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.