Put every network's address on the interface, and split up from join
Two networks on one agent, and only one of them worked. The interface plan is exhaustive by contract — it is what the interface should carry and nothing else — but the request that built it held a single address, so the provisioner was told about the first network and took the second one's address off, or never put it on. On the host that is a network whose address the operating system has never heard of: the tunnel is up, the status says all is well, and nothing routes. The request now carries every address, which is also what takes one off when a network is left or stopped. The other half is the command line. `up --network X --secret Y` and `network join` were two ways to do the same thing, and the one on `up` could only be undone by restarting — which is how a network somebody left came back, and how an invite line told the other side to start their agent with a network baked into it. So they are one thing now, split the way the system is: **`up` runs the agent** — the device's one process, serving whatever it has joined, answering `status`, taking instructions — and **`join` decides what it belongs to**, at any time, while it runs. `join` is at the top level because it is what gets typed; `network join` is the same command for anyone who likes the long form. Every line that told somebody to type the old form is gone with it: the invite after making a network, the lock error from a second `up`, the empty-network hint in `id`, the README walkthrough and the WireGuard document. The invite now prints the `join` line for the other machine and, separately, the `up --peer` line for an agent that is not running yet — two commands, because they really are two, and no amount of wording makes starting an agent the same thing as joining a network. Joining says how the network stood before: new, already here, or stopped and now running again. That last one matters — joining is an instruction to run it, so it undoes a stop, and a pause that ends without a word is a pause nobody can rely on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -70,18 +70,29 @@ On the first machine:
|
||||
|
||||
```bash
|
||||
cargo build --release
|
||||
./target/release/tsunagi network secret generate # prints tsn1...; share it privately
|
||||
./target/release/tsunagi status # this device, the agent, and this host
|
||||
./target/release/tsunagi network # the networks this device belongs to
|
||||
|
||||
./target/release/tsunagi up --network lab --secret "$SECRET"
|
||||
```
|
||||
|
||||
It prints its endpoint id and then waits. On the second machine, pass that id:
|
||||
Two commands do the work, and they are separate on purpose: `up` runs the
|
||||
agent — one per device, for as long as you want it — and `join` decides
|
||||
what it belongs to, at any time, while it runs.
|
||||
|
||||
```bash
|
||||
./target/release/tsunagi up --network lab --secret "$SECRET" \
|
||||
--peer <endpoint-id-from-the-first-machine>
|
||||
# Terminal one: the agent. It prints its endpoint id and then serves.
|
||||
./target/release/tsunagi up
|
||||
|
||||
# Terminal two: make a network. With no --secret it invents one and prints
|
||||
# it, along with the line to send the other machine.
|
||||
./target/release/tsunagi join --network lab
|
||||
```
|
||||
|
||||
On the second machine, start its agent with the first machine's endpoint id
|
||||
and join the same network with the secret that was printed:
|
||||
|
||||
```bash
|
||||
./target/release/tsunagi up --peer <endpoint-id-from-the-first-machine>
|
||||
./target/release/tsunagi join --network lab --secret tsn1...
|
||||
```
|
||||
|
||||
Within a few seconds both print something like:
|
||||
@@ -132,8 +143,8 @@ ping 100.65.243.53
|
||||
what they find, so `--ipv4-range` only matters for whoever starts the network:
|
||||
|
||||
```bash
|
||||
tsunagi up --network lab --secret "$SECRET" --ipv4-range 10.44.0.0/16
|
||||
tsunagi up --network lab --secret "$SECRET" --ipv4-range none # no data plane
|
||||
tsunagi up --ipv4-range 10.44.0.0/16
|
||||
tsunagi up --ipv4-range none # no data plane at all
|
||||
```
|
||||
|
||||
One agent has one interface, so two of its networks cannot both use that
|
||||
@@ -195,7 +206,7 @@ each named after the network, so members can be reached by name instead of
|
||||
by address:
|
||||
|
||||
```bash
|
||||
tsunagi up --network lab --secret "$SECRET" --dns
|
||||
tsunagi up --dns # or `tsunagi dns on` against a running agent
|
||||
dig @127.0.0.1 -p 5354 music.lab
|
||||
```
|
||||
|
||||
@@ -336,29 +347,29 @@ tsunagi dns on start it, now and after every restart
|
||||
tsunagi dns off stop it, now and after every restart
|
||||
```
|
||||
|
||||
**A network without a secret makes one.** `tsunagi up --network lab` and
|
||||
`tsunagi network join --network lab` both resolve a bare name the same way: if this device is already in exactly
|
||||
one network called `lab`, that one — so the name alone resumes what you have;
|
||||
if it is in none, a fresh random secret, printed in full along with the one
|
||||
line to send the others:
|
||||
**A network without a secret makes one.** `tsunagi join --network lab`
|
||||
resolves a bare name in the obvious way: if this device is already in
|
||||
exactly one network called `lab`, that one — so the name alone resumes what
|
||||
you have; if it is in none, a fresh random secret, printed in full with the
|
||||
line to send the other machine:
|
||||
|
||||
```
|
||||
tsunagi is up
|
||||
network lab (k2on43wadb…)
|
||||
secret tsn1u7c…
|
||||
joined `lab` (k2on43wadbi5x267vp6z3ogkm7nbjedfdoxyauxhtxhwqrprylba)
|
||||
secret tsn1u7c…
|
||||
|
||||
No --peer was given, so this agent waits to be contacted. Run this on the
|
||||
other machine:
|
||||
Run this on the other machine:
|
||||
|
||||
tsunagi up --network lab --secret tsn1u7c… --peer 91e83a6e2b7a…
|
||||
tsunagi join --network lab --secret tsn1u7c…
|
||||
|
||||
Its agent has to be running. If it is not:
|
||||
|
||||
tsunagi up --peer 91e83a6e2b7a…
|
||||
```
|
||||
|
||||
`up` says which of the two happened — `· new` or `· already here` beside
|
||||
the network — and warns when the name is one another configured network
|
||||
also answers to, because a name is a label and the id is the identity. A
|
||||
command line with a different secret makes a *different* network of the
|
||||
same name, and that is how a network you left comes back: the secret on the
|
||||
command line is what decides which network it is.
|
||||
Two networks of one name is a thing that happens — a mistyped secret makes
|
||||
one — so joining says whether the network was already here, and warns when
|
||||
another configured network answers to the same name. A name is a label and
|
||||
the id is the identity.
|
||||
|
||||
That is the ad-hoc case: one person makes a network and sends the command
|
||||
round. The secret is printed *only* when the agent invented it — there is
|
||||
|
||||
Reference in New Issue
Block a user