Network Topology

Default Ports

Port Protocol Direction Service
5005 UDP bidirectional Broadcaster ingest (REGISTER_TX / AUDIO_TX) + relay fan-out (AUDIO)
19997 UDP mixer_web → mixer Control plane (fader/mute/scene/relay-assignment JSON commands)
19999 UDP MIDI sender → mixer Raw MIDI note datagrams from shiloh-midi-sender
8889 TCP browser → mixer_web Phoenix LiveView web UI
8890 TCP browser → web-relay WHEP HTTP signalling (WebRTC SDP exchange)
3819 UDP mixer → Ardour Ardour OSC (transport/navigation commands)
3820 UDP Ardour → mixer Ardour OSC feedback (fader/mute state)

NOTE: Port 5005 is shared between ingest (broadcaster → mixer) and relay output
(mixer → relay clients). The mixer disambiguates by packet type tag and the direction
of the session handshake.

LAN Setup (Typical)

All machines on the same LAN segment. No NAT or tunnelling needed.

192.168.0.0/24

  stg-srv001 (192.168.0.64)
    shiloh-mixer      :5005 UDP (ingest + relay)
    shiloh-mixer      :19997 UDP (control plane, localhost-only by default)
    shiloh-web-relay  :8890 TCP (WHEP HTTP)
    mixer_web         :8889 TCP (web UI)

  laptop / studio (any IP)
    shiloh-broadcaster → stg-srv001:5005

  pi-relay (192.168.0.189)
    shiloh-relay → stg-srv001:5005

Firewall rules needed on stg-srv001:

# Allow broadcaster ingest and relay fan-out
-A INPUT -p udp --dport 5005 -j ACCEPT

# Allow web UI access
-A INPUT -p tcp --dport 8889 -j ACCEPT

# Allow WHEP signalling
-A INPUT -p tcp --dport 8890 -j ACCEPT

# Optional: restrict control plane to localhost only (default bind is 127.0.0.1)
# No external firewall rule needed unless you change control_bind.

WAN / Remote Broadcaster Setup

For a broadcaster machine that is not on the same LAN, use a WireGuard tunnel so the
mixer sees a stable private IP.

Mixer server (stg-srv001)

Add the remote peer to your WireGuard config:

[Peer]
PublicKey = <remote broadcaster pubkey>
AllowedIPs = 10.0.0.2/32

Reload: wg syncconf wg0 <(wg-quick strip wg0)

Remote broadcaster machine

[Interface]
PrivateKey = <local privkey>
Address = 10.0.0.2/32
DNS = 10.0.0.1

[Peer]
PublicKey = <server pubkey>
Endpoint = <server-public-ip>:51820
AllowedIPs = 10.0.0.1/32   # route only the mixer IP through the tunnel
PersistentKeepalive = 25

Then connect the broadcaster to the WireGuard address:

shiloh-broadcaster connect --server 10.0.0.1:5005 --name remote-studio --channels 2

NOTE: The control_bind in shiloh-mixer.toml defaults to 127.0.0.1. If
shiloh-web-relay runs on a different host it needs the control plane accessible over
the network. Set control_bind to the WireGuard or LAN interface IP and add a firewall
rule for port 19997 restricted to trusted IPs only.

Firewall Rules for Remote Access

# WireGuard tunnel
-A INPUT -p udp --dport 51820 -j ACCEPT

# Broadcaster ingest (allow from WireGuard subnet)
-A INPUT -p udp --dport 5005 -s 10.0.0.0/24 -j ACCEPT

# Restrict control plane to WireGuard peers (if web-relay is remote)
-A INPUT -p udp --dport 19997 -s 10.0.0.0/24 -j ACCEPT

# WHEP for browser access (public or restricted as needed)
-A INPUT -p tcp --dport 8890 -j ACCEPT

Pi Relay Setup

The Pi relay runs shiloh-relay as an aarch64 binary via systemd.

Build on the mixer server or a Linux aarch64 cross-compile host:

cargo build --release --target aarch64-unknown-linux-gnu -p shiloh-relay
scp target/aarch64-unknown-linux-gnu/release/shiloh-relay pi@pi-relay:~/bin/

systemd unit (/etc/systemd/system/shiloh-relay.service):

[Unit]
Description=Shiloh Relay
After=network-online.target sound.target
Wants=network-online.target

[Service]
ExecStart=/home/pi/bin/shiloh-relay connect \
    --server stg-srv001:5005 \
    --name pi-relay \
    --device default \
    --buffer-ms 50
Restart=always
RestartSec=3
User=pi

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now shiloh-relay

DNS and Hostname Resolution

shiloh-broadcaster and shiloh-relay both accept a host:port string for --server.
DNS resolution happens at startup. On LAN setups, use mDNS hostnames (stg-srv001.local)
or static /etc/hosts entries for stability.

For remote setups, always resolve the WireGuard peer IP directly (10.0.0.1:5005) rather
than a public DNS name, since the tunnel IP is stable and avoids DNS lookup failures.