feat: add engine surface for daemon — listen port, peer SSH host keys, re_stun#263
Conversation
…, re_stun Three additive engine-API asks the tailscaled-rs daemon needs, mirroring Go tsnet/tailscale behavior: - StatusNode.ssh_host_keys: project Hostinfo.sshHostKeys onto the domain Node and surface it on StatusNode (Go ipnstate.PeerStatus.SSH_HostKeys), for tailscale ssh host-key pinning. Empty when control advertised none. The wire PeerChange carries no ssh host keys, so it is left unchanged. - Device::re_stun: force an immediate STUN/endpoint re-probe without rebinding the underlay socket (Go magicsock Conn.ReSTUN). Factored the STUN sweep out of rebind_and_reprobe into a shared DirectManager::stun_sweep_once; no socket swap, no re-ping, no-op when DERP-only inert. - Config.wireguard_listen_port: pin the UDP port magicsock binds for WireGuard + disco (Go tailscaled --port), threaded Config -> ts_control::Config -> ForwarderConfig -> Env -> the initial bind_underlay_addr. None keeps today's ephemeral bind; Some(p) pins p with an ephemeral fallback if taken (mirroring rebind_socket) so a port collision never fails bring-up, and a successful pin carries across rebind. IPv4-only-default + fail-closed bind family unchanged. Signed-off-by: GeiserX <9169332+GeiserX@users.noreply.github.com>
|
Warning Review limit reached
More reviews will be available in 34 minutes and 22 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (22)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
Three small, additive engine-API surfaces the downstream daemon needs (its
ENGINE_ASKS.md#22, #23, #26). Each unblocks a daemon CLI feature on a pin bump. Behaviorally faithful to Go tsnet/tailscaled.#23 —
StatusNode.ssh_host_keys(Goipnstate.PeerStatus.SSH_HostKeys)The wire
HostInfo.ssh_host_keysalready existed but wasn't projected. Now the domainNodecarriesssh_host_keys: Vec<String>(populated in the wire→domain conversion fromHostInfo.sshHostKeys), andStatusNodesurfaces it. Pure read-projection. Lets the daemon write aknown_hostsfrom the netmap fortnet ssh(pinned host-key verification, no TOFU).#26 —
Device::re_stun()(Gomagicsock.Conn.ReSTUN)Forces an immediate STUN re-probe / endpoint re-derivation without tearing down sockets — the lighter sibling of
rebind(). Reuses the STUN-sweep machinery (probe_stun_servers_once, gated bystun_probe_should_run); no socket swap, no control round-trip; clean no-op when DERP-only. Fortnet debug restun.#22 —
Config.wireguard_listen_port: Option<u16>(Gotailscaled --port)Pins the UDP port magicsock binds for WireGuard + disco.
None= ephemeral (unchanged default behavior, = Go's port 0);Some(p)bindspfor fixed-firewall-pinhole deployments. ThreadedConfig → ts_control::Config → Env → bind_underlay_addr(the single initial-bind site). A taken pinned port falls back to ephemeral (never hard-fails bring-up — mirrorsrebind_socket's fallback). The bind family is unchanged (IPv4-only default + fail-closed posture untouched — only the port is configurable). A laterrebind()keeps the pinned port automatically (it already prefers the current local port).Tests
Wire→domain→status
ssh_host_keysprojection (present + absent);re_stunpeer-gate + DERP-only no-op;bind_underlay_addrpins a free port and falls back to ephemeral when taken;wireguard_listen_portthreadsConfig → Envand crossesFrom<&Config>; default isNone.Gates (local, all green — re-verified after rebasing onto current main)
cargo test -p geiserx_ts_control -p geiserx_ts_runtime -p geiserx_tailscale(248 + 354 + 24) · clippy-D warnings(3 crates +tunlane) ·cargo fmt --check·cargo doc(broken_intra_doc_links=deny) ·cargo run -p checks.First batch of the daemon engine-asks. After this lands + a release, the daemon enables these via a pin bump:
tnet ssh(host-key pinning),tnet debug restun,tailnetd --port. (Separately confirmed for the daemon: theidentity-federationfeature compiles clean on the facade — the 4 WIF flags need only the feature flag on, no engine code.)Signed-off-by: Sergio sergio@geiser.cloud
Created using Claude Code (Opus 4.8)