Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/openlibrecommunity/olcrtc/llms.txt

Use this file to discover all available pages before exploring further.

For those who prefer a native binary without Podman or containers, olcRTC can be built directly on the host using the standard Go toolchain and mage. This approach gives you full control over the binary, makes it easy to integrate with systemd, and lets you cross-compile for other platforms. You need Go 1.26+, mage, and git.
olcRTC is in Beta. Always verify that the video call service you choose is accessible in your network before relying on it.

SWAP Recommendation

If your machine has less than 4 GB of RAM, the build may crash. Enable a swap file first:
sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile

Build and Run

1

Install git

apt install git
2

Install Go 1.26+

pacman -S go
On Debian/Ubuntu, the system package is typically Go 1.19 — too old. Use APT pinning or the Go SDK path instead:
This is the recommended approach on Debian 13+. It pulls Go from the testing repository without polluting the rest of the system.
echo 'deb http://deb.debian.org/debian/ testing main non-free-firmware' | sudo tee /etc/apt/sources.list.d/testing.list

cat <<EOF | sudo tee /etc/apt/preferences.d/testing-pin
Package: *
Pin: release a=testing
Pin-Priority: 100
EOF

sudo apt update
sudo apt install -t testing golang-go

sudo update-alternatives --install /usr/bin/go go `which go` 10
sudo update-alternatives --install /usr/bin/gofmt gofmt `which gofmt` 10
Verify the installation:
go version
# go version go1.26.x linux/amd64
3

Install mage

mage is the build system used by olcRTC — similar to make but written in Go.
go install github.com/magefile/mage@latest
Add ~/go/bin to your PATH so the shell can find mage:
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Verify:
mage --version
# mage vx.x.x
4

Clone the repository

git clone https://github.com/openlibrecommunity/olcrtc
cd olcrtc
5

Build the binary

Build for the current platform:
mage build
Cross-compile for all supported platforms at once (Linux amd64/arm64, Windows amd64, macOS amd64/arm64, FreeBSD amd64/arm64, OpenBSD amd64/arm64):
mage cross
The resulting binary is placed in build/:
build/olcrtc-linux-amd64
6

Generate the encryption key

Generate a 64-character hex key. This is done once on the server; the same key must be used on both server and client.
openssl rand -hex 32
# d823fa01cb3e0609b67322f7cf984c4ee2e4ce2e294936fc24ef38c9e59f4799
Save this output — you will need it for both config files.
7

Run the server

On the server machine (VPS, remote server, etc.). Create a YAML config file, then run the binary with it.
Recommended: jitsi + datachannel. No registration, stable data path, lowest latency. See docs/examples/jitsi.instances.yaml for a list of public Jitsi instances — verify in your browser that the instance you choose actually loads before using it.
To see every connection in the logs, add debug: true to your YAML:
debug: true
Example debug output:
2026/05/03 08:05:23 Connecting link via direct/vp8channel/wbstream...
2026/05/03 08:05:25 wbstream publisher state: connected
2026/05/03 08:05:27 Link connected
2026/05/03 08:05:43 sid=3 connect icanhazip.com:443
2026/05/03 08:05:43 sid=3 connected icanhazip.com
8

Run the client

On your local machine. auth.provider, net.transport, room.id, and crypto.key must match the server exactly.For Android, owenewans/owenclave reads the olcrtc:// URI directly — no YAML or binary needed on the device.
9

Verify the tunnel

Send a request through the SOCKS5 proxy. The response should show your server’s IP:
curl --socks5-hostname 127.0.0.1:8808 https://icanhazip.com

All Mage Targets

Build

TargetWhat it does
mage buildBuild the olcrtc binary for the current platform → build/olcrtc-<os>-<arch>
mage crossCross-compile for all supported platforms (Linux, Windows, macOS, FreeBSD, OpenBSD; amd64 + arm64)
mage mobileBuild the Android AAR via gomobile → build/olcrtc.aar
mage cleanRemove the build/ directory
mage build    # native binary for this machine
mage cross    # all platforms
mage mobile   # Android AAR (requires gomobile)
mage clean    # wipe build/

Code Quality

TargetWhat it does
mage vetRun go vet on the whole module
mage lintRun golangci-lint ./...
mage tidyRun go mod tidy and go mod verify
mage depsRun go mod download
mage vet
mage lint
mage tidy
mage deps

Tests

TargetWhat it does
mage testUnit tests in -short mode — fast, no network
mage testFullAll unit tests + local e2e with -race; no real providers
mage e2eSmoke matrix against real providers
mage stressStress matrix against real providers (~6 hours)
mage soakReal-provider throughput soak (long)
mage localSoakIn-memory throughput soak — no network required
mage test       # quick units
mage testFull   # full units + fast e2e, race detector
mage e2e        # real-provider smoke
mage stress     # real-provider stress (~6h)
mage soak       # real-provider soak
mage localSoak  # local in-memory soak

Pipelines

