Main README covers quick start, API overview, and links to example READMEs. Each example (paste, filemanager, can-sync, canfs) gets its own README with setup instructions, architecture, and configuration details. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CAN Sync
P2P full-mirror replication for CAN Service. Two machines with the same passphrase automatically discover each other and sync all assets over encrypted connections. No port forwarding or static IPs needed.
┌─────────────┐ protobuf ┌─────────────┐ iroh (QUIC) ┌─────────────┐ protobuf ┌─────────────┐
│ CAN Service │◄───────────►│ CAN Sync │◄─────────────►│ CAN Sync │◄───────────►│ CAN Service │
│ Machine A │ sync API │ Agent A │ encrypted │ Agent B │ sync API │ Machine B │
│ port 3210 │ │ │ │ │ │ port 3210 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Quick Start
-
Start CAN Service on each machine (port 3210):
cargo run -
Configure the sync agent -- edit
config.yaml:can_service_url: "http://127.0.0.1:3210" sync_api_key: "can-sync-default-key" sync_passphrase: "my-secret-phrase" # must be the same on all machines poll_interval_secs: 30 -
Start the sync agent on each machine:
cd examples/can-sync cargo run -- config.yaml
That's it. Any file uploaded to either CAN Service will appear on the other within seconds.
How It Works
Peer Discovery
Peers find each other through two mechanisms (both run simultaneously):
- Gossip -- iroh-gossip uses a topic derived from the shared passphrase. Peers on the same local network or connected to the same relay discover each other by broadcasting their node IDs.
- Internet rendezvous -- Each agent publishes its node ID to pkarr relay servers using deterministic DNS-like "slots" derived from the passphrase. All agents scan these slots periodically to find peers worldwide.
Sync Protocol
Once two peers connect over iroh's encrypted QUIC transport:
- Hash exchange -- Both sides send their full list of asset hashes
- Diff -- Each side computes what the other is missing
- Transfer -- Missing assets are sent concurrently in both directions (metadata + file content bundled together as protobuf)
- Live sync -- After the initial reconciliation, each agent subscribes to SSE events from its local CAN Service. When a new asset is ingested locally, it's pushed to the connected peer instantly.
The live sync uses SSE events (not polling) for instant propagation. A fallback incremental poll runs every 30 seconds as a safety net.
Echo Prevention
When peer A sends an asset to peer B, B's CAN Service emits an SSE event for the new ingest. Without protection, B would try to push that asset right back to A. The sync agent tracks which hashes were received from each peer and filters them out of the push loop.
Configuration
| Field | Default | Description |
|---|---|---|
can_service_url |
(required) | URL of the local CAN Service |
sync_api_key |
(required) | Must match sync_api_key in CAN Service's config |
sync_passphrase |
(required) | Shared secret for peer discovery (all peers must match) |
poll_interval_secs |
3 |
Fallback poll interval for catching missed events |
ticket_file |
(none) | Write this node's address to a file (for direct connection in tests) |
connect_ticket_file |
(none) | Read a peer's address from a file (for direct connection in tests) |
CAN Service must have sync_api_key set in its config.yaml for the sync endpoints to be enabled.
Security
- Transport -- All peer traffic is encrypted with QUIC + TLS 1.3 (mandatory in iroh)
- Identity -- Each node gets an Ed25519 keypair on first run
- Discovery -- Only peers with the same passphrase can find each other
- Hash verification -- Every received asset is re-hashed and compared before being stored
Project Structure
src/
main.rs Entry point: config, iroh endpoint, discovery, peer connections
config.rs YAML config loading
can_client.rs HTTP client for CAN Service's sync API (protobuf + SSE)
protocol.rs Protobuf message types (shared with CAN Service)
discovery.rs Peer discovery via iroh-gossip
rendezvous.rs Internet peer discovery via pkarr relay
peer.rs Per-peer sync: reconciliation, live push/receive, echo prevention