Embedded TURN server

This commit is contained in:
David Zhao
2021-03-06 22:47:48 -08:00
parent 2008a2e1e1
commit fa2ffa46e7
14 changed files with 316 additions and 67 deletions

View File

@@ -9,6 +9,7 @@ import (
"os/signal"
"runtime"
"runtime/pprof"
"strconv"
"syscall"
"time"
@@ -77,6 +78,11 @@ func main() {
Usage: "generates a pair of API & secret keys",
Action: generateKeys,
},
{
Name: "ports",
Usage: "print ports that server is configured to use",
Action: printPorts,
},
},
Version: version.Version,
}
@@ -241,3 +247,38 @@ func generateKeys(c *cli.Context) error {
fmt.Println("Secret Key: ", secret)
return nil
}
func printPorts(c *cli.Context) error {
confString, err := getConfigString(c)
if err != nil {
return err
}
conf, err := config.NewConfig(confString)
if err != nil {
return err
}
udpPorts := make([]string, 0)
tcpPorts := make([]string, 0)
tcpPorts = append(tcpPorts, strconv.Itoa(int(conf.Port)))
udpPorts = append(udpPorts, fmt.Sprintf("%d-%d", conf.RTC.ICEPortRangeStart, conf.RTC.ICEPortRangeEnd))
if conf.TURN.Enabled {
udpPorts = append(udpPorts, fmt.Sprintf("%d-%d", conf.TURN.PortRangeStart, conf.TURN.PortRangeEnd))
udpPorts = append(udpPorts, strconv.Itoa(conf.TURN.ListenPort))
tcpPorts = append(tcpPorts, strconv.Itoa(conf.TURN.ListenPort))
}
fmt.Println("TCP Ports")
for _, p := range tcpPorts {
fmt.Println(p)
}
fmt.Println("UDP Ports")
for _, p := range udpPorts {
fmt.Println(p)
}
return nil
}

1
go.mod
View File

@@ -19,6 +19,7 @@ require (
github.com/pion/rtp v1.6.2
github.com/pion/sdp/v3 v3.0.4
github.com/pion/stun v0.3.5
github.com/pion/turn/v2 v2.0.5
github.com/pion/webrtc/v3 v3.0.13
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0

View File

@@ -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)

View File

@@ -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

View File

@@ -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
}

81
pkg/service/turn.go Normal file
View File

@@ -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
}
}

View File

@@ -16,6 +16,7 @@ var ServiceSet = wire.NewSet(
NewRTCService,
NewLivekitServer,
NewRoomManager,
NewTurnServer,
config.GetAudioConfig,
wire.Bind(new(livekit.RoomService), new(*RoomService)),
)

View File

@@ -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
}

View File

