Add Windows named-pipe local control

This commit is contained in:
Eric Wendland 2026-07-18 17:05:38 +02:00
commit 3c84713472
9 changed files with 338 additions and 72 deletions

View file

@ -3,11 +3,11 @@
`geth` is a single-binary local-first mesh runtime. One executable provides both
daemon mode and control mode. The daemon owns local identity, metadata storage,
the shared Iroh endpoint, resource registry, module routing, and local control
socket. Control commands connect to the Unix socket and send typed JSONL
requests.
endpoint. Control commands connect to a per-home Unix socket on Linux/macOS or
a per-home named pipe on Windows and send typed JSONL requests.
Within `geth-node`, daemon lifecycle code is separated from feature handlers:
`daemon.rs` owns `geth daemon run` startup, local socket binding, shutdown
`daemon.rs` owns `geth daemon run` startup, local endpoint binding, shutdown
signal handling, Iroh endpoint startup, the Iroh accept loop, and background
live-sync task spawning. `local_control.rs` owns async local `ControlRequest`
routing, safe trace-field classification, and named peer/resource/local handler
@ -28,9 +28,11 @@ as stale and replaced. This keeps one daemon authoritative for each geth home
and prevents a second process from unlinking the first daemon's control path.
After local control stops accepting requests, `daemon.rs` cancels the Iroh
accept and live-sync tasks, releases native docs/gossip/blob handles, calls
`Endpoint::close().await`, and removes the local control socket. The same
cleanup path runs when the serving loop returns an error, preventing stale
socket files and unclosed endpoint clones from becoming restart behavior.
`Endpoint::close().await`, and releases the local control endpoint. On Unix this
also removes the socket path; Windows named pipes disappear with their server
handles. The same cleanup path runs when the serving loop returns an error,
preventing stale endpoints and unclosed endpoint clones from becoming restart
behavior.
Foreground daemons handle Ctrl-C, and Unix daemons also handle the SIGTERM used
by user service managers, through this same graceful shutdown path.

View file

@ -60,9 +60,10 @@ cover the subset intended as stable rather than every incidental field.
## Local Control JSONL
The local daemon control socket uses newline-delimited JSON request and response
messages from `geth-control`. This protocol is local-only and not a remote trust
boundary, but local automation may still rely on it.
The local daemon control endpoint uses newline-delimited JSON request and
response messages from `geth-control`. Its carrier is a Unix socket on
Linux/macOS and a per-home Windows named pipe. This protocol is local-only and
not a remote trust boundary, but local automation may still rely on it.
Stable local-control variants follow the same compatibility rules as `--json`
output. Unknown variants, malformed JSON, and messages without a trailing

View file

@ -22,8 +22,10 @@ For deployment-readiness work that cuts across feature areas, see
- `[x]` Daemon startup claims the local control endpoint before starting
network and background modules.
- `[x]` A live endpoint rejects another daemon with the stable
`daemon_already_running` code instead of unlinking the first socket.
- `[x]` Stale, unreachable socket paths are recovered automatically.
`daemon_already_running` code instead of unlinking the first Unix socket or
replacing the first Windows named-pipe server.
- `[x]` Stale, unreachable Unix socket paths are recovered automatically;
Windows pipe lifetime is owned by the server handle.
- `[x]` Tests cover stale recovery and live second-daemon rejection.
- `[x]` Keep local control available when Iroh-native startup degrades.
@ -37,6 +39,17 @@ For deployment-readiness work that cuts across feature areas, see
- `[x]` Tests inject a post-endpoint native-store failure and verify clean
degradation where UDP endpoint binding is available.
- `[x]` Use a platform-native local control carrier.
Acceptance criteria:
- `[x]` Linux and macOS retain per-home Unix-domain sockets.
- `[x]` Windows derives a deterministic per-home named-pipe name and uses
Tokio named-pipe clients and server instances for the same JSONL protocol.
- `[x]` Unary control, SSH proxying, and TCP byte forwarding share one async
local-stream abstraction without adding another executable or remote
transport.
- `[x]` Unix-socket forwarding is cfg-gated with an explicit unsupported
result on Windows, and a platform transport roundtrip runs in CI tests.
- `[x]` Make startup modes and the daemon lifecycle discoverable.
Acceptance criteria:
- `[x]` Base and nested CLI help explain every command family instead of
@ -346,10 +359,11 @@ control, local CAS, service installation, and written architecture decisions.
- `cargo run -p geth -- daemon run` starts one local daemon.
- No `gethd` or `gethctl` binaries exist in the workspace.
- `[x]` Local daemon control socket.
- `[x]` Local daemon control endpoint.
Acceptance criteria:
- Control request/response types roundtrip through JSONL serialization.
- `geth status` and `geth node id` talk to a running daemon.
- Unix sockets and Windows named pipes carry the same local protocol.
- Control decoding treats input as untrusted and returns structured errors.
- `[x]` Local metadata store and identity.