Skip to main content

System Architecture

Undying Terminal implements a three-component distributed architecture designed for session persistence and network resilience.

Design Principles

1. Session Persistence First

Unlike traditional SSH clients, Undying Terminal prioritizes session survival over raw performance:
  • Sessions survive network disconnects, sleep/wake, VPN switches
  • Sequence-based recovery ensures no data loss (up to 64MB buffer)
  • Automatic reconnection with exponential backoff
Design Trade-off: Buffering adds minimal latency (~1-2ms) but enables bulletproof recovery.

2. Component Separation

The three-component split enables:
  • Decoupled lifecycle: Server runs continuously; clients/terminals reconnect
  • Named pipe isolation: Terminals connect locally; clients connect remotely
  • Process isolation: Shell crashes don’t affect server or client

3. Recovery Over Reliability

Traditional approach: Make connections reliable (don’t drop)
Undying Terminal: Assume connections will fail; focus on recovery
This mindset shift enables:
  • Graceful handling of network instability
  • Transparent reconnection
  • Zero user intervention

Components

Server: undying-terminal-server.exe

Responsibilities

  • TCP listener (default port 2022)
  • Named pipe server for terminal registration
  • Client registry (client_id → session mapping)
  • Passkey authentication
  • Packet relay (terminal ↔ client)

Key Features

  • Multi-client support (one server, many sessions)
  • Session recovery coordination
  • Encryption endpoint (optional)
  • Windows service mode

Architecture

Threading Model:
  • Main thread: Accept loop (TCP + named pipe)
  • Per-client thread: Packet relay
  • Per-terminal thread: Pipe I/O

Terminal: undying-terminal-terminal.exe

Responsibilities

  • ConPTY session management
  • Shell process spawning (cmd.exe, powershell.exe)
  • Named pipe client (connects to server)
  • Terminal I/O relay

Key Features

  • Windows ConPTY integration
  • Terminal resize handling
  • Jumphost proxy mode (—jump)
  • Client ID/passkey generation

Architecture

Jumphost Mode: When started with --jump, terminal acts as a proxy:

Client: undying-terminal.exe

Responsibilities

  • User I/O (stdin/stdout)
  • TCP connection to server
  • Reconnection logic
  • Keepalive sender
  • Port forwarding orchestration

Key Features

  • SSH bootstrap mode (—ssh)
  • Tunnel management (-t, -r)
  • One-shot command execution (-c)
  • Recovery protocol

Architecture

Communication Protocols

TCP Communication (Client ↔ Server)

Packet Structure:
  • encrypted: 0x00 (plaintext) or 0x01 (encrypted)
  • header: Packet type (see EtPacketType/TerminalPacketType)
  • payload: Protobuf-serialized message
Framing (length-prefixed):

Named Pipe Communication (Terminal ↔ Server)

Uses same packet structure, but transport is Windows named pipe:
  • Pipe name: \\.\pipe\undying-terminal (configurable via UT_PIPE_NAME)
  • Connection: Terminal connects; server accepts
  • I/O: Synchronous reads/writes

Data Flow

Initial Connection Flow

1

Terminal Registration

2

Client Handshake

3

Session Active

Reconnection Flow

1

Disconnect Detected

Client detects disconnect (3 missed keepalives or socket error)
2

Reconnect with Backoff

3

Recovery Handshake

Sequence-Based Recovery

How It Works

Each Connection maintains:
Recovery Steps:
  1. Client reconnects → sends last_recv=N (last packet from server)
  2. Server responds → sends last_recv=M (last packet from client)
  3. Catchup phase:
    • Client resends packets M+1 through N (missed by server)
    • Server resends packets N+1 through M (missed by client)
  4. Resume normal operation
Buffer Limit: Only last 64MB is buffered. If client disconnects for hours and server sends >64MB, some packets are lost. This is by design (bounded memory).

Encryption

Optional XSalsa20 symmetric encryption via libsodium:
Security Notes:
  • Nonce MSB differentiates directions (prevents replay)
  • Per-packet nonce increment ensures uniqueness
  • No authentication (encryption only, not MAC)
For production use, enable encryption via shared_key_hex in config.

Threading Model

Server

Client

Terminal

Performance Characteristics

Latency overhead is negligible for interactive terminal use (<5ms is imperceptible).

Scalability

Horizontal Scaling

Not designed for horizontal scaling (single-server architecture). For high availability:
  • Run multiple independent servers on different ports
  • Use client-side failover (connect to backup server)

Vertical Scaling

Server handles:
  • ~1000 concurrent sessions on typical hardware (4-core, 8GB RAM)
  • Limited by thread count and network bandwidth
  • Each session: 1 thread + ~5MB memory

Security Considerations

  1. No authentication beyond passkey - Use strong random passkeys
  2. Optional encryption - Enable for internet-facing servers
  3. No MAC/AEAD - Encryption provides confidentiality, not authenticity
  4. Passkey transmission - Sent in plaintext during initial handshake (before encryption)
Recommendations:
  • Enable shared_key_hex for production
  • Use firewall rules to restrict access
  • Consider VPN for sensitive environments
  • Rotate passkeys periodically

Limitations

By Design

  • Single-server architecture (no clustering)
  • 64MB recovery buffer (bounded memory)
  • Windows-only (ConPTY dependency)

Roadmap

There is no published roadmap. If you want to propose changes or new features, please open an issue: https://github.com/Microck/UndyingTerminal/issues

Next Steps

Component Details

Deep dive into each component

Protocol Specification

Wire protocol and Protobuf messages

Network Flow Diagrams

Visualize packet flows

Configuration Guide

Configure server options