Skip to main content

NodeState

Struct NodeState 

Source
pub struct NodeState {
    pub disco_keys: DiscoKeyPair,
    pub machine_keys: MachineKeyPair,
    pub network_lock_keys: NetworkLockKeyPair,
    pub node_keys: NodeKeyPair,
    pub old_node_key: Option<NodePublicKey>,
    pub acme_account_key: Option<Zeroizing<Vec<u8>>>,
}
Expand description

The complete runtime key state for a Tailscale node.

Fields§

§disco_keys: DiscoKeyPair

The DiscoKeyPair this Tailnet peer uses for the Disco protocol.

These should be randomly generated for each run of a Tailscale device.

§machine_keys: MachineKeyPair

The MachineKeyPair for the hardware this Tailnet peer runs on.

§network_lock_keys: NetworkLockKeyPair

The NetworkLockKeyPair for this Tailnet peer, for use with Tailnet Lock.

§node_keys: NodeKeyPair

The NodeKeyPair for this Tailnet peer.

§old_node_key: Option<NodePublicKey>

The node’s previous node public key during a rotation (see PersistState::old_node_key). Threaded to registration as RegisterRequest.OldNodeKey.

§acme_account_key: Option<Zeroizing<Vec<u8>>>

The persisted ACME account key (PKCS#8 DER), threaded from PersistState::acme_account_key. The acme cert-issuance path reads this to reuse the same Let’s Encrypt account across renewals. None when no ACME account is provisioned.

Wrapped in Zeroizing so the DER private-key bytes are wiped from memory on drop; serializes transparently via the inner Vec (unchanged JSON shape).

Implementations§

Source§

impl NodeState

Source

pub fn generate() -> NodeState

Generate a new NodeState. All keys get random values.

Source

pub fn rotate_node_key(&mut self)

Rotate the node key for re-registration, the runtime twin of PersistState::rotate_node_key: record the current node public key as old_node_key and replace the node_keys pair with a freshly-generated one. The next registration built from this state sends the prior key as RegisterRequest.OldNodeKey, so control links the new node key to the node’s existing identity instead of treating it as a brand-new node (Go’s regen/doLogin flow).

Only the node key rotates. The disco and machine keys are deliberately left untouched: the data plane (magicsock/WireGuard sessions, disco) keys on those and on per-peer keys, never on the self node key, so a node-key rotation does not re-key or flap an established tunnel. The node key is a control-plane identity. (The disco ping packet does carry the self node key as a claimed-sender identity — a caller that rotates at runtime should refresh magicsock’s copy so outbound pings advertise the new key, but that is a magicsock concern, not a key-state one.)

old_node_key anchor lifecycle. This records the prior key as old_node_key only if no rotation anchor is already held (old_node_key is currently None). A second rotation before a successful re-register therefore preserves the original pre-expiry key as the anchor, rather than overwriting it with the intermediate rotated key — control links a rotation against the key it already knows, so the anchor must stay pinned to the last registered key, not a transient one. The anchor is released back to None by clear_old_node_key, which the re-register path calls on a successful register: once control has accepted the rotated key, that key is now the node’s known identity, so a subsequent genuine expiry cycle correctly captures it as the new anchor. (A runtime caller that drives repeated rotations is additionally expected not to rotate again while a re-register is unconfirmed; this guard is the belt-and-suspenders.)

Source

pub fn clear_old_node_key(&mut self)

Release the rotation anchor: drop any old_node_key back to None.

Called by the re-register path on a successful register. After control accepts a rotated node key, that key is the node’s known identity, so the next genuine node-key rotation should anchor on it (capture it fresh as old_node_key) rather than re-sending a now-stale prior key. Paired with rotate_node_key’s preserve-if-Some guard: the anchor is captured once per rotation episode and cleared once the episode is confirmed. A no-op when no anchor is held (the steady-state case — every successful map-poll re-register calls this and it harmlessly does nothing while old_node_key is already None).

Trait Implementations§

Source§

impl Clone for NodeState

Source§

fn clone(&self) -> NodeState

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NodeState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for NodeState

Source§

fn default() -> NodeState

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for NodeState

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<NodeState, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for NodeState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl From<&NodeState> for PersistState

Source§

fn from(value: &NodeState) -> PersistState

Converts to this type from the input type.
Source§

impl From<&PersistState> for NodeState

Source§

fn from(value: &PersistState) -> NodeState

Converts to this type from the input type.
Source§

impl From<NodeState> for PersistState

Source§

fn from(value: NodeState) -> PersistState

Converts to this type from the input type.
Source§

impl From<PersistState> for NodeState

Source§

fn from(value: PersistState) -> NodeState

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DisplayExt for T
where T: Display,

Source§

fn as_display_debug(&self) -> DisplayToDebug<'_>

Return a wrapper around this value that provides Debug using its Display implementation.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<A, T> DynMessage<A> for T
where A: Actor + Message<T>, T: Send + 'static,

Source§

fn handle_dyn<'a>( self: Box<T>, state: &'a mut A, actor_ref: ActorRef<A>, tx: Option<Sender<Result<Box<dyn Any + Send>, SendError<Box<dyn Any + Send>, Box<dyn Any + Send>>>>>, stop: &'a mut bool, ) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn ReplyError>>> + Send + 'a>>

Handles the dyn message with the provided actor state, ref, and reply sender.
Source§

fn as_any(self: Box<T>) -> Box<dyn Any>

Casts the type to a Box<dyn Any>.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

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

Source§

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ReplyError for T
where T: Debug + Send + 'static,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToCompactString for T
where T: Display,

Source§

impl<T> ToLine for T
where T: Display,

Source§

fn to_line(&self) -> Line<'_>

Converts the value to a Line.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToSpan for T
where T: Display,

Source§

fn to_span(&self) -> Span<'_>

Converts the value to a Span.
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> ToText for T
where T: Display,

Source§

fn to_text(&self) -> Text<'_>

Converts the value to a Text.
Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more