chore: rename project quicnprotochat -> quicproquo (binaries: qpq)

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>
This commit is contained in:
2026-03-01 20:11:51 +01:00
parent 553de3a2b7
commit 853ca4fec0
152 changed files with 4070 additions and 788 deletions

View File

@@ -16,10 +16,10 @@ This compiles all four crates:
| Crate | Type | Purpose |
|---|---|---|
| `quicnprotochat-core` | library | Crypto primitives, MLS `GroupMember` state machine, hybrid KEM |
| `quicnprotochat-proto` | library | Cap'n Proto schemas, generated types, envelope serialisation helpers |
| `quicnprotochat-server` | binary | Unified Authentication + Delivery Service (`NodeService`) |
| `quicnprotochat-client` | binary | CLI client with subcommands (`ping`, `register`, `send`, `recv`, etc.) |
| `quicproquo-core` | library | Crypto primitives, MLS `GroupMember` state machine, hybrid KEM |
| `quicproquo-proto` | library | Cap'n Proto schemas, generated types, envelope serialisation helpers |
| `quicproquo-server` | binary | Unified Authentication + Delivery Service (`NodeService`) |
| `quicproquo-client` | binary | CLI client with subcommands (`ping`, `register`, `send`, `recv`, etc.) |
For a release build with LTO, symbol stripping, and single codegen unit:
@@ -47,25 +47,25 @@ cargo test --workspace
The test suite includes:
- **`quicnprotochat-proto`**: Round-trip serialisation tests for Cap'n Proto `Envelope` messages (Ping, Pong, corrupted-input error handling).
- **`quicnprotochat-core`**: Two-party MLS round-trip (`create_group` / `add_member` / `send_message` / `receive_message`), group ID lifecycle assertions.
- **`quicnprotochat-client`**: Integration tests for MLS group operations and auth service interactions (require a running server or use in-process mocks).
- **`quicproquo-proto`**: Round-trip serialisation tests for Cap'n Proto `Envelope` messages (Ping, Pong, corrupted-input error handling).
- **`quicproquo-core`**: Two-party MLS round-trip (`create_group` / `add_member` / `send_message` / `receive_message`), group ID lifecycle assertions.
- **`quicproquo-client`**: Integration tests for MLS group operations and auth service interactions (require a running server or use in-process mocks).
To run tests for a single crate:
```bash
cargo test -p quicnprotochat-core
cargo test -p quicproquo-core
```
---
## Cap'n Proto code generation
The `quicnprotochat-proto` crate does not contain hand-written Rust types for wire messages. Instead, its `build.rs` script invokes the `capnp` compiler at build time to generate Rust source from the `.capnp` schema files.
The `quicproquo-proto` crate does not contain hand-written Rust types for wire messages. Instead, its `build.rs` script invokes the `capnp` compiler at build time to generate Rust source from the `.capnp` schema files.
### How it works
1. `build.rs` locates the workspace-root `schemas/` directory (two levels above `crates/quicnprotochat-proto/`).
1. `build.rs` locates the workspace-root `schemas/` directory (two levels above `crates/quicproquo-proto/`).
2. It invokes `capnpc::CompilerCommand` on all four schema files:
- `schemas/envelope.capnp` -- top-level wire envelope with `MsgType` discriminant
- `schemas/auth.capnp` -- `AuthenticationService` RPC interface
@@ -82,7 +82,7 @@ The `build.rs` script emits `cargo:rerun-if-changed` directives for each schema
The `src_prefix` is set to the `schemas/` directory so that inter-schema imports (e.g., `using Auth = import "auth.capnp".Auth;` inside `node.capnp`) resolve correctly.
### Design constraints of quicnprotochat-proto
### Design constraints of quicproquo-proto
The proto crate is intentionally restricted:

View File

