Documentation

The native protocol

The implemented direct-address path uses one QUIC connection and one bidirectional stream per transfer session. The stream carries negotiation, manifest, receive-plan, payload, and acknowledgement frames.

Transport

Transport is QUIC via quinn with rustls. The receiver presents a self-signed certificate today. Identity material is persisted, but transfer-path peer authentication is not wired into the direct sender yet.

The direct protocol begins with FERRY01\n and then exchanges JSON length-prefixed negotiation frames. Unsupported version ranges fail closed before any manifest or body bytes are sent.

Session shape

client -> server : QUIC connect
client -> server : one bidirectional stream : FERRY01\n
client -> server : DirectProtocolHello
server -> client : DirectProtocolResponse
client -> server : TransferManifest
server -> client : DirectReceivePlan
client -> server : DirectPayloadHeader + payload bytes per requested file
server -> client : DirectAck

Manifest entries

Each manifest entry carries enough metadata to make a deterministic resume decision:

  • relative_path — normalized, traversal-rejected destination path.
  • size — total bytes.
  • blake3 — full BLAKE3 hash of the file body.
  • unix_mode — optional, applied only on Unix targets.
  • modified_unix_ms — best-effort wall-clock modification time.

BLAKE3 was chosen because it is fast, parallel-friendly, and supports cheap prefix verification for resume.

Resume probe

receiver: locate destination_path
  if missing -> decision = TransferFromZero
  if existing and size matches and full BLAKE3 matches -> decision = Skip
  if existing and size <= manifest size -> hash existing prefix:
    if prefix BLAKE3 matches sender prefix BLAKE3 -> decision = ResumeAt(offset)
    else -> decision = TransferFromZero
  else -> decision = Conflict

Destination safety

Receive-side path safety is non-negotiable. Every entry is checked before any byte is written:

  • Reject absolute paths and .. traversal segments.
  • Reject Windows reserved device names (CON, AUX, NUL, and friends).
  • Reject slash or backslash inside path components, colon-containing components, trailing spaces, trailing dots, and non-UTF-8 components.
  • Write through a temp file in the destination directory and atomically rename on success.

Versioning rules

Protocol changes follow these rules:

  • Major version bumps require explicit compatibility notes in docs/protocol-native.md.
  • Discovery TXT records carry enough data to select transport without opening a connection.
  • Golden tests pin the on-the-wire bytes of negotiation frames so regressions are obvious.

The repository copy at docs/protocol-native.md is the source of truth and may include fields that have not been merged onto this page yet.