fix(relay): force dual-stack relay socket for wildcard listeners#226
Open
ti wants to merge 2 commits into
Open
fix(relay): force dual-stack relay socket for wildcard listeners#226ti wants to merge 2 commits into
ti wants to merge 2 commits into
Conversation
Listener and relay sockets hardcoded "0.0.0.0" + the IPv4-only network
strings "udp4"/"tcp4". On IPv4-only hosts that's fine, but on IPv6-only
hosts (e.g. IPv6-only EKS) the socket cannot be reached at all, so
TURN allocations silently fail. On dual-stack hosts (Linux default with
net.ipv6.bindv6only=0) it still works for IPv4 peers but breaks for
IPv6-only peers, including pod-to-pod traffic on IPv6-only Kubernetes.
Switch to the unspecified address (":port" / "") plus the family-neutral
network strings ("udp" / "tcp"). The kernel then opens an IPv6 wildcard
socket that accepts IPv4 (mapped) and IPv6 peers on dual-stack hosts and
the available family on single-family hosts, matching the behavior of
Go's net.Listen with no host. Verified end-to-end on IPv6-only EKS:
- 16-thread UDP listener now bound on [::]:7006 (was 0.0.0.0:7006)
- TURN allocate succeeds from an IPv6-only client
- relay address returned to the client is on the listener's IPv6 addr
No semantic change for IPv4-only deployments: ":port" continues to bind
to the IPv4 wildcard when no IPv6 stack is present.
…ener
Stunner's RelayGen.AllocatePacketConn forwards pion/turn's hint
`AllocateListenerConfig.Network` ("udp4"/"udp6") straight to
ListenPacket. On Linux dual-stack hosts that hint forces a
single-family socket regardless of how the listener was bound, so a
relay allocated from an IPv6-only Kubernetes cluster is unreachable
when pion/turn defaults to the RFC 6156 IPv4 allocation family
(default, since browser TURN clients omit REQUESTED-ADDRESS-FAMILY).
Build on top of l7mp#225 (Address: "" wildcard fix): when the listener uses
the wildcard, replace the family-pinned network with the family-neutral
"udp" so the relay socket binds [::] on dual-stack hosts and reaches
both IPv4 and IPv6 peers from one allocation. No-op for explicit
family-pinned listeners.
End-to-end cross-family forwarding additionally requires pion/turn's
`ipMatchesFamily` permission check to accept v6 peers on v4
allocations; tracked in a separate pion/turn upstream issue. With both
fixes in place, browser-issued Allocate (default IPv4 family) on an
IPv6-only EKS cluster successfully relays to IPv6 backend pods --
verified end-to-end with LiveKit (connectionType=turn).
Refs: l7mp#225
5 tasks
Member
|
TL;DR The current policy is compliant with the RFC. We can decide to deviate from the standard, but only for a good reason. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Override pion/turn's family-pinned
AllocateListenerConfig.Networkhint(
udp4/udp6) with the family-neutraludpwhen the listener usesthe wildcard
Address, so the relay socket binds[::]on Linuxdual-stack hosts and reaches both IPv4 and IPv6 peers from a single
allocation.
A no-op when
r.Addressis family-pinned (RFC 6156 strict behavior ispreserved).
Why
Browsers' TURN clients omit
REQUESTED-ADDRESS-FAMILYin theirAllocaterequest, so pion/turn falls back to the RFC 6156 default IPv4family. The Allocation Manager then asks the relay generator to listen
on
udp4. On an IPv6-only Kubernetes cluster, a pion-based WebRTCmedia-server pod only has an IPv6 address, so a single-family IPv4
relay socket can never reach it.
The result is what looks like a successful TURN allocation with no
working media path:
Allocatesucceeds,CreatePermissionfor anIPv6 peer is silently dropped by pion/turn's strict
ipMatchesFamily,Send-indicationfails with "no permission added", and the WebRTCpeer-connection times out.
Stack
This builds on #225 (
Address: "0.0.0.0"→""). Together they makethe listener and relay sockets uniformly dual-stack on dual-stack hosts.
Pairing pion/turn fix
End-to-end cross-family forwarding additionally requires pion/turn's
internal/server/turn.goto accept IPv6 peers on a default-IPv4allocation (
ipMatchesFamily). Tracked at pion/turn#566 andproposed in pion/turn#567. Until that lands, deployments need a
vendored pion/turn (a
replacedirective ingo.modis enough).Verified
On an IPv6-only Linux host with a custom build of stunnerd from this
branch:
[::]:<turn-port>(verified via/proc/net/udp6).[::]:<random>after Allocate (was previouslyIPv4-only).
paired pion/turn patch above; ICE candidate pairs forced to relay
(
iceTransportPolicy: "relay") succeed, browser reports mediaflowing through the relay candidate.
No regression on dual-stack and IPv4-only hosts.
Refs: #225, pion/turn#566, pion/turn#567