Implement UDP muxing.

This commit is contained in:
Juliusz Chroboczek
2025-03-21 15:11:36 +01:00
parent e09b135cd2
commit 85c32897ad
3 changed files with 47 additions and 16 deletions
+18 -7
View File
@@ -65,13 +65,24 @@ then press *Ready* in one of the two; you should see a video in the other.
If your server has a global IPv4 address and there is no firewall, there If your server has a global IPv4 address and there is no firewall, there
is nothing to do. is nothing to do.
If your server has a global IPv4 address, then the firewall must, at If your server has a global IPv4 address, then the firewall must allow
a strict minimum, allow incoming traffic to TCP port 8443 (or whatever is traffic to and from:
configured with the `-http` command-line option) and TCP port 1194 (or
whatever is configured with the `-turn` option). For best performance, it * TCP port 8443 (or whatever is configured with the `-http` option); and
should also allow UDP traffic to the TURN port, and UDP traffic to
ephemeral (high-numbered) ports (or whatever is configured using the * TCP and UDP port 1194 (or whatever is configured with the `-turn` option).
`-udp-range` option).
For good performance, your firewall should allow incoming and outgoing
traffic from the UDP ports used for media transfer. By default, these are
all high-numbered (ephemeral) ports, but they can be restricted using the
following options:
* the `-udp-range port1-port2` option restricts the UDP ports to be in
the range from port1 to port2 inclusive; this should be a large range,
on the order of a few tens of thousands of ports;
* the `-udp port` option makes the server use just a single port, and
demultiplex the traffic in userspace.
If your server is behind NAT (which is not recommended), then the NAT must If your server is behind NAT (which is not recommended), then the NAT must
forward, at the very least, port 8443 to your server. Ideally, you should forward, at the very least, port 8443 to your server. Ideally, you should
+18 -7
View File
@@ -9,6 +9,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
"strconv"
"syscall" "syscall"
"time" "time"
@@ -23,7 +24,7 @@ import (
func main() { func main() {
var cpuprofile, memprofile, mutexprofile, httpAddr string var cpuprofile, memprofile, mutexprofile, httpAddr string
var udpRange string var udp, udpRange string
flag.StringVar(&httpAddr, "http", ":8443", "web server `address`") flag.StringVar(&httpAddr, "http", ":8443", "web server `address`")
flag.StringVar(&webserver.StaticRoot, "static", "./static/", flag.StringVar(&webserver.StaticRoot, "static", "./static/",
@@ -42,8 +43,8 @@ func main() {
"store memory profile in `file`") "store memory profile in `file`")
flag.StringVar(&mutexprofile, "mutexprofile", "", flag.StringVar(&mutexprofile, "mutexprofile", "",
"store mutex profile in `file`") "store mutex profile in `file`")
flag.StringVar(&udpRange, "udp-range", "", flag.StringVar(&udp, "udp", "", "UDP port")
"UDP port `range`") flag.StringVar(&udpRange, "udp-range", "", "UDP port `range`")
flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses") flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses")
flag.BoolVar(&ice.ICERelayOnly, "relay-only", false, flag.BoolVar(&ice.ICERelayOnly, "relay-only", false,
"require use of TURN relays for all media traffic") "require use of TURN relays for all media traffic")
@@ -51,16 +52,26 @@ func main() {
"built-in TURN server `address` (\"\" to disable)") "built-in TURN server `address` (\"\" to disable)")
flag.Parse() flag.Parse()
if udp != "" {
if udpRange != "" { if udpRange != "" {
log.Fatalf("Cannot specify both -udp and -udp-range")
}
port, err := strconv.Atoi(udp)
if err != nil {
log.Fatalf("UDP: %v", err)
}
err = group.SetUDPMux(port)
if err != nil {
log.Fatalf("UDP: %v", err)
}
} else if udpRange != "" {
var min, max uint16 var min, max uint16
n, err := fmt.Sscanf(udpRange, "%v-%v", &min, &max) n, err := fmt.Sscanf(udpRange, "%v-%v", &min, &max)
if err != nil { if err != nil {
log.Printf("UDP range: %v", err) log.Fatalf("UDP range: %v", err)
os.Exit(1)
} }
if n != 2 || min <= 0 || max <= 0 || min > max { if n != 2 || min <= 0 || max <= 0 || min > max {
log.Printf("UDP range: bad range") log.Fatalf("UDP range: bad range")
os.Exit(1)
} }
group.UDPMin = min group.UDPMin = min
group.UDPMax = max group.UDPMax = max
+10 -1
View File
@@ -25,6 +25,7 @@ import (
var Directory, DataDirectory string var Directory, DataDirectory string
var UseMDNS bool var UseMDNS bool
var UDPMin, UDPMax uint16 var UDPMin, UDPMax uint16
var udpMux ice.UDPMux
type NotAuthorisedError struct { type NotAuthorisedError struct {
err error err error
@@ -357,6 +358,12 @@ func codecsFromName(name string) ([]webrtc.RTPCodecParameters, error) {
return parms, nil return parms, nil
} }
func SetUDPMux(port int) error {
var err error
udpMux, err = ice.NewMultiUDPMuxFromPort(port)
return err
}
func APIFromCodecs(codecs []webrtc.RTPCodecParameters) (*webrtc.API, error) { func APIFromCodecs(codecs []webrtc.RTPCodecParameters) (*webrtc.API, error) {
s := webrtc.SettingEngine{} s := webrtc.SettingEngine{}
s.SetSRTPReplayProtectionWindow(512) s.SetSRTPReplayProtectionWindow(512)
@@ -379,7 +386,9 @@ func APIFromCodecs(codecs []webrtc.RTPCodecParameters) (*webrtc.API, error) {
} }
} }
if UDPMin > 0 && UDPMax > 0 { if udpMux != nil {
s.SetICEUDPMux(udpMux)
} else if UDPMin > 0 && UDPMax > 0 {
s.SetEphemeralUDPPortRange(UDPMin, UDPMax) s.SetEphemeralUDPPortRange(UDPMin, UDPMax)
} }