TargetWhat it does
mage checkbuild + vet + lint + testFull — run before every commit
mage allcheck + e2e — full pre-merge pipeline
mage nightlyall + stress — nightly CI (~6 hours)
mage everythingnightly + soak + localSoak — full validation (12+ hours)
mage check       # pre-commit
mage all         # pre-merge
mage nightly     # nightly CI (~6h)
mage everything  # maximum confidence (12+ h)

Help

mage help (or mage -l) lists all available targets. Running mage with no arguments also prints the target list — Help is the default target.
mage help   # list all targets
mage -l     # same as mage help
mage        # no arguments — also prints target list

E2E Environment Variables

Fine-tune test runs through environment variables:
VariableApplies toDefaultDescription
E2E_CARRIERSe2e, stressallComma-separated list of carriers to test (e.g. jitsi,wbstream)
E2E_TRANSPORTSe2e, stressallComma-separated list of transports to test
E2E_TIMEOUTe2e30mPer-test timeout
E2E_STRESSe2eSet to any value to enable stress mode inside e2e
E2E_STRESS_DURATIONe2eStress duration when E2E_STRESS is set
STRESS_BULK_DURATIONstress15mDuration of the bulk-transfer phase per case
STRESS_ECHO_DURATIONstress15mDuration of the echo phase per case
STRESS_CASE_TIMEOUTstress35mHard timeout per stress case
STRESS_TIMEOUTstress6hHard timeout for the entire stress run
SOAK_CARRIERSsoaktelemost,jitsi,wbstreamCarriers to soak
SOAK_TRANSPORTSsoakdatachannel,vp8channelTransports to soak (real provider soak)
SOAK_TRANSPORTSlocalSoakallTransports to soak (local in-memory soak)
SOAK_DURATIONsoak, localSoak10m (6m local)How long to soak
SOAK_CHAOSlocalSoakEnable chaos mode in the local soak
Example — run a single targeted stress case:
E2E_CARRIERS=telemost E2E_TRANSPORTS=videochannel \
    STRESS_BULK_DURATION=0 STRESS_ECHO_DURATION=0 \
    STRESS_CASE_TIMEOUT=2m STRESS_TIMEOUT=3m mage stress
Example — soak only jitsi for 30 minutes:
SOAK_CARRIERS=jitsi SOAK_DURATION=30m mage soak

Updating the Binary

A running process does not update itself. To apply new code:

1. Pull the latest source

cd olcrtc
git pull --recurse-submodules
To switch branches first:
git switch dev
git pull --recurse-submodules

2. Rebuild

mage build
# Result: build/olcrtc-linux-amd64
For a different architecture, or to rebuild everything:
mage cross
ls build/

3. Stop the old process

If running in a terminal, press Ctrl+C. If running in the background:
pgrep -af olcrtc   # find the PID
kill <pid>
If using systemd, a service restart is sufficient — no manual kill needed.

4. (Optional) Install to a system path

If you copied the binary outside of build/, update the copy:
sudo install -m 0755 build/olcrtc-linux-amd64 /usr/local/bin/olcrtc

5. Restart with the same config

./build/olcrtc-linux-amd64 server.yaml
./build/olcrtc-linux-amd64 client.yaml
Or via systemd:
sudo systemctl restart olcrtc-server
sudo systemctl restart olcrtc-client
No config changes are needed if auth.provider, net.transport, room.id, crypto.key, and socks.port are unchanged.

Multiple Instances on One Server

Run as many olcRTC server instances as needed — each uses its own YAML file and runs in its own process.
# server-jitsi.yaml
mode: srv
auth:
  provider: jitsi
room:
  id: "https://meet.example.org/room1"
crypto:
  key: "aaaa...1111"
net:
  transport: datachannel
  dns: "8.8.8.8:53"
data: data
# server-wbstream.yaml
mode: srv
auth:
  provider: wbstream
room:
  id: "<room-id>"
crypto:
  key: "bbbb...2222"
net:
  transport: vp8channel
  dns: "8.8.8.8:53"
data: data
Run each in its own terminal, tmux pane, or systemd service:
./build/olcrtc-linux-amd64 server-jitsi.yaml
./build/olcrtc-linux-amd64 server-wbstream.yaml
On the client, use a different SOCKS5 port for each server:
# client-jitsi.yaml
mode: cnc
auth:
  provider: jitsi
room:
  id: "https://meet.example.org/room1"
crypto:
  key: "aaaa...1111"
net:
  transport: datachannel
  dns: "8.8.8.8:53"
socks:
  host: "127.0.0.1"
  port: 8808
data: data
# client-wbstream.yaml
mode: cnc
auth:
  provider: wbstream
room:
  id: "<room-id>"
crypto:
  key: "bbbb...2222"
net:
  transport: vp8channel
  dns: "8.8.8.8:53"
socks:
  host: "127.0.0.1"
  port: 8809
data: data
./build/olcrtc-linux-amd64 client-jitsi.yaml      # SOCKS5 on :8808
./build/olcrtc-linux-amd64 client-wbstream.yaml    # SOCKS5 on :8809

Build docs developers (and LLMs) love