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 }