diff --git a/INSTALL b/INSTALL index f60597b..e73e55d 100644 --- a/INSTALL +++ b/INSTALL @@ -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 is nothing to do. -If your server has a global IPv4 address, then the firewall must, at -a strict minimum, allow incoming traffic to TCP port 8443 (or whatever is -configured with the `-http` command-line option) and TCP port 1194 (or -whatever is configured with the `-turn` option). For best performance, it -should also allow UDP traffic to the TURN port, and UDP traffic to -ephemeral (high-numbered) ports (or whatever is configured using the -`-udp-range` option). +If your server has a global IPv4 address, then the firewall must allow +traffic to and from: + + * TCP port 8443 (or whatever is configured with the `-http` option); and + + * TCP and UDP port 1194 (or whatever is configured with the `-turn` 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 forward, at the very least, port 8443 to your server. Ideally, you should diff --git a/galene.go b/galene.go index f8a05f7..b4fedce 100644 --- a/galene.go +++ b/galene.go @@ -9,6 +9,7 @@ import ( "path/filepath" "runtime" "runtime/pprof" + "strconv" "syscall" "time" @@ -23,7 +24,7 @@ import ( func main() { var cpuprofile, memprofile, mutexprofile, httpAddr string - var udpRange string + var udp, udpRange string flag.StringVar(&httpAddr, "http", ":8443", "web server `address`") flag.StringVar(&webserver.StaticRoot, "static", "./static/", @@ -42,8 +43,8 @@ func main() { "store memory profile in `file`") flag.StringVar(&mutexprofile, "mutexprofile", "", "store mutex profile in `file`") - flag.StringVar(&udpRange, "udp-range", "", - "UDP port `range`") + flag.StringVar(&udp, "udp", "", "UDP port") + flag.StringVar(&udpRange, "udp-range", "", "UDP port `range`") flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses") flag.BoolVar(&ice.ICERelayOnly, "relay-only", false, "require use of TURN relays for all media traffic") @@ -51,16 +52,26 @@ func main() { "built-in TURN server `address` (\"\" to disable)") flag.Parse() - if udpRange != "" { + if udp != "" { + 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 n, err := fmt.Sscanf(udpRange, "%v-%v", &min, &max) if err != nil { - log.Printf("UDP range: %v", err) - os.Exit(1) + log.Fatalf("UDP range: %v", err) } if n != 2 || min <= 0 || max <= 0 || min > max { - log.Printf("UDP range: bad range") - os.Exit(1) + log.Fatalf("UDP range: bad range") } group.UDPMin = min group.UDPMax = max diff --git a/group/group.go b/group/group.go index 2bd0fe9..43d71fc 100644 --- a/group/group.go +++ b/group/group.go @@ -25,6 +25,7 @@ import ( var Directory, DataDirectory string var UseMDNS bool var UDPMin, UDPMax uint16 +var udpMux ice.UDPMux type NotAuthorisedError struct { err error @@ -357,6 +358,12 @@ func codecsFromName(name string) ([]webrtc.RTPCodecParameters, error) { 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) { s := webrtc.SettingEngine{} 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) }