Codex 555d738a85
ci / test (push) Has been cancelled
ci / remote-bench (push) Has been cancelled
Initial Dosh implementation
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00
2026-06-11 08:42:28 -04:00

dosh - Dormant Shell

dosh is a low-latency remote terminal designed around fast attach and fast reconnect. It is mosh-shaped, but not a mosh clone: the server is a resident daemon, terminal sessions stay hot, and repeat connects try encrypted UDP before starting SSH.

The core target is simple:

  • First secure trust establishment uses SSH.
  • Existing sessions attach in one encrypted UDP exchange whenever cached credentials allow it.
  • Reconnect after sleep, roaming, or network change resumes in one encrypted UDP exchange.
  • Cold SSH fallback stays competitive with plain ssh by doing less after auth.

Why not just mosh?

mosh is excellent at roaming and high-latency interactivity. Its startup path still has work dosh can avoid:

  1. SSH connects to the host.
  2. SSH starts mosh-server.
  3. The client receives connection material over SSH.
  4. SSH exits and the mosh UDP session begins.

dosh keeps dosh-server running before the client arrives. Named PTY sessions can also be prewarmed, so attaching to default does not need to spawn a daemon, create a PTY, or start a shell on the user's critical path.

This is not an encryption argument against mosh. dosh also encrypts its UDP data channel; the speed difference comes from keeping the server and session hot.

Fast Path Order

The client always tries the cheapest valid path first:

  1. UDP resume: existing ClientId and session key. No SSH. One encrypted UDP request, one encrypted UDP reply.
  2. UDP attach ticket: cached server-issued attach ticket for the same host/user/session/mode. No SSH. One encrypted UDP request, one encrypted UDP reply.
  3. SSH bootstrap: ssh -T user@host dosh-auth ..., then one encrypted UDP attach.
  4. New session: same as attach, but the server must create the PTY/shell unless the session was prewarmed.

The fastest path is not a custom SSH replacement. SSH remains the first trust root; dosh removes SSH from repeat attaches when the server has already issued valid credentials.

Attach tickets are implemented because they are the way a fresh client process can skip SSH after a recent successful bootstrap.

Connection Speed Contract

dosh is measured by terminal-ready time: elapsed time from running dosh host to the first usable terminal screen.

  • UDP resume: <= one measured UDP RTT + local render time.
  • UDP attach ticket: <= one measured UDP RTT + local render time.
  • Warm attach with ControlMaster: <= ssh host true over the existing master + one measured UDP RTT.
  • Cold attach without ControlMaster: <= cold ssh host terminal-ready time + one measured UDP RTT.
  • New session: measured separately because it may need PTY and shell creation.

The client emits timing spans for credential lookup, SSH bootstrap, UDP resume, UDP ticket attach, and terminal-ready time.

Architecture

dosh-server
  UDP socket on one configurable port
  session table keyed by name
  one PTY per named session
  optional prewarmed sessions, default ["default"]
  terminal parser/screen state per session
  client table per session
  encrypted UDP protocol
  tiny SSH-invoked dosh-auth helper mode

dosh-client
  terminal raw mode
  local credential cache
  UDP resume/attach first
  SSH bootstrap fallback
  PTY input/output forwarding
  reconnect and roaming state machine

Install

Default UDP port: 50000. This is intentionally inside the common forwarded range 50000-52000/udp.

Put this repo on your Gitea server, then install on each Linux server you want to attach to:

curl -fsSL https://gitea.example.com/you/dosh/raw/branch/main/install.sh \
  | DOSH_REPO=https://gitea.example.com/you/dosh.git DOSH_PORT=50000 sh -s -- server

Install the client on macOS:

curl -fsSL https://gitea.example.com/you/dosh/raw/branch/main/install.sh \
  | DOSH_REPO=https://gitea.example.com/you/dosh.git DOSH_SERVER=user@host DOSH_PORT=50000 sh -s -- client

Install the client on Windows PowerShell:

$env:DOSH_REPO="https://gitea.example.com/you/dosh.git"; $env:DOSH_SERVER="user@host"; $env:DOSH_PORT="50000"; irm https://gitea.example.com/you/dosh/raw/branch/main/install.ps1 | iex

Attach:

dosh-client user@host

Use named sessions:

dosh-client --session work user@host

Press Ctrl-] to detach the current client while leaving the server session alive.

If SSH and UDP use different public names, specify the UDP address:

dosh-client --dosh-host public.example.com --dosh-port 50000 user@host

Develop

Build:

cargo build

Attach locally, using local bootstrap instead of SSH:

target/debug/dosh-client --local-auth --no-cache local

Benchmark local attach:

target/debug/dosh-bench --local-auth --server local --iterations 5

Benchmark a remote host over SSH bootstrap:

target/release/dosh-bench --server user@host --ssh-port 22 --iterations 3

Benchmark the ControlMaster-backed SSH bootstrap path:

target/release/dosh-bench --server user@host --controlmaster --iterations 3

Run the Docker OpenSSH benchmark gate used by CI. It checks both cold SSH bootstrap and ControlMaster-backed SSH bootstrap against a containerized sshd plus resident dosh-server:

make bench-docker-ssh

The CI workflow includes an optional remote benchmark job. It runs when DOSH_BENCH_HOST, DOSH_BENCH_USER, and DOSH_BENCH_SSH_KEY repository secrets are configured.

Install release binaries and the user systemd service:

make install

Performance Rules

The stack is performance-driven, not fixed by taste. Rust is the default because the likely bottlenecks are network RTT, SSH startup/auth, PTY/shell creation, packet size, and terminal rendering. Change language or runtime only if measurements show they are the bottleneck.

Hot-path rules:

  • Custom UDP protocol with AEAD for v0; no QUIC handshake on attach.
  • Fixed binary packet headers for terminal traffic; no JSON on the protocol path.
  • Preallocated buffers; avoid per-packet heap churn.
  • Single-thread event loop is preferred for the hot path.
  • No PTY allocation, shell spawn, shell rc files, or MOTD on attach to an existing session.
  • Initial snapshot should be sent in the first UDP reply when it fits under the packet budget.

Goals

  • Connection speed as specified above.
  • UDP roaming and reconnect.
  • Encrypted terminal data.
  • Reuse SSH pubkeys for first trust establishment.
  • Named persistent sessions.
  • Multiple clients attached to one session.
  • Optional view-only clients.
  • Single server port, not one port per session.
  • Static server and client binaries where practical.

Non-Goals

  • Replacing SSH as the first public-key trust mechanism.
  • Multi-user access control.
  • Windows support in v0.
  • Full mosh compatibility.
  • Perfect predictive local echo in the first MVP.

Status

Rust implementation is present in this repository. It contains dosh-server, dosh-client, dosh-auth, dosh-bench, shared auth/crypto/protocol modules, a resident PTY server, encrypted UDP bootstrap attach, UDP resume, sealed UDP attach tickets, client ACKs, server retransmit bookkeeping, sliding replay protection, server-side vt100 screen snapshots/diffs, a hardened user systemd unit, an install script, Docker SSH benchmark gates, CI, and protocol/integration tests.

S
Description
Dosh dormant shell: SSH-speed Rust remote terminal attach over encrypted UDP
Readme 13 MiB
v0.1.17 Latest
2026-07-03 20:35:22 +00:00
Languages
Rust 94.5%
Shell 3.7%
PowerShell 1.1%
JavaScript 0.4%
Makefile 0.2%