mirror of
https://github.com/livekit/livekit.git
synced 2026-05-15 00:55:32 +00:00
feat: support UDP in TURN (#61)
1. Add UDP option to TURN 2. GetLocalIPAddress default to IPv4
This commit is contained in:
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/livekit/protocol/auth"
|
||||
@@ -40,7 +39,12 @@ func printPorts(c *cli.Context) error {
|
||||
}
|
||||
|
||||
if conf.TURN.Enabled {
|
||||
tcpPorts = append(tcpPorts, strconv.Itoa(conf.TURN.TLSPort))
|
||||
if conf.TURN.TLSPort > 0 {
|
||||
tcpPorts = append(tcpPorts, fmt.Sprintf("%d - TURN/TLS", conf.TURN.TLSPort))
|
||||
}
|
||||
if conf.TURN.UDPPort > 0 {
|
||||
udpPorts = append(udpPorts, fmt.Sprintf("%d - TURN/UDP", conf.TURN.UDPPort))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("TCP Ports")
|
||||
|
||||
+4
-2
@@ -95,10 +95,12 @@ keys:
|
||||
# # - using cert_file and key_file below
|
||||
# # defaults to false
|
||||
# enabled: false
|
||||
# # needs to match tls cert domain
|
||||
# domain: turn.myhost.com
|
||||
# # defaults to 3478 - recommended to 443 if not running HTTP3/QUIC server
|
||||
# udp_port: 3478
|
||||
# # defaults to 3478 - if not using a load balancer, this must be set to 443
|
||||
# tls_port: 3478
|
||||
# # needs to match tls cert domain
|
||||
# domain: turn.myhost.com
|
||||
# # optional
|
||||
# # cert_file: /path/to/cert.pem
|
||||
# # key_file: /path/to/key.pem
|
||||
|
||||
@@ -91,6 +91,7 @@ type TURNConfig struct {
|
||||
CertFile string `yaml:"cert_file"`
|
||||
KeyFile string `yaml:"key_file"`
|
||||
TLSPort int `yaml:"tls_port"`
|
||||
UDPPort int `yaml:"udp_port"`
|
||||
}
|
||||
|
||||
func NewConfig(confString string, c *cli.Context) (*Config, error) {
|
||||
@@ -135,6 +136,7 @@ func NewConfig(confString string, c *cli.Context) (*Config, error) {
|
||||
TURN: TURNConfig{
|
||||
Enabled: false,
|
||||
TLSPort: 3478,
|
||||
UDPPort: 3478,
|
||||
},
|
||||
Keys: map[string]string{},
|
||||
}
|
||||
|
||||
+5
-2
@@ -41,12 +41,15 @@ func GetLocalIPAddress() (string, error) {
|
||||
var ip net.IP
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
ip = v.IP.To4()
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
ip = v.IP.To4()
|
||||
default:
|
||||
continue
|
||||
}
|
||||
if ip == nil {
|
||||
continue
|
||||
}
|
||||
if ip.IsLoopback() {
|
||||
loopBack = ip.String()
|
||||
} else {
|
||||
|
||||
@@ -513,11 +513,20 @@ func (r *RoomManager) iceServersForRoom(ri *livekit.Room) []*livekit.ICEServer {
|
||||
})
|
||||
}
|
||||
if r.config.TURN.Enabled {
|
||||
iceServers = append(iceServers, &livekit.ICEServer{
|
||||
Urls: []string{fmt.Sprintf("turns:%s:443?transport=tcp", r.config.TURN.Domain)},
|
||||
Username: ri.Name,
|
||||
Credential: ri.TurnPassword,
|
||||
})
|
||||
var urls []string
|
||||
if r.config.TURN.UDPPort > 0 {
|
||||
urls = append(urls, fmt.Sprintf("turn:%s:%d?transport=udp", r.config.RTC.NodeIP, r.config.TURN.UDPPort))
|
||||
}
|
||||
if r.config.TURN.TLSPort > 0 {
|
||||
urls = append(urls, fmt.Sprintf("turns:%s:443?transport=tcp", r.config.TURN.Domain))
|
||||
}
|
||||
if len(urls) > 0 {
|
||||
iceServers = append(iceServers, &livekit.ICEServer{
|
||||
Urls: urls,
|
||||
Username: ri.Name,
|
||||
Credential: ri.TurnPassword,
|
||||
})
|
||||
}
|
||||
}
|
||||
return iceServers
|
||||
}
|
||||
|
||||
+52
-31
@@ -25,46 +25,67 @@ func NewTurnServer(conf *config.Config, roomStore RoomStore, node routing.LocalN
|
||||
if !turnConf.Enabled {
|
||||
return nil, nil
|
||||
}
|
||||
if turnConf.Domain == "" {
|
||||
return nil, errors.New("TURN domain required")
|
||||
}
|
||||
if turnConf.TLSPort == 0 {
|
||||
return nil, errors.New("invalid TURN tcp port")
|
||||
}
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(turnConf.CertFile, turnConf.KeyFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "TURN tls cert required")
|
||||
}
|
||||
|
||||
tlsListener, err := tls.Listen("tcp4", "0.0.0.0:"+strconv.Itoa(turnConf.TLSPort), &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen on TURN TCP port")
|
||||
if turnConf.TLSPort == 0 && turnConf.UDPPort == 0 {
|
||||
return nil, errors.New("invalid TURN ports")
|
||||
}
|
||||
|
||||
serverConfig := turn.ServerConfig{
|
||||
Realm: livekitRealm,
|
||||
AuthHandler: newTurnAuthHandler(roomStore),
|
||||
LoggerFactory: logger.LoggerFactory(),
|
||||
ListenerConfigs: []turn.ListenerConfig{
|
||||
{
|
||||
Listener: tlsListener,
|
||||
RelayAddressGenerator: &turn.RelayAddressGeneratorPortRange{
|
||||
RelayAddress: net.ParseIP(node.Ip),
|
||||
Address: "0.0.0.0",
|
||||
MinPort: turnMinPort,
|
||||
MaxPort: turnMaxPort,
|
||||
MaxRetries: allocateRetries,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
relayAddrGen := &turn.RelayAddressGeneratorPortRange{
|
||||
RelayAddress: net.ParseIP(node.Ip),
|
||||
Address: "0.0.0.0",
|
||||
MinPort: turnMinPort,
|
||||
MaxPort: turnMaxPort,
|
||||
MaxRetries: allocateRetries,
|
||||
}
|
||||
var logValues []interface{}
|
||||
|
||||
if turnConf.TLSPort > 0 {
|
||||
if turnConf.Domain == "" {
|
||||
return nil, errors.New("TURN domain required")
|
||||
}
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(turnConf.CertFile, turnConf.KeyFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "TURN tls cert required")
|
||||
}
|
||||
|
||||
tlsListener, err := tls.Listen("tcp4", "0.0.0.0:"+strconv.Itoa(turnConf.TLSPort),
|
||||
&tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen on TURN TCP port")
|
||||
}
|
||||
|
||||
listenerConfig := turn.ListenerConfig{
|
||||
Listener: tlsListener,
|
||||
RelayAddressGenerator: relayAddrGen,
|
||||
}
|
||||
serverConfig.ListenerConfigs = append(serverConfig.ListenerConfigs, listenerConfig)
|
||||
logValues = append(logValues, "turn.portTLS", turnConf.TLSPort)
|
||||
}
|
||||
|
||||
logger.Infow("Starting TURN server",
|
||||
"TLS port", turnConf.TLSPort)
|
||||
if turnConf.UDPPort > 0 {
|
||||
udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(turnConf.UDPPort))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen on TURN UDP port")
|
||||
}
|
||||
|
||||
packetConfig := turn.PacketConnConfig{
|
||||
PacketConn: udpListener,
|
||||
RelayAddressGenerator: relayAddrGen,
|
||||
}
|
||||
serverConfig.PacketConnConfigs = append(serverConfig.PacketConnConfigs, packetConfig)
|
||||
logValues = append(logValues, "turn.portUDP", turnConf.UDPPort)
|
||||
}
|
||||
|
||||
logger.Infow("Starting TURN server", logValues...)
|
||||
return turn.NewServer(serverConfig)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user