pub struct LinkEngine { /* private fields */ }Expand description
The Link Engine manages a single link’s lifecycle.
It follows the action-queue model: methods return Vec<LinkAction> instead
of performing I/O directly. The caller dispatches actions.
Implementations§
Source§impl LinkEngine
impl LinkEngine
Sourcepub fn new_initiator(
dest_hash: &[u8; 16],
hops: u8,
mode: LinkMode,
mtu: Option<u32>,
now: f64,
rng: &mut dyn Rng,
) -> (Self, Vec<u8>)
pub fn new_initiator( dest_hash: &[u8; 16], hops: u8, mode: LinkMode, mtu: Option<u32>, now: f64, rng: &mut dyn Rng, ) -> (Self, Vec<u8>)
Create a new initiator-side link engine.
Returns (engine, linkrequest_data) — the caller must pack linkrequest_data
into a LINKREQUEST packet and send it.
Sourcepub fn new_initiator_stamped(
dest_hash: &[u8; 16],
hops: u8,
mode: LinkMode,
mtu: Option<u32>,
now: f64,
rng: &mut dyn Rng,
stamp_cost: StampCost,
) -> (Self, Vec<u8>)
pub fn new_initiator_stamped( dest_hash: &[u8; 16], hops: u8, mode: LinkMode, mtu: Option<u32>, now: f64, rng: &mut dyn Rng, stamp_cost: StampCost, ) -> (Self, Vec<u8>)
Create an initiator link whose X25519 public key carries a stamp of at
least stamp_cost over destination_hash || ed25519_public_key.
Sourcepub fn new_initiator_with_keys(
dest_hash: &[u8; 16],
hops: u8,
mode: LinkMode,
mtu: Option<u32>,
now: f64,
prv: X25519PrivateKey,
sig_prv: Ed25519PrivateKey,
) -> (Self, Vec<u8>)
pub fn new_initiator_with_keys( dest_hash: &[u8; 16], hops: u8, mode: LinkMode, mtu: Option<u32>, now: f64, prv: X25519PrivateKey, sig_prv: Ed25519PrivateKey, ) -> (Self, Vec<u8>)
Create an initiator link from pre-generated keys.
Used when the X25519 key was stamped ahead of time, off the caller’s
latency-sensitive thread; see rns-net’s link request stamping.
Sourcepub fn set_link_id_from_hashable(
&mut self,
hashable_part: &[u8],
data_len: usize,
)
pub fn set_link_id_from_hashable( &mut self, hashable_part: &[u8], data_len: usize, )
Set link_id from the hashable part of the packed LINKREQUEST packet.
Must be called after packing the LINKREQUEST packet (since link_id depends on the packet’s hashable part).
Sourcepub fn new_responder(
owner_sig_prv: &Ed25519PrivateKey,
owner_sig_pub_bytes: &[u8; 32],
linkrequest_data: &[u8],
hashable_part: &[u8],
dest_hash: &[u8; 16],
hops: u8,
now: f64,
rng: &mut dyn Rng,
) -> Result<(Self, Vec<u8>), LinkError>
pub fn new_responder( owner_sig_prv: &Ed25519PrivateKey, owner_sig_pub_bytes: &[u8; 32], linkrequest_data: &[u8], hashable_part: &[u8], dest_hash: &[u8; 16], hops: u8, now: f64, rng: &mut dyn Rng, ) -> Result<(Self, Vec<u8>), LinkError>
Create a new responder-side link engine from an incoming LINKREQUEST.
owner_sig_prv / owner_sig_pub are the destination’s signing keys.
Returns (engine, actions) where actions include the LRPROOF data to send.
Sourcepub fn handle_lrproof(
&mut self,
proof_data: &[u8],
peer_sig_pub_bytes: &[u8; 32],
now: f64,
rng: &mut dyn Rng,
) -> Result<(Vec<u8>, Vec<LinkAction>), LinkError>
pub fn handle_lrproof( &mut self, proof_data: &[u8], peer_sig_pub_bytes: &[u8; 32], now: f64, rng: &mut dyn Rng, ) -> Result<(Vec<u8>, Vec<LinkAction>), LinkError>
Handle an incoming LRPROOF (initiator side).
Validates the proof, performs ECDH, derives session key, returns LRRTT data to be encrypted and sent.
Sourcepub fn handle_lrproof_with_hops(
&mut self,
proof_data: &[u8],
peer_sig_pub_bytes: &[u8; 32],
packet_hops: Option<u8>,
now: f64,
rng: &mut dyn Rng,
) -> Result<(Vec<u8>, Vec<LinkAction>), LinkError>
pub fn handle_lrproof_with_hops( &mut self, proof_data: &[u8], peer_sig_pub_bytes: &[u8; 32], packet_hops: Option<u8>, now: f64, rng: &mut dyn Rng, ) -> Result<(Vec<u8>, Vec<LinkAction>), LinkError>
Validate an LRPROOF while recording its authenticated hop metric.
Sourcepub fn handle_lrrtt(
&mut self,
encrypted_data: &[u8],
now: f64,
) -> Result<Vec<LinkAction>, LinkError>
pub fn handle_lrrtt( &mut self, encrypted_data: &[u8], now: f64, ) -> Result<Vec<LinkAction>, LinkError>
Handle an incoming LRRTT (responder side).
Decrypts the RTT packet, activates the link.
Sourcepub fn handle_lrrtt_with_hops(
&mut self,
encrypted_data: &[u8],
packet_hops: Option<u8>,
now: f64,
) -> Result<Vec<LinkAction>, LinkError>
pub fn handle_lrrtt_with_hops( &mut self, encrypted_data: &[u8], packet_hops: Option<u8>, now: f64, ) -> Result<Vec<LinkAction>, LinkError>
Handle LRRTT while recording the responder-side hop metric. The legacy timing-only method remains available for existing callers.
Sourcepub fn encrypt(
&self,
plaintext: &[u8],
rng: &mut dyn Rng,
) -> Result<Vec<u8>, LinkError>
pub fn encrypt( &self, plaintext: &[u8], rng: &mut dyn Rng, ) -> Result<Vec<u8>, LinkError>
Encrypt plaintext for transmission over this link.
Sourcepub fn encrypt_untagged(
&self,
plaintext: &[u8],
rng: &mut dyn Rng,
) -> Result<(Vec<u8>, HmacSha256), LinkError>
pub fn encrypt_untagged( &self, plaintext: &[u8], rng: &mut dyn Rng, ) -> Result<(Vec<u8>, HmacSha256), LinkError>
Self::encrypt with the tag left to the caller (see
Token::encrypt_untagged).
Sourcepub fn can_encrypt(&self) -> bool
pub fn can_encrypt(&self) -> bool
Whether this link has a session key to encrypt with.
Sourcepub fn encrypted_len(&self, plaintext_len: usize) -> usize
pub fn encrypted_len(&self, plaintext_len: usize) -> usize
Length of the ciphertext LinkEngine::encrypt produces for a
plaintext of plaintext_len bytes.
Sourcepub fn encrypt_into(
&self,
plaintext: &[u8],
rng: &mut dyn Rng,
out: &mut [u8],
) -> Result<(), LinkError>
pub fn encrypt_into( &self, plaintext: &[u8], rng: &mut dyn Rng, out: &mut [u8], ) -> Result<(), LinkError>
LinkEngine::encrypt into out, which must be exactly
LinkEngine::encrypted_len(plaintext.len()) bytes long.
Sourcepub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, LinkError>
pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, LinkError>
Decrypt ciphertext received on this link.
Sourcepub fn decrypt_into(
&self,
ciphertext: &[u8],
out: &mut Vec<u8>,
) -> Result<(), LinkError>
pub fn decrypt_into( &self, ciphertext: &[u8], out: &mut Vec<u8>, ) -> Result<(), LinkError>
LinkEngine::decrypt into out, replacing its contents and
reusing its capacity.
Sourcepub fn decrypt_chunks(
&self,
chunks: &[&[u8]],
skip: usize,
) -> Result<Vec<u8>, LinkError>
pub fn decrypt_chunks( &self, chunks: &[&[u8]], skip: usize, ) -> Result<Vec<u8>, LinkError>
Decrypt ciphertext held in consecutive chunks without joining them,
dropping the first skip plaintext bytes.
Sourcepub fn decrypt_stream(&self, skip: usize) -> Option<TokenDecryptStream>
pub fn decrypt_stream(&self, skip: usize) -> Option<TokenDecryptStream>
Start a Self::decrypt_chunks whose chunks are fed as they arrive.
Sourcepub fn sign_packet_hash(&self, packet_hash: &[u8; 32]) -> [u8; 64]
pub fn sign_packet_hash(&self, packet_hash: &[u8; 32]) -> [u8; 64]
Sign an explicit delivery proof for a packet sent over this Link.
Sourcepub fn signing_key(&self) -> &Ed25519PrivateKey
pub fn signing_key(&self) -> &Ed25519PrivateKey
This end’s Link signing key, which signs its delivery proofs.
Sourcepub fn peer_signing_key(&self) -> Option<&Ed25519PublicKey>
pub fn peer_signing_key(&self) -> Option<&Ed25519PublicKey>
The remote endpoint’s Link signing key, once known.
Sourcepub fn validate_packet_proof(
&self,
packet_hash: &[u8; 32],
signature: &[u8; 64],
) -> bool
pub fn validate_packet_proof( &self, packet_hash: &[u8; 32], signature: &[u8; 64], ) -> bool
Validate a delivery proof using the remote endpoint’s Link signing key.
Sourcepub fn build_identify(
&self,
identity: &Identity,
rng: &mut dyn Rng,
) -> Result<Vec<u8>, LinkError>
pub fn build_identify( &self, identity: &Identity, rng: &mut dyn Rng, ) -> Result<Vec<u8>, LinkError>
Build LINKIDENTIFY data (encrypted).
Sourcepub fn handle_identify(
&mut self,
encrypted_data: &[u8],
) -> Result<Vec<LinkAction>, LinkError>
pub fn handle_identify( &mut self, encrypted_data: &[u8], ) -> Result<Vec<LinkAction>, LinkError>
Handle incoming LINKIDENTIFY (encrypted data).
Only responders (non-initiators) can receive LINKIDENTIFY (Python: Link.py:1017).
Sourcepub fn record_inbound(&mut self, now: f64) -> Vec<LinkAction>
pub fn record_inbound(&mut self, now: f64) -> Vec<LinkAction>
Record that an inbound packet was received (updates timing).
If the link is STALE, recovers to ACTIVE (Python: Link.py:987-988).
Sourcepub fn record_proof(&mut self, now: f64)
pub fn record_proof(&mut self, now: f64)
Record that a proof signed by the peer was received.
Python’s PacketReceipt.validate_link_proof sets link.last_proof,
and the watchdog’s stale check takes the latest of last_inbound and
last_proof: an initiator that only ever hears proofs back for its
own confirmed traffic stays active. Proofs do not reactivate a link
that already went stale, matching upstream.
Sourcepub fn record_outbound(&mut self, now: f64, is_keepalive: bool)
pub fn record_outbound(&mut self, now: f64, is_keepalive: bool)
Record that an outbound packet was sent (updates timing).
Sourcepub fn record_inbound_traffic(&mut self, data_len: usize)
pub fn record_inbound_traffic(&mut self, data_len: usize)
Record one accepted inbound packet using its packed data/ciphertext size.
Sourcepub fn record_outbound_traffic(&mut self, data_len: usize)
pub fn record_outbound_traffic(&mut self, data_len: usize)
Record one successfully packed outbound packet.
Sourcepub fn tick(&mut self, now: f64) -> Vec<LinkAction>
pub fn tick(&mut self, now: f64) -> Vec<LinkAction>
Periodic tick: check keepalive, stale, timeouts.
Sourcepub fn needs_keepalive(&self, now: f64) -> bool
pub fn needs_keepalive(&self, now: f64) -> bool
Check if a keepalive should be sent. Returns true if conditions are met.
Sourcepub fn should_reply_keepalive(&self, payload: &[u8], now: f64) -> bool
pub fn should_reply_keepalive(&self, payload: &[u8], now: f64) -> bool
Return whether a received keepalive probe needs a responder reply.
0xff is the initiator probe and 0xfe the responder acknowledgement,
matching upstream Reticulum. A responder that sent any traffic within
the current keepalive interval can omit the acknowledgement because that
traffic already refreshed the initiator’s inbound timer.
Sourcepub fn teardown(&mut self) -> Vec<LinkAction>
pub fn teardown(&mut self) -> Vec<LinkAction>
Tear down the link (initiator-initiated close).
Sourcepub fn handle_teardown(&mut self) -> Vec<LinkAction>
pub fn handle_teardown(&mut self) -> Vec<LinkAction>
Handle incoming teardown (remote close).
pub fn link_id(&self) -> &LinkId
pub fn state(&self) -> LinkState
pub fn rtt(&self) -> Option<f64>
pub fn mdu(&self) -> usize
pub fn mtu(&self) -> u32
pub fn is_initiator(&self) -> bool
Sourcepub fn activated_at(&self) -> Option<f64>
pub fn activated_at(&self) -> Option<f64>
When the link became active, or None if it never did.
pub fn mode(&self) -> LinkMode
pub fn remote_identity(&self) -> Option<&([u8; 16], [u8; 64])>
pub fn destination_hash(&self) -> &[u8; 16]
pub fn expected_hops(&self) -> u8
pub fn rebalanced_at(&self) -> Option<f64>
pub fn tx_packets(&self) -> u64
pub fn rx_packets(&self) -> u64
pub fn tx_bytes(&self) -> u64
pub fn rx_bytes(&self) -> u64
Sourcepub fn derived_key(&self) -> Option<&[u8]>
pub fn derived_key(&self) -> Option<&[u8]>
Get the derived session key (needed for hole-punch token derivation).
pub fn keepalive_interval(&self) -> f64
Sourcepub fn last_proof(&self) -> f64
pub fn last_proof(&self) -> f64
When the peer’s latest valid packet proof arrived (0 before the first).