@@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.14.0
// protoc-gen-go v1.25.0-devel
// protoc v3.15.3
// source: internal.proto
package livekit
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type Node struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.14.0
// protoc-gen-go v1.25.0-devel
// protoc v3.15.3
// source: model.proto
package livekit
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type TrackType int32
const (
@@ -140,6 +135,7 @@ type Room struct {
EmptyTimeout uint32 `protobuf:"varint,3,opt,name=empty_timeout,json=emptyTimeout,proto3" json:"empty_timeout,omitempty"`
MaxParticipants uint32 `protobuf:"varint,4,opt,name=max_participants,json=maxParticipants,proto3" json:"max_participants,omitempty"`
CreationTime int64 `protobuf:"varint,5,opt,name=creation_time,json=creationTime,proto3" json:"creation_time,omitempty"`
TurnPassword string `protobuf:"bytes,6,opt,name=turn_password,json=turnPassword,proto3" json:"turn_password,omitempty"`
}
func (x *Room) Reset() {
@@ -209,6 +205,13 @@ func (x *Room) GetCreationTime() int64 {
return 0
}
func (x *Room) GetTurnPassword() string {
if x != nil {
return x.TurnPassword
}
return ""
}
type ParticipantInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -443,7 +446,7 @@ var File_model_proto protoreflect.FileDescriptor
var file_model_proto_rawDesc = []byte{
0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6c,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6f, 0x6d, 0x12,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6f, 0x6d, 0x12,
0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69,
0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x74,
@@ -453,41 +456,43 @@ var file_model_proto_rawDesc = []byte{
0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69,
0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x72,
0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xfd, 0x01, 0x0a, 0x0f, 0x50,
0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10,
0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64,
0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x05,
0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6c, 0x69,
0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61,
0x74, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61,
0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x12, 0x1a,
0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3e, 0x0a, 0x05, 0x53, 0x74,
0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x00,
0x12, 0x0a, 0x0a, 0x06, 0x4a, 0x4f, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06,
0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x49, 0x53, 0x43,
0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x22, 0x6f, 0x0a, 0x09, 0x54, 0x72,
0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69,
0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x18, 0x04,
0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x22, 0x46, 0x0a, 0x0b, 0x44,
0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x04, 0x74, 0x65,
0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74,
0x12, 0x18, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
0x48, 0x00, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x2a, 0x2b, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65,
0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x56,
0x49, 0x44, 0x45, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x10, 0x02,
0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2d, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x69, 0x76, 0x65,
0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x75,
0x72, 0x6e, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x74, 0x75, 0x72, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22,
0xfd, 0x01, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
0x79, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x1e, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69,
0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65,
0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x6b,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69,
0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x72, 0x61,
0x63, 0x6b, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22,
0x3e, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x49, 0x4e,
0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4a, 0x4f, 0x49, 0x4e, 0x45, 0x44, 0x10,
0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a,
0x0c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x22,
0x6f, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03,
0x73, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x26,
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6c,
0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65,
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x75,
0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6d, 0x75, 0x74, 0x65, 0x64,
0x22, 0x46, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x14, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x42,
0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x2b, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x63,
0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x10, 0x00,
0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x44,
0x41, 0x54, 0x41, 0x10, 0x02, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x2f, 0x6c, 0x69, 0x76, 0x65,
0x6b, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2f, 0x6c, 0x69, 0x76, 0x65, 0x6b, 0x69, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.14.0
// protoc-gen-go v1.25.0-devel
// protoc v3.15.3
// source: room.proto
package livekit
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type CreateRoomRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache

View File

@@ -1,13 +1,12 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.14.0
// protoc-gen-go v1.25.0-devel
// protoc v3.15.3
// source: rtc.proto
package livekit
import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@@ -21,10 +20,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type SignalTarget int32
const (

View File

@@ -9,6 +9,7 @@ message Room {
uint32 empty_timeout = 3;
uint32 max_participants = 4;
int64 creation_time = 5;
string turn_password = 6;
}
message ParticipantInfo {

106
test/turn_test.go Normal file
View File

@@ -0,0 +1,106 @@
package test
import (
"fmt"
"net"
"testing"
"time"
"github.com/pion/turn/v2"
"github.com/stretchr/testify/require"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/routing"
"github.com/livekit/livekit-server/pkg/service"
"github.com/livekit/livekit-server/pkg/utils"
"github.com/livekit/livekit-server/proto/livekit"
)
func TestTurnServer(t *testing.T) {
conf, err := config.NewConfig("")
require.NoError(t, err)
conf.TURN.Enabled = true
currentNode, err := routing.NewLocalNode(conf)
require.NoError(t, err)
currentNode.Id = utils.NewGuid(nodeId1)
// local routing and store
router := routing.NewLocalRouter(currentNode)
roomStore := service.NewLocalRoomStore()
roomStore.DeleteRoom(testRoom)
s, err := service.InitializeServer(conf, &StaticKeyProvider{}, roomStore, router, currentNode, &routing.RandomSelector{})
require.NoError(t, err)
go s.Start()
waitForServerToStart(s)
defer s.Stop()
time.Sleep(syncDelay)
// create a room
rm := &livekit.Room{
Sid: utils.NewGuid(utils.RoomPrefix),
Name: "testroom",
TurnPassword: utils.RandomSecret(),
}
require.NoError(t, roomStore.CreateRoom(rm))
turnConf := &turn.ClientConfig{
STUNServerAddr: fmt.Sprintf("localhost:%d", conf.TURN.ListenPort),
TURNServerAddr: fmt.Sprintf("%s:%d", currentNode.Ip, conf.TURN.ListenPort),
Username: rm.Name,
Password: rm.TurnPassword,
Realm: "livekit",
}
t.Run("TURN works over TCP", func(t *testing.T) {
conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", conf.TURN.ListenPort))
require.NoError(t, err)
tc := *turnConf
tc.Conn = turn.NewSTUNConn(conn)
c, err := turn.NewClient(&tc)
require.NoError(t, err)
defer c.Close()
require.NoError(t, c.Listen())
// Allocate a relay socket on the TURN server. On success, it
// will return a net.PacketConn which represents the remote
// socket.
relayConn, err := c.Allocate()
require.NoError(t, err)
defer func() {
require.NoError(t, relayConn.Close())
}()
})
// UDP test doesn't pass
//t.Run("TURN connects over UDP", func(t *testing.T) {
// conn, err := net.ListenPacket("udp4", "0.0.0.0:0")
// require.NoError(t, err)
// defer func() {
// require.NoError(t, conn.Close())
// }()
//
// tc := *turnConf
// tc.Conn = conn
//
// client, err := turn.NewClient(&tc)
// require.NoError(t, err)
// defer client.Close()
//
// // Start listening on the conn provided.
// require.NoError(t, client.Listen())
//
// // Allocate a relay socket on the TURN server. On success, it
// // will return a net.PacketConn which represents the remote
// // socket.
// relayConn, err := client.Allocate()
// require.NoError(t, err)
// defer func() {
// require.NoError(t, relayConn.Close())
// }()
//})
}