feat: add up/set pref Config fields for the daemon#268
Conversation
…pdate, operator, nickname, posture, webclient Add the faithfully-wirable subset of the downstream daemon's engine-ask #21: eight Go up/set pref flags it cannot wire today, surfaced on tailscale::Config and threaded to ts_control::Config via From<&Config> like the existing prefs. Two are genuinely advertised to control (mirroring Go applyPrefsToHostinfoLocked): - advertise_app_connector (Go Prefs.AppConnector.Advertise) sets HostInfo.AppConnector = Some(true) on registration and every map request (Go hi.AppConnector.Set(...)). Advertises the capability bool only; the app-connector data path (domain routes / 4via6) is a separate subsystem, exactly the boundary Go draws. - auto_update_apply (Go Prefs.AutoUpdate.Apply) feeds HostInfo.AllowsUpdate (Go hi.AllowsUpdate = ... || Apply.EqualBool(true)). This fork runs no updater; the flag only advertises the node accepts a remote update trigger. Both ride new MapRequestBuilder methods app_connector()/allows_update(), mirroring the wire_ingress wiring, and are set in register.rs + client.rs. Six are store-only carried prefs — faithful because Go's engine layer also just stores these; the behavior is daemon / c2n / separate-subsystem / OS-router, not engine. Each is carried on both configs and threaded through From, never read inside ts_control and never advertised: - auto_update_check (Go AutoUpdate.Check, local background-checker gate) - operator_user (Go OperatorUser, daemon LocalAPI uid authz) - node_nickname (Go ProfileName, local display label) - posture_checking (Go PostureChecking; no Hostinfo field — posture is a c2n pull the fork does not implement, so storing is identical to posture-disabled) - run_web_client (Go RunWebClient, gates a separate local web-client server) - exit_node_allow_lan_access (Go ExitNodeAllowLANAccess, OS-router route-shaping with no effect on the netstack-default fork that has no host-route layer) Each store-only field's doc comment honestly states it is a carried pref whose behavior is daemon/control-side, not an engine action. Per honest-omission, the Linux netfilter knobs, --unattended, and the WIF flags are deliberately left out (no engine layer to act on them). All default off/None (fail-closed). Tests cover From<&Config> threading (default + set), the AppConnector/AllowsUpdate wire keys via serde_json, and that a default Config advertises neither. Signed-off-by: GeiserX <9169332+GeiserX@users.noreply.github.com>
|
Warning Review limit reached
More reviews will be available in 11 minutes and 44 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 (5)
✨ 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
Engine ask #21 (the faithfully-wirable subset): 8
Configfields for Goup/setpref flags the daemon can't wire today. Each is behaviorally faithful to Go v1.100.0's tsnet/Prefs layer (researched verbatim) — no inert fields (honest-omission rule).Advertised to control (wired to existing HostInfo fields)
advertise_app_connector: bool→HostInfo.AppConnector(GoapplyPrefsToHostinfoLocked:hi.AppConnector.Set(advertise)). Go calls.Setunconditionally, so the key is always sent:true→AppConnector:true,false(default)→AppConnector:false(a.Set(false)opt.Boolmarshals tofalse, not omitted — omitting it would be a not-tailscaled fingerprint tell). The app-connector data path (domain routes / 4via6) is a separate deferred subsystem.auto_update_apply: Option<bool>→HostInfo.AllowsUpdate(Go:…|| Apply.EqualBool(true)).Some(true)→AllowsUpdate:true;None/Some(false)→false (anomitzerobool, omitted — matches Go). No updater is implemented (advertise only).Store-only (carried prefs — faithful, since Go's engine layer also just carries these; the behavior is daemon/c2n/separate-subsystem/OS-router, documented honestly per field)
auto_update_check,operator_user(daemon LocalAPI uid authz),node_nickname(local profile label),posture_checking(noHostinfo.PostureCheckingexists — posture is a c2n pull the fork doesn't implement; storing == disabled),run_web_client(separate web server),exit_node_allow_lan_access(OS-router route-shaping, inert on the netstack-default fork).Deliberately NOT added (honest omission — no engine layer to act on them)
The Linux netfilter knobs (
--snat-subnet-routes/--stateful-filtering/--netfilter-mode),--unattended(GoForceDaemon, Windows), and the WIF flags (already behindidentity-federation— the daemon enables the feature, no engine code).Reviewed
Independent wire-parity review caught a HIGH fingerprint bug (the original
app_connectoromitted the key onfalsewhere Go sendsAppConnector:false) — fixed (Some(value), mirroring the fork'sHostInfo.containerSome(false)-is-a-real-signal precedent) + tests updated to assert the Go-faithful wire bytes, empirically confirmed against Go v1.100.0'sopt.Boolmarshaling.Gates (local, all green)
cargo test -p geiserx_ts_control -p geiserx_ts_control_serde -p geiserx_tailscale(255 + serde + facade) · clippy-D warnings(3 crates +tunlane) ·cargo fmt --check·cargo doc(broken_intra_doc_links=deny) ·cargo run -p checks. Tests prove the wire keys viaserde_json::to_value, theFrom<&Config>threading, and fail-closed defaults.Signed-off-by: Sergio sergio@geiser.cloud
Created using Claude Code (Opus 4.8)