Files
Bundle OKF 0.1 · 8 conceitos · iamdoubz/gmmff
Open source Repository Open in the app JSON README (API)
About
# Files
- [gmmff Wiki Quickstart](quickstart.md) - Entry point for the gmmff peer-to-peer file transfer system wiki. Provides high-level overview and navigation to key sections.
- [Source Map](source-map.md) - Mapping of wiki topics to source code locations for easy navigation.
# Directories
- [architecture](architecture/)
- [domain-concepts](domain-concepts/)
- [integrations](integrations/)
- [operations](operations/)
- [testing](testing/)
- [workflows](workflows/)
Details
- Kind
- OKF bundles
- Topic
- Developer tools
- Publisher
- iamdoubz
- Origin
- okf_github
- Category
- dados
- Version
- 0.1
- Stars
- 1
- Last push
- 2026-09-06T13:07:13Z
- Repository state
- ativo
- Language
- Go
- License
- MIT
- Added
- 2026-09-08 09:04:14
- Updated
- 2026-09-08 09:04:14
- Origin id
iamdoubz/gmmff:openwiki/index.md
README
<p align="center">
<img src="imgs/gmmff-social.png" alt="A view from space of a giant worm hole sucking in your favorite file types... oh the horror!">
</p>
# gmmff — peer-to-peer file transfer
[](https://github.com/iamdoubz/gmmff/releases/latest)
[](https://github.com/iamdoubz/gmmff/actions/workflows/docker.yml)
[](https://github.com/iamdoubz/gmmff/issues)
[](https://github.com/iamdoubz/gmmff/pulls?q=is%3Apr+is%3Aclosed)
[](LICENSE)
[](https://goreportcard.com/report/github.com/iamdoubz/gmmff/v2)
> **gmmff** (pronounced *gimph*) is a brutally simple, cryptographically sound
> peer-to-peer file and message transfer system.
gmmff consists of two parts: a **signaling server** that brokers the initial
connection, and a **CLI client** that handles the actual transfer. The server
never sees file contents — once two (or more) peers are connected, all data flows
directly between them over an encrypted WebRTC data channel.
---
## Application overview
### Installing
Please use the [guide here](docs/INSTALL.md) for installing `gmmff`.
### Building
Please use the [guide here](docs/BUILD.md) for building `gmmff`.
### CLI
[CLI documentation](docs/CLI.md)
### WASM Webclient
[WASM documentation](docs/WASM.md)
### Schedule — encrypted server-side transfers
[Schedule documentation](docs/SCHEDULE.md)
#### Limitations
The crypto api is only available in secure contexts: https and localhost. If
you attempt to use schedule using http, it will not work!
### Local-network mode (no internet required)
[Local mode documentation](docs/LOCAL.md)
---
## Commands
See the [Commands documentation](docs/CMDS.md)
---
## Environment variables
See the [Commands documentation](docs/CMDS.md) and the [env example](configs/.env.example)
---
## STUN/TURN configuration
See the [STUN/TURN documentation](docs/TURN.md)
---
## Quick Start
### Option A — Docker Compose
```bash
git clone https://github.com/iamdoubz/gmmff
cd gmmff
cp configs/.env.example configs/.env
docker compose up -d
# Server available at ws://localhost:8080/ws
```
### Option B — Local Go + Redis or Valkey
Prerequisites: **Go 1.23+**, and **Redis 7+** *or* **Valkey 7.2+** (wire-compatible
drop-in — the same client talks to either; use a `valkey://` URL if you prefer).
```bash
# Start Redis (or: valkey-server)
redis-server
# Run with in-memory store (no Redis/Valkey needed for dev)
go run ./cmd/gmmff serve --memory --log-pretty --log-level debug
# Or with Redis/Valkey (set GMMFF_REDIS_URL; valkey:// is accepted)
go run ./cmd/gmmff serve --log-pretty --log-level debug
```
### Verify
```bash
curl http://localhost:8080/healthz # → ok
curl http://localhost:8080/readyz # → ok (or 503 if Redis is down)
curl http://localhost:8080/metrics # → JSON counters
```
---
## Server configuration
*Most* flags have environment variable equivalents with the `GMMFF_` prefix.
Copy `configs/.env.example` to `.env` and adjust.
See [ENV.md](docs/ENV.md) and the [example env file](configs/.env.example) for more information.
---
## Deployment
For production deployments, see the dedicated guides in the `docs/` directory:
- **[docs/SYSTEMD.md](docs/SYSTEMD.md)** — Creating a dedicated system user, installing the binary and service file, managing configuration without editing the service file, and Redis Unix socket access.
- **[docs/NGINX.md](docs/NGINX.md)** — Configuring nginx as a reverse proxy with TLS termination, WebSocket upgrade headers, timeout tuning, and endpoint access control.
---
## Security model
See [Security Documentation](docs/SECURITY.md) for more information.
---
## Wire protocol
See [Protocol Documentation](docs/PROTOCOL.md) for more information.
---
## Privacy & logging
Logs contain **only**:
- Timestamp
- Component name (`broker`, `store`, `main`)
- Slot UUID (opaque — means nothing to outsiders)
- Error code (e.g. `ERR_REDIS_UNAVAILABLE`)
- HTTP method + path + status code
Logs **never** contain: file names, file sizes, IP addresses, user agents,
slot codes, or any data that could identify a transfer or a user.
---
## Architecture overview
```
Peer A ──┐ ┌── Peer B
│ wss://host/ws │
└──── Signaling server ────┘
│
Redis (slot state)
```
1. Peer A runs `gmmff create` and receives a one-time 3-word code
2. Peer A shares that code out-of-band with Peer B
3. Peer B runs `gmmff join <code>` on any machine, anywhere
4. CPace PAKE authenticates both sides — the signaling server stays blind
5. The SDP offer/answer is HMAC-signed with the PAKE shared key, preventing man-in-the-middle substitution
6. A direct WebRTC/DTLS control channel opens; the signaling server's job is done
7. Both peers enter the session REPL and can freely exchange files and messages
| Phase | What the server does |
|-------|----------------------|
| `slot.create` | Generates a UUID + 3-word code, persists in Redis with 10-min TTL |
| `slot.join` | Resolves code → slot, links the responder, sends `slot.ready` to both |
| Relay | Forwards `pake.*`, `sdp.*`, `ice.*` frames opaquely to the other peer |
| `bye` / expire | Deletes both Redis keys; notifies peer |
The server **cannot** intercept the session. PAKE authentication happens
entirely between the two clients, and the DTLS session key is bound to the
PAKE shared secret via HMAC — so a compromised signaling server cannot
substitute its own SDP fingerprints.
If you want to learn more, see the dedicated [Architecture document](docs/ARCHITECTURE.md).
---
## Project structure
```
gmmff/
├── cmd/gmmff/ # Binary entrypoint (Cobra CLI)
│ ├── main.go # Root command + serve subcommand + shared helpers
│ ├── create.go # gmmff create — starts file+message session, session REPL
│ ├── chat.go # gmmff chat — pure chat; gmmff join — joins any session
│ ├── local.go # gmmff local — self-contained local-network mode
│ └── cleanup.go # gmmff cleanup — remove expired schedule uploads (cron-friendly)
├── internal/
│ ├── broker/ # WebSocket hub, message router, HTTP server, UI config
│ │ ├── broker.go
│ │ ├── server.go
│ │ └── uiconfig.go # Feature flags served via /config.json
│ ├── schedule/ # Server-side encrypted file storage (Schedule feature)
│ │ ├── config.go # Env parsing, TTL options, IP allowlists
│ │ ├── store.go # Pending/complete file lifecycle, chunk storage
│ │ ├── handler.go # HTTP handlers: /api/schedule/*
│ │ └── cleanup.go # Crontab parser, background cleanup goroutine
│ ├── store/ # Redis + in-memory slot persistence
│ │ └── store.go
│ ├── slot/ # Slot domain model & state machine
│ │ └── slot.go
│ ├── crypto/ # Slot code generation (3-word passphrase)
│ │ └── codegen.go
│ ├── log/ # Privacy-safe structured logger
│ │ └── log.go
│ ├── archive/ # On-the-fly zip for multi-file transfers
│ │ └── archive.go
│ ├── peer/ # WebRTC + PAKE orchestration; StartSession/JoinSession
│ │ └── peer.go
│ ├── peerconfig/ # Shared Config type (avoids peer↔session import cycle)
│ │ └── peerconfig.go
│ ├── session/ # Bidirectional session coordinator
│ │ └── session.go
│ ├── signaling/ # WebSocket signaling client
│ │ ├── client_native.go
│ │ ├── client_js.go
│ │ └── b64.go
│ ├── transfer/ # Binary chunk protocol (send + receive state machines)
│ │ └── transfer.go
│ ├── localmode/ # Self-contained local-network mode
│ │ ├── embed.go
│ │ ├── tls.go
│ │ ├── mdns.go
│ │ └── local.go
│ └── turn/ # TURN URL parsing and ephemeral credential derivation
│ └── turn.go
├── pkg/protocol/ # Wire message types (shared server/client)
│ └── protocol.go
├── web/ # Browser UI (Wasm + plain JS)
│ ├── cmd/gmmff-wasm/ # Go→Wasm entry point (syscall/js bridge)
│ │ └── main.go
│ └── static/ # Served files
│ ├── index.html # Single-page UI (Files + Chat + Schedule tabs)
│ ├── css/
│ │ └── app.css
│ ├── js/
│ │ └── app.js # UI logic + Schedule IIFE module (AES-GCM crypto)
│ ├── themes/
│ │ └── default.json
│ └── i18n/
│ ├── languages.json
│ ├── en.json
│ └── ... # 32 languages total
├── configs/
│ ├── .env.example # All environment variable reference
│ ├── gmmff.conf # nginx reverse proxy configuration
│ └── gmmff.service # systemd service unit
├── docs/
│ ├── ARCHITECTURE.md
│ ├── BUILD.md
│ ├── CLI.md
│ ├── CMDS.md
│ ├── INSTALL.md
│ ├── LOCAL.md
│ ├── NGINX.md
│ ├── PROTOCOL.md
│ ├── SCHEDULE.md
│ ├── SECURITY.md
│ ├── SYSTEMD.md
│ ├── TURN.md
│ └── WASM.md
├── Dockerfile
├── docker-compose.yml
├── go.mod
├── go.sum
└── README.md
```
---
## Features
### Current
- **Local-network mode** — `gmmff local` is a fully self-contained mode with embedded server, auto TLS, mDNS discovery, and QR code; no internet or external server required
- **Multi-peer sessions** — `gmmff create --max-peers N` allows 2–10 participants; 2-peer sessions are bidirectional, 3–10 peer sessions broadcast from the initiator to all
- **Display names** — initiator and joiners can set a name; names are announced to all peers on connect and shown as message labels throughout the session
- **Signaling server** — Go, Redis-backed, privacy-safe structured logs, Docker-ready
- **CPace PAKE** — zero-knowledge authentication; server stays blind to the shared secret
- **SDP MAC binding** — HMAC-signed SDP with HKDF-derived subkeys; prevents MITM via signaling relay
- **DTLS 1.3** — all data channel traffic encrypted end-to-end via Pion WebRTC
- **Multi-file and directory transfers** — multiple files and directories zipped on the fly
- **Transfer queue** — multiple transfers serialized automatically; each gets its own progress bar
- **Resumable transfers** — partial + meta sidecar files; progress bars pick up at the correct offset
- **Clean cancellation** — `Ctrl+C` or `\q` delivers clean messages to all peers; partial file preserved
- **SHA-256 integrity** — full-file hash verified before `TransferOK` is sent
- **Secure chat** — pure text chat (`gmmff chat`) or inline messaging within a file session
- **Sliding window** — configurable in-flight chunks (`--window`); default 2
- **Configurable chunk size** — up to SCTP maximum 65526 bytes (`--chunk-size`)
- **STUN multi-server** — append additional STUN servers via `--stun` (repeatable) or `GMMFF_STUN`
- **TURN support** — long-term and ephemeral credentials, mixed auth types, transport hints, max 3 servers
- **Browser UI (Wasm)** — same Go source compiled to WebAssembly; Files, Chat, and Schedule tabs
- **Schedule tab** — browser-side AES-256-GCM encrypted uploads; server never sees plaintext; TTL, download limits, IP/password access control, QR codes, auto-download links, cleanup service
- **Schedule CLI** — `gmmff schedule upload/download/delete` for terminal-based encrypted transfers; full browser↔CLI interoperability
- **Drag and drop** — drop files anywhere on the browser UI to queue them for sending
- **32 languages** — English, Spanish, French, German, Italian, Swedish, Portuguese (BR/EU), Arabic, Bengali, Persian, Finnish, Hindi, Indonesian, Japanese, Korean, Marathi, Malay, Dutch, Norwegian, Polish, Russian, Thai, Filipino, Turkish, Ukrainian, Urdu, Vietnamese, Chinese (Simplified/Traditional), Tamil, Sinhala; language picker with 7-day persistence
- **ICE settings panel** — configurable STUN/TURN in the browser UI, persisted 7 days
- **Share links + QR codes** — shareable URLs and scannable QR codes on all code screens
- **UI feature flags** — 15 server-side feature flags served via `/config.json` control tab visibility, ICE settings, share links, QR codes, server field, peers slider, MOTD, and allowed languages
### Backlog
- **Browser extension** — use your favorite browser to send/receive files
- **More languages** — 32 languages shipped; contributions welcome
- **Trusted local CA** — one-time CA install for iOS Safari support in `gmmff local`
- **Quantum-safe encryption** — post-quantum algorithms with elliptic-curve fallback
### Probably won't do
- wasm webclient: window slider (defaults to 2, 1–16 range)
- **Password-protected zips** — optional encryption on the zip archive
---
## Inspiration
<p align="center">
<a href="https://xkcd.com/949" target="_blank"><img src="https://imgs.xkcd.com/comics/file_transfer.png" alt="xkcd comic explaining the difficulties of sending large files between two people"></a>
</p>
- [X] [webwormhole](https://github.com/saljam/webwormhole) by [@saljam](https://github.com/saljam)
- [X] [FilePizza](https://github.com/kern/filepizza) by [@kern](https://github.com/kern) and [@neerajbaid](https://github.com/neerajbaid)
- [X] [Firefox Send](https://gitlab.com/timvisee/send) by [@mozilla](https://github.com/mozilla/) new fork by [@timvisee](https://github.com/timvisee)
- [X] [Jirafeau](https://gitlab.com/jirafeau/Jirafeau) by [Jerome Jutteau](https://gitlab.com/mojo42) and many [others](https://gitlab.com/jirafeau/Jirafeau/-/blob/master/AUTHORS.md?ref_type=heads)...
---
## License
MIT — see [LICENSE](LICENSE). All dependencies are MIT or Apache-2.0.