datarhei-dragonfork-core/core/webrtc/ice.go
ZGaetano b045b26f17
Some checks failed
ci / race tests (push) Blocked by required conditions
ci / WebRTC smoke (5-viewer fanout) (push) Blocked by required conditions
ci / WebRTC latency p95 gate (push) Blocked by required conditions
ci / vet + build (push) Has been cancelled
webrtc: BuildICEConfig uses NAT1To1IPs list, falls back to PublicIP (issue #20)
2026-05-10 14:01:53 -04:00

62 lines
2.2 KiB
Go

package webrtc
import (
"github.com/pion/webrtc/v4"
)
// BuildICEConfig translates a Config into the two Pion config pieces every
// PeerConnection needs: a webrtc.Configuration (with ICE servers) and a
// SettingEngine (with NAT1To1 and port range tuning).
//
// NAT1To1 IP resolution order:
// 1. NAT1To1IPs — the full list is passed directly to Pion when non-empty.
// 2. PublicIP — promoted to a single-element NAT1To1IPs list for backward
// compatibility with configs that only set PublicIP.
// 3. Neither set — STUN-only mode; no host candidates are injected.
//
// The returned *SettingEngine may be nil if no engine-level tuning is
// required (i.e. no NAT1To1 IPs and UDPPortRange at defaults). Callers
// should only pass it to webrtc.NewAPI when non-nil.
func BuildICEConfig(c Config) (webrtc.Configuration, *webrtc.SettingEngine, error) {
if err := c.Validate(); err != nil {
return webrtc.Configuration{}, nil, err
}
rtcConfig := webrtc.Configuration{
ICEServers: make([]webrtc.ICEServer, 0, len(c.ICEServers)),
}
for _, uri := range c.ICEServers {
rtcConfig.ICEServers = append(rtcConfig.ICEServers, webrtc.ICEServer{
URLs: []string{uri},
})
}
// Build the effective NAT1To1 IP list.
// Prefer the explicit NAT1To1IPs slice; fall back to PublicIP as a
// single-element list so that legacy configs (PublicIP only) continue
// to work without operator changes.
nat1to1 := c.NAT1To1IPs
if len(nat1to1) == 0 && c.PublicIP != "" {
nat1to1 = []string{c.PublicIP}
}
var se *webrtc.SettingEngine
if len(nat1to1) > 0 || c.UDPPortRange.Low > 0 {
engine := webrtc.SettingEngine{}
if len(nat1to1) > 0 {
engine.SetNAT1To1IPs(nat1to1, webrtc.ICECandidateTypeHost)
}
// Constrain the ephemeral UDP range Pion allocates for ICE candidates.
// Note: this is a separate concern from our FFmpeg→Source UDP ports;
// Pion uses its own port pool for the WebRTC media path.
if c.UDPPortRange.Low > 0 && c.UDPPortRange.High >= c.UDPPortRange.Low {
if err := engine.SetEphemeralUDPPortRange(
uint16(c.UDPPortRange.Low), uint16(c.UDPPortRange.High)); err != nil {
return webrtc.Configuration{}, nil, err
}
}
se = &engine
}
return rtcConfig, se, nil
}