Saved servers
Keep the machines this koshi dials — names, addresses, certificate fingerprints, and secrets — and reconnect when a remote link drops.
A saved server is one record on the machine you sit at: a name, an address,
the fingerprint of the certificate that machine presents, and a secret. The
store is readable only by its owner, and koshi remote list never prints a
secret.
| Command | Result |
|---|---|
koshi remote new | Save a server, asking for its name, address, certificate fingerprint and secret |
koshi remote edit <SERVER> | Change one saved server's name, address, certificate fingerprint or secret |
koshi remote list [--format table|json] | List the servers this machine has saved |
koshi remote forget <SERVER> | Drop one saved server |
koshi remote set-secret <SERVER> | Replace the secret of one saved server |
Naming a server
--remote takes either the host:port a machine listens on or the name it was
saved under. The first connection names the address and the certificate
fingerprint, and --save-as gives it a short name:
koshi attach --remote laptop.local:7654 --certificate-fingerprint sha256:3f6a0c2e9b8d4f17a5c3e1d0b9f8a7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0 --save-as work S-quiet-heronAfter that the name stands in for the address and the fingerprint:
koshi attach --remote work S-quiet-heronA first connection from any command that takes --remote, koshi list-sessions included, saves the address, the fingerprint, and the secret.
Without --save-as the server is saved with no name, and koshi remote list
prints - for it. A later koshi attach --remote <address> --save-as <NAME>
names it. A saved server refuses a --save-as name other than the one it has;
koshi remote edit renames it.
koshi remote new saves a server without attaching to one of its sessions. See
the setup walkthrough.
Certificate fingerprints
The fingerprint is the sha256 of the server's certificate, written as sha256:
followed by 64 lowercase hex characters. koshi share grant and koshi share open on the server print it in each connect command, and koshi remote list
prints it for each saved server.
An address that is not saved needs --certificate-fingerprint; without it the
connection is refused and nothing is dialled:
koshi: invalid arguments: laptop.local:7654 is not saved, so the fingerprint of its certificate is needed: add `--certificate-fingerprint <FINGERPRINT>` with the fingerprint `koshi share grant` printed on that machinekoshi compares the fingerprint during the TLS handshake, before the secret is sent. A server that presents another certificate is refused, the secret is not sent, and the refusal names the address and both fingerprints.
A saved server accepts --certificate-fingerprint only when it matches the
saved one. To change the fingerprint a saved server expects, for example after
the server's certificate changed on purpose, run koshi share open on the
server to print the new one, then:
koshi remote edit workA changed fingerprint means the machine answering that address may not be the one you saved. Change the saved fingerprint only when you know why the certificate changed.
A saved server that holds no fingerprint is never dialled. The sweep leaves it out and names it on standard error with the command that fixes it:
koshi: desk holds no certificate fingerprint, so it is not dialled; run `koshi remote edit desk` and give the fingerprint `koshi share grant` printed on that machineEditing a saved server
koshi remote edit workIt asks the same four questions with the saved values in brackets. An empty answer keeps the value in brackets, and an empty secret keeps the saved secret, so only what changes is typed:
$ koshi remote edit work
press Enter to keep the value in brackets. An empty secret keeps the saved one. Ctrl-C stops without saving.
name [work]:
address [laptop.local:7654]: laptop.local:7655
fingerprint [sha256:3f6a0c2e9b8d4f17a5c3e1d0b9f8a7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0]:
secret:
checking laptop.local:7655 …
updated work at laptop.local:7655.The check dials the server with the fingerprint the answers settled on. When
it does not pass, the last question is save the change anyway? [y/N].
Nothing is written until every answer has settled. Ctrl-C at any question, and input that ends before an answer arrives, leave the saved server unchanged.
Rotating a secret
Once the serving machine grants a fresh secret:
koshi remote set-secret workIt reads the new secret the way a connection does — from
KOSHI_REMOTE_SECRET, or asked for at the terminal.
A --remote connection to a saved server presents the saved secret. If
KOSHI_REMOTE_SECRET holds a secret no saved server holds, the connection is
refused before it opens and names koshi remote set-secret. A bare
koshi list-sessions and a bare koshi attach present each saved server's own
secret and do not read KOSHI_REMOTE_SECRET.
Two koshi processes at once
The store is read again at the moment the record is written, and the read and
the write are held against every other koshi by a lock on
remote/servers.lock beside the store.
- A server another
koshisaved while the questions were open is still saved, and a name or address that another record took meanwhile is refused with nothing written. - Every command that changes a saved server takes that lock,
koshi attachincluded, which stamps the record it dialled. - A lock another
koshistill holds after five seconds readskoshi: IPC unavailable: another koshi is changing the saved servers; try again. The operating system releases the lock if thekoshiholding it dies. - The lock is never held while a question waits for an answer.
An edit re-reads its record at that same moment. A record whose name, address,
secret, or fingerprint another koshi changed while the questions were open is
refused, and the older values are not written:
koshi: invalid arguments: work changed while the questions were open, so nothing was saved; run `koshi remote edit work` againThe sweep
A bare koshi list-sessions and a bare koshi attach sweep every saved server
and append what answered. The sweep waits two seconds in total, not two
seconds per server. A server not heard from inside that wait is left out:
koshi: work did not answer; its sessions are not listedA server whose connection fails is left out too, and its line carries the same
sentence koshi attach --remote work prints for that failure, naming what to
do.
Reconnecting
remote-reconnect is on by default and belongs to the terminal you sit at. It
applies only to a terminal viewing a session on another machine.
A link drops when it breaks, or when no byte arrives over it for
remote-link-timeout-ms
(30 seconds by default). A dropped link dials that machine again — after 1
second, then 2, 4, 8, and 8 before every dial after that — for up to 120
seconds. While it waits, the tab strip reads a tag shaped like:
RECONNECTING (attempt 4, retry in 8s)The first number is the dial it is about to make; the second is the seconds
left before that dial. While a dial runs, the tag reads
RECONNECTING (attempt 4, dialing).
Joining again puts back the tab you were on, the focused pane of each tab, the fullscreened pane of each tab, the scroll offset of each pane, and your floating panes. Keys and pastes typed while the link is down are dropped. The quit keybinding leaves at once while the link is down; koshi prints the commands that list and rejoin the session, and exits 0.
Each dial reads the saved server as it is at that moment, so a
koshi remote edit or koshi remote set-secret made while attached takes
effect at the next dial.
A refusal no dial can change stops the dialing at once: a certificate that is
not the expected one, a token the server does not admit, a token that does not
reach the session, two builds sharing no protocol version, or no saved server
at that address any more. koshi then puts your terminal back the way it found
it, prints the cause, the session continues without you, and the commands
that list and rejoin the session, and exits with a non-zero status.
Off, a dropped link ends the terminal, printing how to attach again by hand. A link to a session on this machine ends the terminal either way.
version 2
remote-reconnect #true