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
PeerCryptoMapmapping each known remote peer to its establishedumsh_crypto::PairwiseKeysand 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
LinearMapof in-flightPendingAckrecords keyed bySendReceipt, one entry per ACK-requested send awaiting either forwarding confirmation or a final transport ACK. - An internal
next_receiptcounter used to issue uniqueSendReceiptvalues 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 toMac::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>
impl<I: NodeIdentity, const PEERS: usize, const ACKS: usize, const FRAME: usize> IdentitySlot<I, PEERS, ACKS, FRAME>
Sourcepub fn new(
identity: LocalIdentity<I>,
frame_counter: u32,
pfs_parent: Option<LocalIdentityId>,
) -> Self
pub fn new( identity: LocalIdentity<I>, frame_counter: u32, pfs_parent: Option<LocalIdentityId>, ) -> Self
Create a new identity slot.
Sourcepub fn identity(&self) -> &LocalIdentity<I>
pub fn identity(&self) -> &LocalIdentity<I>
Borrow the underlying identity.
Sourcepub fn peer_crypto(&self) -> &PeerCryptoMap<PEERS>
pub fn peer_crypto(&self) -> &PeerCryptoMap<PEERS>
Borrow the per-peer secure-state map.
Sourcepub fn peer_crypto_mut(&mut self) -> &mut PeerCryptoMap<PEERS>
pub fn peer_crypto_mut(&mut self) -> &mut PeerCryptoMap<PEERS>
Mutably borrow the per-peer secure-state map.
Sourcepub fn frame_counter(&self) -> u32
pub fn frame_counter(&self) -> u32
Return the current frame counter.
Sourcepub fn persisted_counter(&self) -> u32
pub fn persisted_counter(&self) -> u32
Return the persisted frame-counter reservation boundary.
Sourcepub fn pending_persist_target(&self) -> Option<u32>
pub fn pending_persist_target(&self) -> Option<u32>
Return the next scheduled persist target, if any.
Sourcepub fn counter_persistence_enabled(&self) -> bool
pub fn counter_persistence_enabled(&self) -> bool
Return whether counter persistence is enabled for this identity.
Sourcepub fn load_persisted_counter(&mut self, value: u32)
pub fn load_persisted_counter(&mut self, value: u32)
Load a persisted counter boundary for this identity.
Sourcepub fn next_receipt(&mut self) -> SendReceipt
pub fn next_receipt(&mut self) -> SendReceipt
Allocate the next send receipt.
Sourcepub fn try_insert_pending_ack(
&mut self,
receipt: SendReceipt,
pending: PendingAck<FRAME>,
) -> Result<Option<PendingAck<FRAME>>, PendingAckError>
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.
Sourcepub fn pending_ack(&self, receipt: &SendReceipt) -> Option<&PendingAck<FRAME>>
pub fn pending_ack(&self, receipt: &SendReceipt) -> Option<&PendingAck<FRAME>>
Borrow pending-ACK state by receipt.
Sourcepub fn pending_ack_mut(
&mut self,
receipt: &SendReceipt,
) -> Option<&mut PendingAck<FRAME>>
pub fn pending_ack_mut( &mut self, receipt: &SendReceipt, ) -> Option<&mut PendingAck<FRAME>>
Mutably borrow pending-ACK state by receipt.
Sourcepub fn remove_pending_ack(
&mut self,
receipt: &SendReceipt,
) -> Option<PendingAck<FRAME>>
pub fn remove_pending_ack( &mut self, receipt: &SendReceipt, ) -> Option<PendingAck<FRAME>>
Remove pending-ACK state by receipt.
Sourcepub fn pfs_parent(&self) -> Option<LocalIdentityId>
pub fn pfs_parent(&self) -> Option<LocalIdentityId>
Return the parent long-term identity if this slot is ephemeral.