Rename the entire workspace:
- Crate packages: quicnprotochat-{core,proto,server,client,gui,p2p,mobile} -> quicproquo-*
- Binary names: quicnprotochat -> qpq, quicnprotochat-server -> qpq-server,
quicnprotochat-gui -> qpq-gui
- Default files: *-state.bin -> qpq-state.bin, *-server.toml -> qpq-server.toml,
*.db -> qpq.db
- Environment variable prefix: QUICNPROTOCHAT_* -> QPQ_*
- App identifier: chat.quicnproto.gui -> chat.quicproquo.gui
- Proto package: quicnprotochat.bench -> quicproquo.bench
- All documentation, Docker, CI, and script references updated
HKDF domain-separation strings and P2P ALPN remain unchanged for
backward compatibility with existing encrypted state and wire protocol.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.1 KiB
Wire Format Overview
This section documents the serialisation pipeline that transforms application-level data structures into encrypted bytes on the wire. Every byte exchanged between quicproquo clients and the server passes through this pipeline, so understanding it is prerequisite to reading the protocol deep dives or the server/client source code.
Serialisation pipeline
Data flows through three stages on the send path. The receive path reverses the order.
Stage 1 Stage 2 Stage 3
-------- -------- --------
Application Cap'n Proto Transport
data serialisation encryption
RPC call capnp::serialize QUIC/TLS 1.3
(zero-copy bytes)
| | |
v v v
Rust structs Canonical byte Encrypted
& method representation ciphertext
invocations (no deserialization on the wire
needed on receive)
Stage 1: Application creates a message or RPC call
At the application layer, the client or server constructs a typed Cap'n Proto message. In the legacy Envelope path (M1), this means building an Envelope struct with a MsgType discriminant, group ID, sender ID, and opaque payload. In the current NodeService path (M3+), this means invoking a Cap'n Proto RPC method such as enqueue() or fetchKeyPackage().
- Envelope (legacy): see Envelope Schema
- NodeService (current): see NodeService Schema
- AuthenticationService (standalone): see Auth Schema
- DeliveryService (standalone): see Delivery Schema
Stage 2: Cap'n Proto serialises to bytes
Cap'n Proto converts the in-memory message to its canonical wire representation. This is a zero-copy format: the byte layout in memory is identical to the byte layout on the wire. No serialisation or deserialisation pass is required; readers can traverse the bytes in-place using pointer arithmetic.
The wire representation consists of:
- A segment table -- a list of segment sizes encoded as little-endian 32-bit integers.
- One or more segments -- contiguous runs of 8-byte aligned words containing struct data, list data, and far pointers.
Cap'n Proto's canonical form is deterministic for a given message, which makes it suitable for signing: two implementations that build the same logical message will produce identical bytes.
Stage 3: Transport encryption
The serialised bytes are encrypted by the QUIC/TLS 1.3 transport layer. The QUIC transport uses native QUIC stream framing, which provides its own length delimitation. Cap'n Proto RPC over QUIC relies on the capnp-rpc crate's built-in stream adapter.
| Transport | Encryption | Authentication |
|---|---|---|
| QUIC + TLS 1.3 | AES-128-GCM or ChaCha20-Poly1305 (negotiated by TLS) | Server cert (rustls/quinn) |
The transport layer treats the payload as opaque bytes. It does not inspect or interpret the Cap'n Proto content. This clean separation means the serialisation format can evolve independently of the transport.
Schema index
The Cap'n Proto schemas that define the wire-level messages are documented on dedicated pages:
| Schema File | Documentation Page | Purpose |
|---|---|---|
schemas/envelope.capnp |
Envelope Schema | Legacy message envelope (M1) |
schemas/auth.capnp |
Auth Schema | Authentication Service RPC interface |
schemas/delivery.capnp |
Delivery Schema | Delivery Service RPC interface |
schemas/node.capnp |
NodeService Schema | Unified node RPC (current) |
Further reading
- Architecture Overview -- system-level view of how services compose
- Protocol Layers Overview -- how transport, framing, and E2E encryption stack
- ADR-002: Cap'n Proto over MessagePack -- why Cap'n Proto was chosen