feat: dumbpipe daemon#101
Draft
Frando wants to merge 7 commits into
Draft
Conversation
Add a `dumbpipe daemon` subcommand that runs any number of incoming and outgoing tunnels over a single iroh endpoint, driven by a TOML config. - `[[connect]]` entries expose a local TCP port that forwards to a remote endpoint under a name; `[[accept]]` entries forward incoming named streams to a local TCP backend selected by name. - A "named" handshake (prefix, u32 length, name) routes streams, so one endpoint can multiplex several tunnels. - `remote` accepts a bare endpoint id or a full ticket; ticket address hints are seeded via a static address lookup alongside discovery. - The connect side reuses one pooled iroh connection per remote across TCP streams and retries a failed connect once. - The secret key is read from IROH_SECRET, else a hex key file under the data dir, else generated and persisted. Config and secret default to <data_dir>/dumbpipe/daemon/. Documented in docs/daemon.md and linked from the README.
Build out the daemon into a configurable, long-running service.
- New daemon ALPN, distinct from the single-tunnel dumbpipe protocol.
- Per-stream header is now postcard-encoded { name, token }.
- Optional per-tunnel token: an accept entry with a token only forwards
streams whose connect side presents the same token.
- Subcommands (start is the default): `accept` and `connect` append
entries to the config file, `show` prints the configured tunnels, and
`start` runs the daemon. `accept --secure` generates a random token.
- `start` creates an empty config file when none exists.
- `reload` (default on) watches the config with notify and applies
changes live: accept routes swap atomically, connect tunnels are
reconciled by local addr, new remotes' hints are registered.
- Connection reuse via iroh-util ConnectionPool with one retry on
connect failure, plus a static address lookup so ticket-form remotes'
relay and address hints are honored.
- Logging: connect/disconnect events inside incoming{remote}:tcp{name,
target} and outgoing{remote}:tcp{name, target} spans; the daemon
defaults to dumbpipe=info,iroh=info when RUST_LOG is unset.
Documented in docs/daemon.md and linked from the README.
Add service subcommands backed by the service-manager crate, and make a subcommand required so bare `dumbpipe daemon` prints help. - `install` / `uninstall` / `start` / `stop` manage a user-level service (systemd user units, launchd, etc.). `install` runs `daemon run` with an absolute config path and enables start at login. - `run` runs the daemon in the foreground (formerly the default `start`). - The systemd unit is named `dumbpipe.service`. - Default log filter `dumbpipe=info,iroh=info` now applies to `daemon run` specifically. Documented in docs/daemon.md and the README.
Add `dumbpipe daemon status`, which reports the service status via service-manager: not installed, running, or stopped.
service-manager loads the launchd agent with `launchctl load`, which targets the GUI login session and aborts over SSH. Fall back to managing the agent in the per-user (Background) launchd domain that an SSH session has, so install/start/stop/status/uninstall work over SSH without elevated permissions. status also checks the per-user domain, since service-manager queries the GUI domain and would report not installed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
not sure if this is too much for this repo. can also move it into a new repo/crate. also not yet fully reviewed (initial version was vibecoded).
but: i wanted to have this for quite a while and it turned out to be really straightforward
dumbpipe daemonstarts a daemon that runs multiple dumbpipe TCP proxies, defined in a config file.each stream opens with a hello with a
nameto map it to the target and an optional token to secure it.config file is reloaded on changes, so you can add connections with
dumbpipe daemon acceptanddumbpipe daemon connect.Workflow.
dumbpipe daemon accept <name> <addr> [--secure]adds an inbound tunneland can mint a token.
dumbpipe daemon connect <remote>:<name> <local-addr> [--token <t>]adds anoutbound tunnel.
dumbpipe daemon showprints what is configured.dumbpipe daemon runruns in the foreground and prints the endpoint id anda ticket to share.
dumbpipe daemon install, thenstart/status/stop/uninstallmanage it as a user-level service.
reload = true(the default) the daemon watches itsconfig file: added or removed tunnels take effect without a restart, so the
acceptandconnectsubcommands reconfigure a running daemon on the fly.Two daemons pair up by matching names: a
connecttunnel forwards a local portto a remote's
accepttunnel of the same name, over a single reused, encryptediroh connection.