pub struct Node<const PEERS: usize = 32> { /* private fields */ }Implementations§
Source§impl<const PEERS: usize> Node<PEERS>
impl<const PEERS: usize> Node<PEERS>
Sourcepub fn factory_reset(identity: Identity, generation: u64) -> Self
pub fn factory_reset(identity: Identity, generation: u64) -> Self
Create a replacement identity only for an explicit factory reset.
Create a replacement identity bound to one normalized control authority. Restoring it for a different server is refused.
Sourcepub fn restore(state: &PersistState) -> Result<Self, NodeError>
pub fn restore(state: &PersistState) -> Result<Self, NodeError>
Restore an identity. Unknown or corrupt state fails closed.
Restore only when state belongs to the configured control authority. Version-one state is bound and rewritten at the next generation.
pub fn identity(&self) -> &Identity
The normalized control authority this identity is bound to.
pub fn netmap(&self) -> &Netmap<PEERS>
pub fn registration_state(&self) -> RegistrationState
pub fn requires_persistence(&self) -> bool
pub fn is_enrolled(&self) -> bool
pub fn rotation_old_node_key(&self) -> Option<&NodePublic>
Sourcepub fn stage_node_key_rotation(
&mut self,
rng: &mut impl Rng,
) -> Result<(), NodeError>
pub fn stage_node_key_rotation( &mut self, rng: &mut impl Rng, ) -> Result<(), NodeError>
Stage a fresh node key and its predecessor as one durable rotation.
An active control session may discover expiry after registration, so a registered node is allowed to stage the same durable replacement.
Sourcepub fn registration_auth_key<'a>(&self, provisioned: &'a str) -> &'a str
pub fn registration_auth_key<'a>(&self, provisioned: &'a str) -> &'a str
Select the credential for a registration request. After enrollment the empty string is returned even though the reusable key remains embedded in firmware for dual-slot disaster recovery.
pub fn trusted_time_floor(&self) -> u64
Sourcepub fn prefer_derp(&mut self, region: u16) -> Result<(), NodeError>
pub fn prefer_derp(&mut self, region: u16) -> Result<(), NodeError>
Apply the relay selected by the platform’s authenticated STUN probes.
The next staged delta inherits it unless the control plane explicitly
sends a replacement HomeDERP. Zero clears a previously selected home
when the current map has no eligible region.
Sourcepub fn set_direct_paths(&mut self, enabled: bool)
pub fn set_direct_paths(&mut self, enabled: bool)
Allow or forbid direct UDP paths to peers.
A node with no UDP socket at all — a browser, which has only WebSockets
— disables them and becomes relay-only: no disco probes, no
NodeAction::DirectTransmit, and no direct candidates staged from a
CallMeMaybe. Every packet, handshakes included, goes to the peer’s
DERP region, and disco pings that arrive over DERP are still answered
over DERP so peers see the relay path as alive. Datagrams handed to
Node::handle_direct_from are ignored, so an adapter that still
drains an old socket cannot learn a direct path or answer over UDP. Such a node should
publish no endpoints and a preferred DERP region, so that peers reach
it through that region.
pub fn direct_paths(&self) -> bool
Sourcepub fn set_initiate_on_demand(&mut self, enabled: bool)
pub fn set_initiate_on_demand(&mut self, enabled: bool)
Start WireGuard handshakes only with peers this node has traffic for.
By default every netmap peer is an initiator, which suits a gateway
that most peers reach anyway. A client in a large tailnet that talks to
one peer would instead handshake with all of them, and over DERP that
means a relay connection per region. With this enabled, peers start as
responders and become initiators — which also makes this node
responsible for rekeying them — the first time
Node::encapsulate_ipv4 has a packet for them. That first packet is
refused with tunnel::Error::NoSession; the handshake follows from
Node::poll_tunnel, and the sender’s own retransmission carries the
data. Enable it before the first netmap is applied.
pub fn set_control_endpoint(&mut self, endpoint: Endpoint)
Sourcepub fn set_registration_body(&mut self, body: &[u8]) -> Result<(), NodeError>
pub fn set_registration_body(&mut self, body: &[u8]) -> Result<(), NodeError>
Supply the next encoded registration request. It remains caller-owned until moved into a command and is zeroized after the control task drops it.
Sourcepub fn advance_trusted_time(
&mut self,
unix_seconds: u64,
) -> Result<(), NodeError>
pub fn advance_trusted_time( &mut self, unix_seconds: u64, ) -> Result<(), NodeError>
Set an authenticated, nondecreasing wall-clock floor. The new floor must be atomically persisted before control traffic resumes.
Sourcepub fn poll(&mut self, now_ms: u64) -> Result<Option<NodeAction>, NodeError>
pub fn poll(&mut self, now_ms: u64) -> Result<Option<NodeAction>, NodeError>
Poll persistence and reconnect deadlines.
Sourcepub fn persistence_result(
&mut self,
generation: u64,
saved: bool,
) -> Result<Option<NodeAction>, NodeError>
pub fn persistence_result( &mut self, generation: u64, saved: bool, ) -> Result<Option<NodeAction>, NodeError>
A failed atomic save never unlocks control traffic.
pub fn control_failed(&mut self, now_ms: u64, jitter_ms: u16)
pub fn handle_control_event( &mut self, event: ControlEvent<'_, PEERS>, ) -> Result<Option<NodeAction>, NodeError>
Sourcepub fn seed_staging(&self, lease: &mut Netmap<PEERS>)
pub fn seed_staging(&self, lease: &mut Netmap<PEERS>)
Seed the one caller-owned staging lease before a streaming update.
Sourcepub fn adopt_reconnected_map(
&mut self,
lease: &mut Netmap<PEERS>,
) -> Result<(), NodeError>
pub fn adopt_reconnected_map( &mut self, lease: &mut Netmap<PEERS>, ) -> Result<(), NodeError>
Install the first map from a replacement control stream while keeping the existing tunnel sessions and path state alive through the outage.
Sourcepub fn forget_relay(&mut self, peer: &NodePublic, region: u16)
pub fn forget_relay(&mut self, peer: &NodePublic, region: u16)
Forget that a peer was reachable through a region, because the relay itself says it no longer holds a connection for that peer.
The region stays in the map and stays connected — other peers may still be there. Only this peer’s learned relay is cleared, so the next packet falls back to its advertised home region or a direct path instead of being written into a relay that will discard it.
Sourcepub fn mark_direct_unhealthy(
&mut self,
peer: &NodePublic,
) -> Result<(), NodeError>
pub fn mark_direct_unhealthy( &mut self, peer: &NodePublic, ) -> Result<(), NodeError>
Mark a formerly working direct path unhealthy so subsequent packets use the peer’s home DERP, when one is advertised, until authenticated direct traffic is seen again.
Sourcepub fn call_me_maybe(
&mut self,
peer: &NodePublic,
endpoints: &[SocketAddr],
rng: &mut impl Rng,
) -> Result<Option<NodeAction>, NodeError>
pub fn call_me_maybe( &mut self, peer: &NodePublic, endpoints: &[SocketAddr], rng: &mut impl Rng, ) -> Result<Option<NodeAction>, NodeError>
Ask an authenticated peer to probe our current endpoints. CallMeMaybe travels only over DERP so both NATs can open their outbound mappings. The platform supplies the same endpoints it published to control. At most the first eight candidates are advertised, as in the decoder.
Sourcepub fn poll_disco(
&mut self,
now_ms: u64,
rng: &mut impl Rng,
) -> Result<Option<NodeAction>, NodeError>
pub fn poll_disco( &mut self, now_ms: u64, rng: &mut impl Rng, ) -> Result<Option<NodeAction>, NodeError>
Emit at most one authenticated direct-path probe. Three unanswered attempts bound each discovery round before DERP fallback takes over. Peers observed on a relay get a fresh round after a ten-second pause, allowing a previously blocked or expired NAT mapping to recover.
Sourcepub fn poll_disco_for(
&mut self,
peer: &NodePublic,
now_ms: u64,
rng: &mut impl Rng,
) -> Result<Option<NodeAction>, NodeError>
pub fn poll_disco_for( &mut self, peer: &NodePublic, now_ms: u64, rng: &mut impl Rng, ) -> Result<Option<NodeAction>, NodeError>
Probe an active peer without waiting for unrelated unreachable peers. Adapters with on-demand application sockets should poll those peers rather than serially probing the entire control-plane peer list.
Sourcepub fn poll_derp(&mut self) -> Result<Option<NodeAction>, NodeError>
pub fn poll_derp(&mut self) -> Result<Option<NodeAction>, NodeError>
Return one due DERP connection command. DNS and TCP remain the adapter’s responsibility.
Sourcepub fn exit_control_ready(&self) -> bool
pub fn exit_control_ready(&self) -> bool
Control-plane conditions for enabling the IPv4 forwarding path. Wi-Fi
and NAT initialization are firmware-owned conditions checked by the
actor before it emits exit-ready.
pub fn handle_derp_event( &mut self, event: DerpEvent<'_>, now_ms: u64, rng: &mut (impl Rng + Rng), ) -> Result<Option<NodeAction>, NodeError>
pub fn handle_direct( &mut self, datagram: &[u8], now_ms: u64, rng: &mut impl Rng, ) -> Result<Option<NodeAction>, NodeError>
Sourcepub fn handle_direct_from(
&mut self,
datagram: &[u8],
source: SocketAddr,
now_ms: u64,
rng: &mut (impl Rng + Rng),
) -> Result<Option<NodeAction>, NodeError>
pub fn handle_direct_from( &mut self, datagram: &[u8], source: SocketAddr, now_ms: u64, rng: &mut (impl Rng + Rng), ) -> Result<Option<NodeAction>, NodeError>
Process a direct datagram and mark its authenticated peer’s source as a healthy direct path before routing any response.
Sourcepub fn encapsulate_ipv6(
&mut self,
peer: &NodePublic,
packet: &[u8],
now_ms: u64,
) -> Result<Option<NodeAction>, NodeError>
pub fn encapsulate_ipv6( &mut self, peer: &NodePublic, packet: &[u8], now_ms: u64, ) -> Result<Option<NodeAction>, NodeError>
Encrypt an inner IPv6 packet for a configured peer. As for IPv4, the caller must apply source ownership and packet policy before forwarding.
Sourcepub fn encapsulate_ipv4(
&mut self,
peer: &NodePublic,
packet: &[u8],
now_ms: u64,
) -> Result<Option<NodeAction>, NodeError>
pub fn encapsulate_ipv4( &mut self, peer: &NodePublic, packet: &[u8], now_ms: u64, ) -> Result<Option<NodeAction>, NodeError>
Encrypt an inner IPv4 packet for a configured peer.
Sourcepub fn poll_tunnel_timers(
&mut self,
now_ms: u64,
) -> Result<Option<NodeAction>, NodeError>
pub fn poll_tunnel_timers( &mut self, now_ms: u64, ) -> Result<Option<NodeAction>, NodeError>
Poll WireGuard keepalive and session-expiry timers.