fix(server): restrict RTC binding to node_ip via rtc.ips.includes #32

Open
sameh-farouk wants to merge 1 commit from fix/multi-user-rtc-ips-bind into main
Member

Closes #31.

Problem

On a multi-user Hero box, the second user's livekit-server fails to start with:

listen udp [<sibling-user-bridge-ip>]:7882: bind: address already in use

Root cause: Pion's UDP port-mux auto-enumerates every global IPv6 on the host when rtc.ips.includes is unset, so each user's livekit tries to bind :7882 on every other user's mycelium bridge IP too.

Fix

Render rtc.ips.includes into the generated livekit.yaml:

rtc:
  ...
  node_ip: "<bridge-ip>"
  ips:
    includes:
      - "<bridge-ip>/128"

This pins both UDP binding and ICE candidate advertisement to the configured node_ip, matching the upstream-recommended approach for restricted-interface deploys (livekit/livekit#1876, #3842).

Test plan

  • Verified on dev box 138.201.206.39: two users (sameh on 4a0:6976:8fa7:efc:5::1, ashraf on 4a0:6976:8fa7:efc:1::1) now start livekit-server concurrently without EADDRINUSE.
  • Confirmed via ss -lun that each user's livekit only listens on its own [node_ip]:7882, not on every host IPv6.
  • Single-user (non-multi-user) deploys unaffected — rtc.ips.includes matching node_ip is a no-op when only one global IPv6 is in scope.

Notes

  • 10-line addition to render_livekit_yaml; no other behavior change.
  • The stale-bridge-address cleanup gap in multi_user_del is a separate issue and tracked elsewhere — this fix removes the bind-time collision regardless.
Closes #31. ## Problem On a multi-user Hero box, the second user's `livekit-server` fails to start with: ``` listen udp [<sibling-user-bridge-ip>]:7882: bind: address already in use ``` Root cause: Pion's UDP port-mux auto-enumerates every global IPv6 on the host when `rtc.ips.includes` is unset, so each user's livekit tries to bind `:7882` on every other user's mycelium bridge IP too. ## Fix Render `rtc.ips.includes` into the generated `livekit.yaml`: ```yaml rtc: ... node_ip: "<bridge-ip>" ips: includes: - "<bridge-ip>/128" ``` This pins both UDP binding and ICE candidate advertisement to the configured `node_ip`, matching the upstream-recommended approach for restricted-interface deploys (livekit/livekit#1876, #3842). ## Test plan - [x] Verified on dev box `138.201.206.39`: two users (`sameh` on `4a0:6976:8fa7:efc:5::1`, `ashraf` on `4a0:6976:8fa7:efc:1::1`) now start `livekit-server` concurrently without EADDRINUSE. - [x] Confirmed via `ss -lun` that each user's livekit only listens on its own `[node_ip]:7882`, not on every host IPv6. - [x] Single-user (non-multi-user) deploys unaffected — `rtc.ips.includes` matching `node_ip` is a no-op when only one global IPv6 is in scope. ## Notes - 10-line addition to `render_livekit_yaml`; no other behavior change. - The stale-bridge-address cleanup gap in `multi_user_del` is a separate issue and tracked elsewhere — this fix removes the bind-time collision regardless.
fix(server): restrict RTC binding to node_ip via rtc.ips.includes
Some checks failed
Build & Test / check (pull_request) Failing after 3s
054c3a88b4
Pion (UDP port-mux) auto-enumerates every global IPv6 address on the
host and tries to bind UDP/7882 on each. On a multi-user Hero box where
each user has their own mycelium /64 bridge, the second users livekit
fails on startup with:

  listen udp [other-user-ip]:7882: bind: address already in use

even though that IP belongs to a sibling users bridge. The collision is
between Pions auto-enumeration and sibling users active bridges, not
between the two livekit instances configured node_ip values.

Render rtc.ips.includes [<node_ip>/128] into the generated livekit.yaml
so the SFU pins UDP binding and ICE candidate advertisement to the
configured node_ip only. Per livekit/livekit#1876 and #3842 this is the
documented restriction mechanism.

Verified on dev box with two concurrent users on
4a0:6976:8fa7:efc:5::1 and 4a0:6976:8fa7:efc:1::1.
Some checks failed
Build & Test / check (pull_request) Failing after 3s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/multi-user-rtc-ips-bind:fix/multi-user-rtc-ips-bind
git switch fix/multi-user-rtc-ips-bind

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff fix/multi-user-rtc-ips-bind
git switch fix/multi-user-rtc-ips-bind
git rebase main
git switch main
git merge --ff-only fix/multi-user-rtc-ips-bind
git switch fix/multi-user-rtc-ips-bind
git rebase main
git switch main
git merge --no-ff fix/multi-user-rtc-ips-bind
git switch main
git merge --squash fix/multi-user-rtc-ips-bind
git switch main
git merge --ff-only fix/multi-user-rtc-ips-bind
git switch main
git merge fix/multi-user-rtc-ips-bind
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_livekit!32
No description provided.