mirror of
https://github.com/livekit/livekit.git
synced 2026-08-28 05:04:10 +00:00
Embedded TURN server
This commit is contained in:
+16
-2
@@ -13,6 +13,7 @@ type Config struct {
|
||||
RTC RTCConfig `yaml:"rtc"`
|
||||
Redis RedisConfig `yaml:"redis"`
|
||||
Audio AudioConfig `yaml:"audio"`
|
||||
TURN TURNConfig `yaml:"turn"`
|
||||
KeyFile string `yaml:"key_file"`
|
||||
Keys map[string]string `yaml:"keys"`
|
||||
LogLevel string `yaml:"log_level"`
|
||||
@@ -49,6 +50,13 @@ type RedisConfig struct {
|
||||
Password string `yaml:"password"`
|
||||
}
|
||||
|
||||
type TURNConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
ListenPort int `yaml:"listen_port"`
|
||||
PortRangeStart uint16 `yaml:"port_range_start"`
|
||||
PortRangeEnd uint16 `yaml:"port_range_end"`
|
||||
}
|
||||
|
||||
func NewConfig(confString string) (*Config, error) {
|
||||
// start with defaults
|
||||
conf := &Config{
|
||||
@@ -56,7 +64,7 @@ func NewConfig(confString string) (*Config, error) {
|
||||
RTC: RTCConfig{
|
||||
UseExternalIP: true,
|
||||
ICEPortRangeStart: 9000,
|
||||
ICEPortRangeEnd: 9200,
|
||||
ICEPortRangeEnd: 11000,
|
||||
StunServers: []string{
|
||||
"stun.l.google.com:19302",
|
||||
"stun1.l.google.com:19302",
|
||||
@@ -69,7 +77,13 @@ func NewConfig(confString string) (*Config, error) {
|
||||
UpdateInterval: 500,
|
||||
},
|
||||
Redis: RedisConfig{},
|
||||
Keys: map[string]string{},
|
||||
TURN: TURNConfig{
|
||||
Enabled: false,
|
||||
ListenPort: 3478,
|
||||
PortRangeStart: 12000,
|
||||
PortRangeEnd: 16000,
|
||||
},
|
||||
Keys: map[string]string{},
|
||||
}
|
||||
if confString != "" {
|
||||
yaml.Unmarshal([]byte(confString), conf)
|
||||
|
||||
@@ -61,6 +61,7 @@ func (r *RoomManager) CreateRoom(req *livekit.CreateRoomRequest) (*livekit.Room,
|
||||
Sid: utils.NewGuid(utils.RoomPrefix),
|
||||
Name: req.Name,
|
||||
CreationTime: time.Now().Unix(),
|
||||
TurnPassword: utils.RandomSecret(),
|
||||
}
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pion/turn/v2"
|
||||
"github.com/urfave/negroni"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/auth"
|
||||
@@ -26,6 +27,7 @@ type LivekitServer struct {
|
||||
httpServer *http.Server
|
||||
router routing.Router
|
||||
roomManager *RoomManager
|
||||
turnServer *turn.Server
|
||||
currentNode routing.LocalNode
|
||||
running utils.AtomicFlag
|
||||
doneChan chan bool
|
||||
@@ -37,6 +39,7 @@ func NewLivekitServer(conf *config.Config,
|
||||
keyProvider auth.KeyProvider,
|
||||
router routing.Router,
|
||||
roomManager *RoomManager,
|
||||
turnServer *turn.Server,
|
||||
currentNode routing.LocalNode,
|
||||
) (s *LivekitServer, err error) {
|
||||
s = &LivekitServer{
|
||||
@@ -45,6 +48,8 @@ func NewLivekitServer(conf *config.Config,
|
||||
rtcService: rtcService,
|
||||
router: router,
|
||||
roomManager: roomManager,
|
||||
// turn server starts automatically
|
||||
turnServer: turnServer,
|
||||
currentNode: currentNode,
|
||||
}
|
||||
|
||||
@@ -132,6 +137,10 @@ func (s *LivekitServer) Start() error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||||
s.httpServer.Shutdown(ctx)
|
||||
|
||||
if s.turnServer != nil {
|
||||
s.turnServer.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/pion/turn/v2"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/config"
|
||||
"github.com/livekit/livekit-server/pkg/logger"
|
||||
"github.com/livekit/livekit-server/pkg/routing"
|
||||
)
|
||||
|
||||
const (
|
||||
allocateRetries = 1000
|
||||
livekitRealm = "livekit"
|
||||
)
|
||||
|
||||
func NewTurnServer(conf *config.Config, roomStore RoomStore, node routing.LocalNode) (*turn.Server, error) {
|
||||
turnConf := conf.TURN
|
||||
if !turnConf.Enabled {
|
||||
return nil, nil
|
||||
}
|
||||
serverConfig := turn.ServerConfig{
|
||||
Realm: livekitRealm,
|
||||
AuthHandler: newTurnAuthHandler(roomStore),
|
||||
}
|
||||
|
||||
tcpListener, err := net.Listen("tcp4", "0.0.0.0:"+strconv.Itoa(turnConf.ListenPort))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen on TURN TCP port")
|
||||
}
|
||||
serverConfig.ListenerConfigs = []turn.ListenerConfig{
|
||||
{
|
||||
Listener: tcpListener,
|
||||
RelayAddressGenerator: &turn.RelayAddressGeneratorPortRange{
|
||||
RelayAddress: net.ParseIP(node.Ip),
|
||||
Address: "0.0.0.0",
|
||||
MinPort: turnConf.PortRangeStart,
|
||||
MaxPort: turnConf.PortRangeEnd,
|
||||
MaxRetries: allocateRetries,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(turnConf.ListenPort))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not listen on TURN UDP port")
|
||||
}
|
||||
serverConfig.PacketConnConfigs = []turn.PacketConnConfig{
|
||||
{
|
||||
PacketConn: udpListener,
|
||||
RelayAddressGenerator: &turn.RelayAddressGeneratorPortRange{
|
||||
RelayAddress: net.ParseIP(node.Ip), // Claim that we are listening on IP passed by user (This should be your Public IP)
|
||||
Address: "0.0.0.0", // But actually be listening on every interface
|
||||
MinPort: turnConf.PortRangeStart,
|
||||
MaxPort: turnConf.PortRangeEnd,
|
||||
MaxRetries: allocateRetries,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
logger.Infow("Starting TURN server",
|
||||
"port", turnConf.ListenPort,
|
||||
"portRange", fmt.Sprintf("%d-%d", turnConf.PortRangeStart, turnConf.PortRangeEnd))
|
||||
return turn.NewServer(serverConfig)
|
||||
}
|
||||
|
||||
func newTurnAuthHandler(roomStore RoomStore) turn.AuthHandler {
|
||||
return func(username, realm string, srcAddr net.Addr) (key []byte, ok bool) {
|
||||
// room id should be the username, create a hashed room id
|
||||
rm, err := roomStore.GetRoom(username)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return turn.GenerateAuthKey(username, livekitRealm, rm.TurnPassword), true
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ var ServiceSet = wire.NewSet(
|
||||
NewRTCService,
|
||||
NewLivekitServer,
|
||||
NewRoomManager,
|
||||
NewTurnServer,
|
||||
config.GetAudioConfig,
|
||||
wire.Bind(new(livekit.RoomService), new(*RoomService)),
|
||||
)
|
||||
|
||||
@@ -23,7 +23,11 @@ func InitializeServer(conf *config.Config, keyProvider auth.KeyProvider, roomSto
|
||||
return nil, err
|
||||
}
|
||||
rtcService := NewRTCService(conf, roomStore, roomManager, router, currentNode)
|
||||
livekitServer, err := NewLivekitServer(conf, roomService, rtcService, keyProvider, router, roomManager, currentNode)
|
||||
server, err := NewTurnServer(conf, roomStore, currentNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
livekitServer, err := NewLivekitServer(conf, roomService, rtcService, keyProvider, router, roomManager, server, currentNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user