@@ -1,6 +1,6 @@
# Certificate lifecycle and CA-signed TLS
This page describes how to use CA-issued certificates with quicnprotochat and how to think about certificate pinning, rotation, and lifecycle.
This page describes how to use CA-issued certificates with quicproquo and how to think about certificate pinning, rotation, and lifecycle.
For basic server TLS setup (self-signed certs, generation), see [Running the Server](running-the-server.md#tls-certificate-handling).
@@ -8,8 +8,8 @@ For basic server TLS setup (self-signed certs, generation), see [Running the Ser
## Current behaviour
- **Server:** Uses a single TLS certificate and private key (DER format). If the files are missing and the server is not in production mode, it generates a self-signed certificate. Production mode (`QUICNPROTOCHAT_PRODUCTION=1`) requires existing cert and key files.
- **Client:** Trusts exactly the roots in the file given by `--ca-cert` (or `QUICNPROTOCHAT_CA_CERT`). Typically this is the server's own certificate (pinning) or a CA that signed the server cert.
- **Server:** Uses a single TLS certificate and private key (DER format). If the files are missing and the server is not in production mode, it generates a self-signed certificate. Production mode (`QPQ_PRODUCTION=1`) requires existing cert and key files.
- **Client:** Trusts exactly the roots in the file given by `--ca-cert` (or `QPQ_CA_CERT`). Typically this is the server's own certificate (pinning) or a CA that signed the server cert.
---
@@ -20,7 +20,7 @@ To pin the server so the client only connects to that server:
1. Copy the server's certificate file (e.g. `data/server-cert.der`) from the server (or your deployment).
2. Use that file as the client's CA cert:
```bash
quicnprotochat --ca-cert /path/to/server-cert.der ...
qpq --ca-cert /path/to/server-cert.der ...
```
3. The client will only accept a connection if the server presents that exact certificate (or a chain ending in it). No separate CA bundle is required.
@@ -43,12 +43,12 @@ To use a certificate issued by a public CA (e.g. Let's Encrypt):
```
2. **Configure the server** to use those paths:
```bash
export QUICNPROTOCHAT_TLS_CERT=/etc/quicnprotochat/server-cert.der
export QUICNPROTOCHAT_TLS_KEY=/etc/quicnprotochat/server-key.der
export QPQ_TLS_CERT=/etc/quicproquo/server-cert.der
export QPQ_TLS_KEY=/etc/quicproquo/server-key.der
```
3. **Configure the client** to trust the CA that signed the server cert. Use the CAs certificate (or the CA bundle) as `--ca-cert`:
```bash
quicnprotochat --ca-cert /etc/ssl/certs/your-ca.der --server-name your.server.example ...
qpq --ca-cert /etc/ssl/certs/your-ca.der --server-name your.server.example ...
```
The `--server-name` must match the certificates SAN (e.g. DNS name).
@@ -60,7 +60,7 @@ To use a certificate issued by a public CA (e.g. Let's Encrypt):
- **Manual rotation:** Replace `server-cert.der` and `server-key.der` on disk, then restart the server. Clients that pin the new cert must be updated with the new cert file.
- **Lets Encrypt renewal:** After renewing (e.g. via certbot), convert the new cert and key to DER, replace the files, and restart the server. If clients use the CA cert (e.g. ISRG Root X1) as `--ca-cert`, they do not need updates when the server cert is renewed.
- **OCSP / CRL:** The quicnprotochat server does not currently perform OCSP stapling or CRL checks. Revocation is handled by the client or by operational procedures (e.g. short-lived certs, rotation on compromise).
- **OCSP / CRL:** The quicproquo server does not currently perform OCSP stapling or CRL checks. Revocation is handled by the client or by operational procedures (e.g. short-lived certs, rotation on compromise).
---
@@ -70,6 +70,6 @@ To use a certificate issued by a public CA (e.g. Let's Encrypt):
|------------------|-------------|--------------------|
| Pinned (single server) | Self-signed or any | Servers cert file |
| CA-issued | Lets Encrypt (or other CA) | CA cert (or bundle) |
| Production | Always use existing cert/key; set `QUICNPROTOCHAT_PRODUCTION=1` | CA or pinned server cert |
| Production | Always use existing cert/key; set `QPQ_PRODUCTION=1` | CA or pinned server cert |
For production, prefer either (a) certificate pinning with the servers cert or (b) a CA-issued server cert with clients trusting the CA, and plan for rotation and restart (or future reload support).

View File

@@ -75,13 +75,13 @@ You will need **three terminal windows**: one for the server, one for Alice, and
In **Terminal 1** (Server):
```bash
cargo run -p quicnprotochat-server
cargo run -p quicproquo-server
```
Wait for the log line confirming it is accepting connections:
```
INFO quicnprotochat_server: accepting QUIC connections addr="0.0.0.0:7000"
INFO quicproquo_server: accepting QUIC connections addr="0.0.0.0:7000"
```
If this is the first run, you will also see a log line about generating the self-signed TLS certificate. The certificate is written to `data/server-cert.der`, which the client will use for TLS verification.
@@ -91,7 +91,7 @@ If this is the first run, you will also see a log line about generating the self
In **Terminal 2** (Alice):
```bash
cargo run -p quicnprotochat-client -- register-state \
cargo run -p quicproquo-client -- register-state \
--state alice.bin \
--server 127.0.0.1:7000
```
@@ -116,7 +116,7 @@ KeyPackage uploaded successfully.
In **Terminal 3** (Bob):
```bash
cargo run -p quicnprotochat-client -- register-state \
cargo run -p quicproquo-client -- register-state \
--state bob.bin \
--server 127.0.0.1:7000
```
@@ -137,7 +137,7 @@ In **Terminal 2** (Alice):
First, create the group:
```bash
cargo run -p quicnprotochat-client -- create-group \
cargo run -p quicproquo-client -- create-group \
--state alice.bin \
--group-id "demo-chat"
```
@@ -151,7 +151,7 @@ Alice is now the sole member of the group at epoch 0.
Next, invite Bob using his identity key from Step 3:
```bash
cargo run -p quicnprotochat-client -- invite \
cargo run -p quicproquo-client -- invite \
--state alice.bin \
--peer-key <BOB_KEY> \
--server 127.0.0.1:7000
@@ -173,7 +173,7 @@ Alice's group state has now advanced to epoch 1.
In **Terminal 3** (Bob):
```bash
cargo run -p quicnprotochat-client -- join \
cargo run -p quicproquo-client -- join \
--state bob.bin \
--server 127.0.0.1:7000
```
@@ -195,7 +195,7 @@ Bob is now a member of the group at epoch 1, sharing the same group secret as Al
In **Terminal 2** (Alice):
```bash
cargo run -p quicnprotochat-client -- send \
cargo run -p quicproquo-client -- send \
--state alice.bin \
--peer-key <BOB_KEY> \
--msg "Hello Bob, this is encrypted with MLS!" \
@@ -215,7 +215,7 @@ message sent
In **Terminal 3** (Bob):
```bash
cargo run -p quicnprotochat-client -- recv \
cargo run -p quicproquo-client -- recv \
--state bob.bin \
--server 127.0.0.1:7000
```
@@ -233,7 +233,7 @@ This command:
In **Terminal 3** (Bob):
```bash
cargo run -p quicnprotochat-client -- send \
cargo run -p quicproquo-client -- send \
--state bob.bin \
--peer-key <ALICE_KEY> \
--msg "Hi Alice, received loud and clear!" \
@@ -249,7 +249,7 @@ message sent
In **Terminal 2** (Alice):
```bash
cargo run -p quicnprotochat-client -- recv \
cargo run -p quicproquo-client -- recv \
--state alice.bin \
--server 127.0.0.1:7000
```
@@ -266,7 +266,7 @@ If you want to see the entire flow in a single command without managing three te
```bash
# Ensure the server is running, then:
cargo run -p quicnprotochat-client -- demo-group --server 127.0.0.1:7000
cargo run -p quicproquo-client -- demo-group --server 127.0.0.1:7000
```
```

View File

@@ -1,6 +1,6 @@
# Docker Deployment
quicnprotochat includes a multi-stage Dockerfile and a Docker Compose configuration for building and running the server in containers.
quicproquo includes a multi-stage Dockerfile and a Docker Compose configuration for building and running the server in containers.
---
@@ -40,7 +40,7 @@ services:
- "7000:7000"
environment:
RUST_LOG: "info"
QUICNPROTOCHAT_LISTEN: "0.0.0.0:7000"
QPQ_LISTEN: "0.0.0.0:7000"
healthcheck:
test: ["CMD", "bash", "-c", "echo '' > /dev/tcp/localhost/7000"]
interval: 5s
@@ -81,9 +81,9 @@ RUN apt-get update \
Key steps:
1. **Base image**: `rust:bookworm` (Debian Bookworm with the Rust toolchain pre-installed).
2. **Install `capnproto`**: Required by `quicnprotochat-proto/build.rs` to compile `.capnp` schemas at build time.
2. **Install `capnproto`**: Required by `quicproquo-proto/build.rs` to compile `.capnp` schemas at build time.
3. **Copy manifests first**: `Cargo.toml` and `Cargo.lock` are copied before source code. Dummy `main.rs` / `lib.rs` stubs are created so that `cargo build` can resolve and cache the dependency graph. This ensures that dependency compilation is cached in a separate Docker layer -- subsequent builds that only change source code skip the dependency compilation step entirely.
4. **Copy schemas**: The `schemas/` directory is copied before the dependency build because `quicnprotochat-proto/build.rs` requires the `.capnp` files during compilation.
4. **Copy schemas**: The `schemas/` directory is copied before the dependency build because `quicproquo-proto/build.rs` requires the `.capnp` files during compilation.
5. **Copy real source and build**: After the dependency cache layer, real source files are copied in and `cargo build --release` is run.
### Stage 2: Runtime (`debian:bookworm-slim`)
@@ -95,16 +95,16 @@ RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /build/target/release/quicnprotochat-server /usr/local/bin/quicnprotochat-server
COPY --from=builder /build/target/release/qpq-server /usr/local/bin/qpq-server
EXPOSE 7000
ENV RUST_LOG=info \
QUICNPROTOCHAT_LISTEN=0.0.0.0:7000
QPQ_LISTEN=0.0.0.0:7000
USER nobody
CMD ["quicnprotochat-server"]
CMD ["qpq-server"]
```
Key characteristics:
@@ -112,9 +112,9 @@ Key characteristics:
- **Minimal image**: No Rust toolchain, no `capnp` compiler, no build artifacts.
- **`ca-certificates`**: Included for future HTTPS calls (e.g., ACME certificate provisioning or key sync endpoints).
- **Non-root execution**: The container runs as `nobody` for defense in depth.
- **Default port**: The Dockerfile defaults to port `7000` via `QUICNPROTOCHAT_LISTEN`, but the `docker-compose.yml` overrides this to `7000` for consistency with the development workflow.
- **Default port**: The Dockerfile defaults to port `7000` via `QPQ_LISTEN`, but the `docker-compose.yml` overrides this to `7000` for consistency with the development workflow.
> **Note**: The `EXPOSE 7000` directive in the Dockerfile and the `QUICNPROTOCHAT_LISTEN=0.0.0.0:7000` override in `docker-compose.yml` mean the effective listen port is `7000` when using Compose. If you run the Docker image directly without Compose, the server will listen on `7000` by default.
> **Note**: The `EXPOSE 7000` directive in the Dockerfile and the `QPQ_LISTEN=0.0.0.0:7000` override in `docker-compose.yml` mean the effective listen port is `7000` when using Compose. If you run the Docker image directly without Compose, the server will listen on `7000` by default.
---
@@ -129,7 +129,7 @@ services:
volumes:
- server-data:/data
environment:
QUICNPROTOCHAT_DATA_DIR: "/data"
QPQ_DATA_DIR: "/data"
volumes:
server-data:
@@ -140,7 +140,7 @@ Or use a bind mount for easier inspection:
```bash
docker compose run \
-v $(pwd)/server-data:/data \
-e QUICNPROTOCHAT_DATA_DIR=/data \
-e QPQ_DATA_DIR=/data \
server
```
@@ -153,18 +153,18 @@ Without a volume, all server state (including TLS certificates and message queue
To build the Docker image without starting a container:
```bash
docker build -t quicnprotochat-server -f docker/Dockerfile .
docker build -t qpq-server -f docker/Dockerfile .
```
To run it manually:
```bash
docker run -d \
--name quicnprotochat \
--name quicproquo \
-p 7000:7000/udp \
-e QUICNPROTOCHAT_LISTEN=0.0.0.0:7000 \
-e QPQ_LISTEN=0.0.0.0:7000 \
-e RUST_LOG=info \
quicnprotochat-server
qpq-server
```
Note the `/udp` suffix on the port mapping -- QUIC runs over UDP.
@@ -180,7 +180,7 @@ When the server runs in Docker with `docker compose up`, the client can connect
docker compose cp server:/data/server-cert.der ./data/server-cert.der
# Connect
cargo run -p quicnprotochat-client -- ping \
cargo run -p quicproquo-client -- ping \
--ca-cert ./data/server-cert.der \
--server-name localhost
```

View File

@@ -1,6 +1,6 @@
# Prerequisites
Before building quicnprotochat you need a Rust toolchain and the Cap'n Proto schema compiler. Docker is optional but useful for reproducible builds and deployment.
Before building quicproquo you need a Rust toolchain and the Cap'n Proto schema compiler. Docker is optional but useful for reproducible builds and deployment.
---
@@ -8,7 +8,7 @@ Before building quicnprotochat you need a Rust toolchain and the Cap'n Proto sch
**Minimum supported Rust version: 1.77+ (stable)**
quicnprotochat uses the 2021 edition and workspace resolver v2. Any stable Rust release from 1.77 onward should work. Install or update via [rustup](https://rustup.rs/):
quicproquo uses the 2021 edition and workspace resolver v2. Any stable Rust release from 1.77 onward should work. Install or update via [rustup](https://rustup.rs/):
```bash
# Install rustup (if not already present)
@@ -29,7 +29,7 @@ The workspace depends on several crates that use procedural macros (`serde_deriv
## Cap'n Proto compiler (`capnp`)
The `quicnprotochat-proto` crate runs a `build.rs` script that invokes the `capnp` binary at compile time to generate Rust types from the `.capnp` schema files in `schemas/`. The `capnp` binary must be on your `PATH`.
The `quicproquo-proto` crate runs a `build.rs` script that invokes the `capnp` binary at compile time to generate Rust types from the `.capnp` schema files in `schemas/`. The `capnp` binary must be on your `PATH`.
### Debian / Ubuntu
@@ -74,7 +74,7 @@ See [Building from Source -- Troubleshooting](building.md#troubleshooting) for m
## Optional: Docker and Docker Compose
If you prefer to build and run quicnprotochat in containers, you will need:
If you prefer to build and run quicproquo in containers, you will need:
- **Docker Engine** 20.10+ (or Docker Desktop)
- **Docker Compose** v2+ (the `docker compose` plugin, not the legacy `docker-compose` binary)

View File

@@ -1,6 +1,6 @@
# Running the Client
The quicnprotochat CLI client provides subcommands for connectivity testing, identity registration, KeyPackage exchange, and persistent group messaging. All commands connect to the server over QUIC + TLS 1.3 and issue Cap'n Proto RPC calls against the `NodeService` endpoint.
The quicproquo CLI client provides subcommands for connectivity testing, identity registration, KeyPackage exchange, and persistent group messaging. All commands connect to the server over QUIC + TLS 1.3 and issue Cap'n Proto RPC calls against the `NodeService` endpoint.
---
@@ -10,8 +10,8 @@ These flags apply to every subcommand:
| Flag | Env var | Default | Purpose |
|---|---|---|---|
| `--ca-cert` | `QUICNPROTOCHAT_CA_CERT` | `data/server-cert.der` | Path to the server's TLS certificate (DER format). The client uses this to verify the server's identity during the TLS handshake. |
| `--server-name` | `QUICNPROTOCHAT_SERVER_NAME` | `localhost` | Expected TLS server name. Must match a SAN in the server's certificate. |
| `--ca-cert` | `QPQ_CA_CERT` | `data/server-cert.der` | Path to the server's TLS certificate (DER format). The client uses this to verify the server's identity during the TLS handshake. |
| `--server-name` | `QPQ_SERVER_NAME` | `localhost` | Expected TLS server name. Must match a SAN in the server's certificate. |
Most subcommands also accept `--server` (default `127.0.0.1:7000`) to specify the server address.
@@ -24,11 +24,11 @@ Most subcommands also accept `--server` (default `127.0.0.1:7000`) to specify th
Send a health probe to the server and print the round-trip time.
```bash
cargo run -p quicnprotochat-client -- ping
cargo run -p quicproquo-client -- ping
```
```bash
cargo run -p quicnprotochat-client -- ping --server 192.168.1.10:7000
cargo run -p quicproquo-client -- ping --server 192.168.1.10:7000
```
**Output:**
@@ -49,7 +49,7 @@ These commands generate a fresh identity keypair in memory each time they run. T
Generate a fresh Ed25519 identity, create an MLS KeyPackage, and upload it to the Authentication Service.
```bash
cargo run -p quicnprotochat-client -- register
cargo run -p quicproquo-client -- register
```
**Output:**
@@ -66,7 +66,7 @@ Share the `identity_key` value with peers who want to add you to a group. They w
Fetch a peer's KeyPackage from the Authentication Service by their Ed25519 public key.
```bash
cargo run -p quicnprotochat-client -- fetch-key a1b2c3d4e5f6...
cargo run -p quicproquo-client -- fetch-key a1b2c3d4e5f6...
```
The `identity_key` argument must be exactly 64 lowercase hex characters (32 bytes).
@@ -90,7 +90,7 @@ KeyPackages are single-use: fetching a KeyPackage atomically removes it from the
Run a complete Alice-and-Bob MLS round-trip against a live server. Both identities are created in-process; both communicate through the server's AS and DS.
```bash
cargo run -p quicnprotochat-client -- demo-group --server 127.0.0.1:7000
cargo run -p quicproquo-client -- demo-group --server 127.0.0.1:7000
```
**Output:**
@@ -106,21 +106,21 @@ This is the fastest way to verify that the entire stack (QUIC + TLS + Cap'n Prot
## Persistent group commands
These commands use a state file (`--state`, default `quicnprotochat-state.bin`) to persist the Ed25519 identity seed and MLS group state between invocations. A companion key store file (same path with `.ks` extension) holds HPKE init private keys.
These commands use a state file (`--state`, default `qpq-state.bin`) to persist the Ed25519 identity seed and MLS group state between invocations. A companion key store file (same path with `.ks` extension) holds HPKE init private keys.
All persistent commands share the `--state` flag:
| Flag | Env var | Default |
|---|---|---|
| `--state` | `QUICNPROTOCHAT_STATE` | `quicnprotochat-state.bin` |
| `--server` | `QUICNPROTOCHAT_SERVER` | `127.0.0.1:7000` |
| `--state` | `QPQ_STATE` | `qpq-state.bin` |
| `--server` | `QPQ_SERVER` | `127.0.0.1:7000` |
### `register-state`
Create or load a persistent identity, generate a KeyPackage, and upload it to the AS.
```bash
cargo run -p quicnprotochat-client -- register-state \
cargo run -p quicproquo-client -- register-state \
--state alice.bin \
--server 127.0.0.1:7000
```
@@ -141,10 +141,10 @@ Refresh the KeyPackage on the server using your **existing** state file. Does no
- Your KeyPackage has expired (server TTL, e.g. 24h).
- Your KeyPackage was consumed (someone invited you) and you want to be invitable again.
Run with the same `--access-token` (or `QUICNPROTOCHAT_ACCESS_TOKEN`) as for other commands.
Run with the same `--access-token` (or `QPQ_ACCESS_TOKEN`) as for other commands.
```bash
cargo run -p quicnprotochat-client -- refresh-keypackage \
cargo run -p quicproquo-client -- refresh-keypackage \
--state alice.bin \
--server 127.0.0.1:7000
```
@@ -163,7 +163,7 @@ If you are told "no key" when someone tries to invite you, have them wait and ru
Create a new MLS group. The caller becomes the sole member at epoch 0.
```bash
cargo run -p quicnprotochat-client -- create-group \
cargo run -p quicproquo-client -- create-group \
--state alice.bin \
--group-id "project-chat"
```
@@ -180,7 +180,7 @@ The group state is saved to the state file. You can now invite peers with `invit
Fetch a peer's KeyPackage from the AS, add them to the group, and deliver the Welcome message via the DS.
```bash
cargo run -p quicnprotochat-client -- invite \
cargo run -p quicproquo-client -- invite \
--state alice.bin \
--peer-key b9a8c7d6e5f4... \
--server 127.0.0.1:7000
@@ -202,7 +202,7 @@ invited peer (welcome queued)
Join a group by consuming a Welcome message from the DS.
```bash
cargo run -p quicnprotochat-client -- join \
cargo run -p quicproquo-client -- join \
--state bob.bin \
--server 127.0.0.1:7000
```
@@ -219,7 +219,7 @@ joined group successfully
Encrypt and send an application message to a peer via the DS.
```bash
cargo run -p quicnprotochat-client -- send \
cargo run -p quicproquo-client -- send \
--state alice.bin \
--peer-key b9a8c7d6e5f4... \
--msg "hello from alice" \
@@ -238,7 +238,7 @@ message sent
Receive and decrypt all pending messages from the DS.
```bash
cargo run -p quicnprotochat-client -- recv \
cargo run -p quicproquo-client -- recv \
--state bob.bin \
--server 127.0.0.1:7000
```
@@ -257,12 +257,12 @@ Additional flags:
```bash
# Wait up to 5 seconds for messages
cargo run -p quicnprotochat-client -- recv \
cargo run -p quicproquo-client -- recv \
--state bob.bin \
--wait-ms 5000
# Stream messages continuously
cargo run -p quicnprotochat-client -- recv \
cargo run -p quicproquo-client -- recv \
--state bob.bin \
--stream --wait-ms 10000
```
@@ -271,7 +271,7 @@ cargo run -p quicnprotochat-client -- recv \
## HPKE init key lifecycle warning
The MLS protocol requires that the HPKE init private key generated during KeyPackage creation is available when processing the corresponding Welcome message. In quicnprotochat, this private key is stored in the key store file (`.ks` extension alongside the state file).
The MLS protocol requires that the HPKE init private key generated during KeyPackage creation is available when processing the corresponding Welcome message. In quicproquo, this private key is stored in the key store file (`.ks` extension alongside the state file).
**The same state file and key store must be used for both `register-state` and `join`.** If you:

View File

@@ -1,13 +1,13 @@
# Running the Server
The quicnprotochat server is a single binary (`quicnprotochat-server`) that exposes a unified **NodeService** endpoint combining Authentication Service (KeyPackage management) and Delivery Service (message relay) operations over a single QUIC + TLS 1.3 connection.
The quicproquo server is a single binary (`qpq-server`) that exposes a unified **NodeService** endpoint combining Authentication Service (KeyPackage management) and Delivery Service (message relay) operations over a single QUIC + TLS 1.3 connection.
---
## Quick start
```bash
cargo run -p quicnprotochat-server
cargo run -p quicproquo-server
```
On first launch the server will:
@@ -20,8 +20,8 @@ On first launch the server will:
You should see output similar to:
```
2025-01-01T00:00:00.000000Z INFO quicnprotochat_server: generated self-signed TLS certificate cert="data/server-cert.der" key="data/server-key.der"
2025-01-01T00:00:00.000000Z INFO quicnprotochat_server: accepting QUIC connections addr="0.0.0.0:7000"
2025-01-01T00:00:00.000000Z INFO quicproquo_server: generated self-signed TLS certificate cert="data/server-cert.der" key="data/server-key.der"
2025-01-01T00:00:00.000000Z INFO quicproquo_server: accepting QUIC connections addr="0.0.0.0:7000"
```
---
@@ -32,36 +32,36 @@ All configuration is available via CLI flags and environment variables. Environm
| Purpose | CLI flag | Env var | Default |
|---|---|---|---|
| QUIC listen address | `--listen` | `QUICNPROTOCHAT_LISTEN` | `0.0.0.0:7000` |
| TLS certificate (DER) | `--tls-cert` | `QUICNPROTOCHAT_TLS_CERT` | `data/server-cert.der` |
| TLS private key (DER) | `--tls-key` | `QUICNPROTOCHAT_TLS_KEY` | `data/server-key.der` |
| Data directory | `--data-dir` | `QUICNPROTOCHAT_DATA_DIR` | `data` |
| QUIC listen address | `--listen` | `QPQ_LISTEN` | `0.0.0.0:7000` |
| TLS certificate (DER) | `--tls-cert` | `QPQ_TLS_CERT` | `data/server-cert.der` |
| TLS private key (DER) | `--tls-key` | `QPQ_TLS_KEY` | `data/server-key.der` |
| Data directory | `--data-dir` | `QPQ_DATA_DIR` | `data` |
| Log level | -- | `RUST_LOG` | `info` |
### Examples
```bash
# Listen on a custom port
cargo run -p quicnprotochat-server -- --listen 0.0.0.0:9000
cargo run -p quicproquo-server -- --listen 0.0.0.0:9000
# Use pre-existing TLS credentials
cargo run -p quicnprotochat-server -- \
--tls-cert /etc/quicnprotochat/cert.der \
--tls-key /etc/quicnprotochat/key.der
cargo run -p quicproquo-server -- \
--tls-cert /etc/quicproquo/cert.der \
--tls-key /etc/quicproquo/key.der
# Via environment variables
QUICNPROTOCHAT_LISTEN=0.0.0.0:9000 \
QPQ_LISTEN=0.0.0.0:9000 \
RUST_LOG=debug \
cargo run -p quicnprotochat-server
cargo run -p quicproquo-server
```
### Production deployment
Set `QUICNPROTOCHAT_PRODUCTION=1` (or `true` / `yes`) so the server enforces production checks:
Set `QPQ_PRODUCTION=1` (or `true` / `yes`) so the server enforces production checks:
- **Auth:** A non-empty `QUICNPROTOCHAT_AUTH_TOKEN` is required; the value `devtoken` is rejected.
- **Auth:** A non-empty `QPQ_AUTH_TOKEN` is required; the value `devtoken` is rejected.
- **TLS:** Existing cert and key files are required (auto-generation is disabled).
- **SQL store:** When `--store-backend=sql`, a non-empty `QUICNPROTOCHAT_DB_KEY` is required. An empty key leaves the database unencrypted on disk and is not acceptable for production.
- **SQL store:** When `--store-backend=sql`, a non-empty `QPQ_DB_KEY` is required. An empty key leaves the database unencrypted on disk and is not acceptable for production.
---
@@ -88,7 +88,7 @@ To use a certificate issued by a CA or a custom self-signed certificate:
```
2. Point the server at them:
```bash
cargo run -p quicnprotochat-server -- \
cargo run -p quicproquo-server -- \
--tls-cert cert.der \
--tls-key key.der
```
@@ -128,7 +128,7 @@ The server persists its state to the data directory (`--data-dir`, default `data
| `data/deliveries.bin` | `bincode`-serialised map of `(channelId, recipientKey)` to message queues |
| `data/hybridkeys.bin` | `bincode`-serialised map of identity keys to hybrid (X25519 + ML-KEM-768) public keys |
Storage is implemented by the `FileBackedStore` in `crates/quicnprotochat-server/src/storage.rs`. Every mutation (upload, enqueue, fetch) flushes the entire map to disk synchronously. This is suitable for proof-of-concept workloads but not production traffic. See [Storage Backend](../internals/storage-backend.md) for details.
Storage is implemented by the `FileBackedStore` in `crates/quicproquo-server/src/storage.rs`. Every mutation (upload, enqueue, fetch) flushes the entire map to disk synchronously. This is suitable for proof-of-concept workloads but not production traffic. See [Storage Backend](../internals/storage-backend.md) for details.
---
@@ -153,16 +153,16 @@ The server uses `tracing` with `tracing-subscriber` and respects the `RUST_LOG`
```bash
# Default: info level
RUST_LOG=info cargo run -p quicnprotochat-server
RUST_LOG=info cargo run -p quicproquo-server
# Debug level for detailed RPC tracing
RUST_LOG=debug cargo run -p quicnprotochat-server
RUST_LOG=debug cargo run -p quicproquo-server
# Trace level for maximum verbosity
RUST_LOG=trace cargo run -p quicnprotochat-server
RUST_LOG=trace cargo run -p quicproquo-server
# Filter to specific crates
RUST_LOG=quicnprotochat_server=debug,quinn=warn cargo run -p quicnprotochat-server
RUST_LOG=quicproquo_server=debug,quinn=warn cargo run -p quicproquo-server
```
---