Host-Guest Communication
Host and guest communicate over AF_VSOCK (port 1234) using the void-box-protocol crate. The protocol uses a simple length-prefixed binary framing. Most payloads are JSON, but Ping, Pong, and PtyData use raw bytes.
Frame Format
+---------------+-----------+--------------------+
| length (4 B) | type (1B) | payload (N bytes) |
+---------------+-----------+--------------------+
| Field | Size | Description |
|---|---|---|
length | 4 bytes | u32 little-endian, payload size only (excludes the 5-byte header) |
type | 1 byte | Message type discriminant |
payload | N bytes | Message payload. Usually JSON; Ping, Pong, and PtyData are raw bytes. |
Message Types
| Type Byte | Direction | Message | Description |
|---|---|---|---|
0x01 | host → guest | ExecRequest | Execute a command (program, args, env, timeout) |
0x02 | guest → host | ExecResponse | Command result (stdout, stderr, exit_code) |
0x03 | host → guest | Ping | Session authentication handshake. Raw payload: 32-byte secret plus optional 4-byte protocol version. |
0x04 | guest → host | Pong | Authentication reply with protocol version |
0x05 | host → guest | Shutdown | Request guest shutdown |
0x06 | host → guest | FileTransfer | Legacy file transfer request |
0x07 | guest → host | FileTransferResponse | Legacy file transfer response |
0x08 | guest → host | TelemetryData | Guest telemetry batch |
0x09 | host → guest | TelemetryAck | Telemetry acknowledgement |
0x0A | host → guest | SubscribeTelemetry | Start telemetry stream |
0x0B | host → guest | WriteFile | Write file to guest filesystem |
0x0C | guest → host | WriteFileResponse | Write file acknowledgement |
0x0D | host → guest | MkdirP | Create directory tree |
0x0E | guest → host | MkdirPResponse | Mkdir acknowledgement |
0x0F | guest → host | ExecOutputChunk | Streaming output chunk (stream, data, seq) |
0x10 | host → guest | ExecOutputAck | Flow control ack (optional) |
0x11 | both | SnapshotReady | Guest signals readiness for live snapshot |
0x12 | host → guest | ReadFile | Read file from guest filesystem |
0x13 | guest → host | ReadFileResponse | File contents or error |
0x14 | host → guest | FileStat | Stat a guest file path |
0x15 | guest → host | FileStatResponse | File metadata (size, mode, mtime) |
0x16 | host → guest | PtyOpen | Open interactive PTY session (program, args, env, interactive flag) |
0x17 | guest → host | PtyOpened | PTY open result (success or error message) |
0x18 | both | PtyData | Raw terminal I/O bytes (not JSON-encoded) |
0x19 | host → guest | PtyResize | Terminal window size change (cols, rows) |
0x1A | host → guest | PtyClose | Request PTY session close (sends SIGHUP to child) |
0x1B | guest → host | PtyClosed | PTY child exited (exit_code) |
Note: PtyData is the only high-throughput stream message with raw bytes instead of JSON. Ping and Pong also use raw bytes for the session-secret and version handshake.
Security
MAX_MESSAGE_SIZE
64 MB — prevents OOM from untrusted length fields. Messages exceeding this limit are rejected before allocation.
Session Secret
32-byte hex token injected as voidbox.secret=<hex> in kernel cmdline. The guest-agent reads it from /proc/cmdline at boot and requires a successful Ping before the connection can send ExecRequest, file, PTY, or telemetry messages.
ExecRequest Debug Redaction
The Debug impl for ExecRequest redacts environment variables matching KEY, SECRET, TOKEN, PASSWORD patterns — preventing accidental credential exposure in logs.
Guest Networking
The vsock protocol above is backend-neutral. Guest IP behavior depends on the VM backend.
Linux/KVM
Linux/KVM uses smoltcp-based usermode networking (SLIRP) — no root, no TAP devices, no bridge configuration.
Guest VM Host
+---------------------+ +------------------+
| eth0: 10.0.2.15/24 | | |
| gw: 10.0.2.2 |-- virtio-net ------| SLIRP stack |
| dns: 10.0.2.3 | (MMIO) | (smoltcp) |
+---------------------+ | |
| 10.0.2.2 -> NAT |
| -> 127.0.0.1 |
+------------------+
Linux/KVM IP Details
| Endpoint | Address | Description |
|---|---|---|
| Guest IP | 10.0.2.15/24 | Static IP assigned to guest eth0 |
| Gateway | 10.0.2.2 | Mapped to host 127.0.0.1 — guest reaches host services via this address |
| DNS | 10.0.2.3 | Forwarded to host resolver |
Outbound TCP/UDP is NATed through the host. The guest reaches host services (e.g. Ollama on :11434) via 10.0.2.2.
macOS/VZ
macOS uses VZNATNetworkDeviceAttachment with DHCP inside the guest instead of the fixed SLIRP 10.0.2.x layout. In the current examples, the guest reaches host-local services through 192.168.64.1, but that addressing comes from the VZ NAT environment rather than the wire protocol itself.