Skip to content

feat(daemons): reach a P2P daemon over EasyTier, through the nodes it names - #545

Merged
futrime merged 2 commits into
mainfrom
feat/daemons-easytier-client
Nov 2, 2026
Merged

futrime merged 2 commits into
mainfrom
feat/daemons-easytier-client

Conversation

@futrime

@futrime futrime commented Nov 2, 2026

Copy link
Copy Markdown
Member

Unit 6 of the daemon-connection-modes batch: the EasyTier client transport, and peers in the registry.

  • Registry: an easytier entry needs peers, at least one EasyTier node (tcp|udp|ws|wss|quic|wg://host:port). Without one the write is refused with An EasyTier daemon needs at least one node., and a malformed node is refused by name. peers is listed by GET /api/daemons and refused on ssh entries. A replace that gives no secret still keeps the secret.
  • Client (_Remote._joins): downloads easytier-core only where it is missing, reporting installing / Downloading EasyTier <v> while it does. It then starts easytier.joining(secret, <free port>, port=easytier.PORT, peers=entry peers) and waits (up to 60 s) until the far hmz web answers /api/daemons/local/state with the derived key. A far hmz older than this one is refused, which fails the daemon. Once up, it asks the far web every 5 s and treats 3 misses in a row, or a change of version, as lost. A lost daemon is retried with the same backoff as ssh, and close terminates and reaps easytier-core. The secret never appears in argv, details or exceptions.
  • Tests: unit tests for registry validation and for installing → failed while downloading, with easytier mocked. A new tests/integration/test_web_p2p.py uses the fake easytier and a far hmz web in its own home with the derived key; it covers reading through /d/far/api/..., refusing an older server, and a drop followed by a reconnect and a reap. Existing web daemon tests now include peers.
  • Docs: peers added to user/web, reference/settings and reference/web.

Notes:

  • EasyTier entries written by feat(daemons): a daemon is reached via ssh or easytier, its secret never listed #539 without peers are now invalid, so the next write drops them. The page has no P2P form yet, so this is unlikely to affect anyone.
  • The serving end (hmz server) must meet through the same nodes. Unit 7/8 own that, and the specs.
  • The far web's fixed key in the test is set by a test-only helper, because hmz web has no key flag (unit 7 owns the CLI).

Checks: ruff, ruff format, pyright and the full uv run pytest. A manual e2e with the fake easytier also passed: near hmz web → POST daemon → connect → up → /d/far/api/daemons.

… names

An EasyTier daemon now names its nodes, `peers`: at least one
tcp|udp|ws|wss|quic|wg://host:port, listed by GET /api/daemons. Reaching
one downloads easytier-core where needed (installing), joins the network
of its secret on a free loopback port, waits until the server's hmz web
answers with the derived key, refuses a server older than this hmz, and
asks it every few seconds whether it still answers; a server lost is
reached again with the same backoff as ssh, and closing reaps
easytier-core. The secret is never on a command line or said.
@futrime
futrime added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit a1f0104 Nov 2, 2026
13 checks passed
@futrime
futrime deleted the feat/daemons-easytier-client branch November 2, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant