iceservers with auth.

This commit is contained in:
Miroslav Šedivý 2021-03-17 15:47:49 +01:00
parent 4abe0a5dba
commit 552223d031
6 changed files with 82 additions and 34 deletions

View File

@ -10,12 +10,13 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
"demodesk/neko/internal/utils" "demodesk/neko/internal/utils"
"demodesk/neko/internal/types"
) )
type WebRTC struct { type WebRTC struct {
ICELite bool ICELite bool
ICETrickle bool ICETrickle bool
ICEServers []string ICEServers []types.ICEServer
EphemeralMin uint16 EphemeralMin uint16
EphemeralMax uint16 EphemeralMax uint16
@ -26,6 +27,7 @@ type WebRTC struct {
const ( const (
defEprMin = 59000 defEprMin = 59000
defEprMax = 59100 defEprMax = 59100
defStun = "stun:stun.l.google.com:19302"
) )
func (WebRTC) Init(cmd *cobra.Command) error { func (WebRTC) Init(cmd *cobra.Command) error {
@ -39,8 +41,8 @@ func (WebRTC) Init(cmd *cobra.Command) error {
return err return err
} }
cmd.PersistentFlags().StringSlice("webrtc.iceserver", []string{"stun:stun.l.google.com:19302"}, "describes a single STUN and TURN server that can be used by the ICEAgent to establish a connection with a peer") cmd.PersistentFlags().String("webrtc.iceservers", "[]", "STUN and TURN servers in JSON format with `urls`, `username`, `password` keys")
if err := viper.BindPFlag("webrtc.iceserver", cmd.PersistentFlags().Lookup("webrtc.iceserver")); err != nil { if err := viper.BindPFlag("webrtc.iceservers", cmd.PersistentFlags().Lookup("webrtc.iceservers")); err != nil {
return err return err
} }
@ -65,7 +67,18 @@ func (WebRTC) Init(cmd *cobra.Command) error {
func (s *WebRTC) Set() { func (s *WebRTC) Set() {
s.ICELite = viper.GetBool("webrtc.icelite") s.ICELite = viper.GetBool("webrtc.icelite")
s.ICETrickle = viper.GetBool("webrtc.icetrickle") s.ICETrickle = viper.GetBool("webrtc.icetrickle")
s.ICEServers = viper.GetStringSlice("webrtc.iceserver")
if err := viper.UnmarshalKey("webrtc.iceservers", &s.ICEServers, viper.DecodeHook(
utils.JsonStringAutoDecode(s.ICEServers),
)); err != nil {
log.Warn().Err(err).Msgf("unable to parse ICE servers")
}
if len(s.ICEServers) == 0 {
s.ICEServers = append(s.ICEServers, types.ICEServer{
URLs: []string{defStun},
})
}
s.NAT1To1IPs = viper.GetStringSlice("webrtc.nat1to1") s.NAT1To1IPs = viper.GetStringSlice("webrtc.nat1to1")
s.IpRetrievalUrl = viper.GetString("webrtc.ip_retrieval_url") s.IpRetrievalUrl = viper.GetString("webrtc.ip_retrieval_url")

View File

@ -42,8 +42,7 @@ type SystemDisconnect struct {
type SignalProvide struct { type SignalProvide struct {
Event string `json:"event,omitempty"` Event string `json:"event,omitempty"`
SDP string `json:"sdp"` SDP string `json:"sdp"`
Lite bool `json:"lite"` ICEServers []types.ICEServer `json:"iceservers"`
ICE []string `json:"ice"`
Videos []string `json:"videos"` Videos []string `json:"videos"`
Video string `json:"video"` Video string `json:"video"`
} }

View File

@ -2,6 +2,12 @@ package types
import "github.com/pion/webrtc/v3" import "github.com/pion/webrtc/v3"
type ICEServer struct {
URLs []string `mapstructure:"urls" json:"urls"`
Username string `mapstructure:"username" json:"username"`
Credential string `mapstructure:"credential" json:"credential"`
}
type WebRTCPeer interface { type WebRTCPeer interface {
SignalAnswer(sdp string) error SignalAnswer(sdp string) error
SignalCandidate(candidate webrtc.ICECandidateInit) error SignalCandidate(candidate webrtc.ICECandidateInit) error
@ -17,8 +23,7 @@ type WebRTCManager interface {
Start() Start()
Shutdown() error Shutdown() error
ICELite() bool ICEServers() []ICEServer
ICEServers() []string
CreatePeer(session Session, videoID string) (*webrtc.SessionDescription, error) CreatePeer(session Session, videoID string) (*webrtc.SessionDescription, error)
} }

View File

@ -1,6 +1,9 @@
package utils package utils
import "encoding/json" import (
"encoding/json"
"reflect"
)
func Unmarshal(in interface{}, raw []byte, callback func() error) error { func Unmarshal(in interface{}, raw []byte, callback func() error) error {
if err := json.Unmarshal(raw, &in); err != nil { if err := json.Unmarshal(raw, &in); err != nil {
@ -8,3 +11,19 @@ func Unmarshal(in interface{}, raw []byte, callback func() error) error {
} }
return callback() return callback()
} }
func JsonStringAutoDecode(m interface{}) func(rf reflect.Kind, rt reflect.Kind, data interface{}) (interface{}, error) {
return func(rf reflect.Kind, rt reflect.Kind, data interface{}) (interface{}, error) {
if rf != reflect.String || rt == reflect.String {
return data, nil
}
raw := data.(string)
if raw != "" && (raw[0:1] == "{" || raw[0:1] == "[") {
err := json.Unmarshal([]byte(raw), &m)
return m, err
}
return data, nil
}
}

View File

@ -77,12 +77,17 @@ func (manager *WebRTCManagerCtx) Start() {
audio.RemoveListener(&audioListener) audio.RemoveListener(&audioListener)
} }
var servers []string
for _, server := range manager.config.ICEServers {
servers = append(servers, server.URLs...)
}
manager.logger.Info(). manager.logger.Info().
Str("ice_lite", fmt.Sprintf("%t", manager.config.ICELite)). Str("icelite", fmt.Sprintf("%t", manager.config.ICELite)).
Str("ice_trickle", fmt.Sprintf("%t", manager.config.ICETrickle)). Str("icetrickle", fmt.Sprintf("%t", manager.config.ICETrickle)).
Str("ice_servers", strings.Join(manager.config.ICEServers, ",")). Str("iceservers", strings.Join(servers, ",")).
Str("ephemeral_port_range", fmt.Sprintf("%d-%d", manager.config.EphemeralMin, manager.config.EphemeralMax)). Str("nat1to1", strings.Join(manager.config.NAT1To1IPs, ",")).
Str("nat_ips", strings.Join(manager.config.NAT1To1IPs, ",")). Str("epr", fmt.Sprintf("%d-%d", manager.config.EphemeralMin, manager.config.EphemeralMax)).
Msgf("webrtc starting") Msgf("webrtc starting")
manager.curImage.Start() manager.curImage.Start()
@ -98,11 +103,7 @@ func (manager *WebRTCManagerCtx) Shutdown() error {
return nil return nil
} }
func (manager *WebRTCManagerCtx) ICELite() bool { func (manager *WebRTCManagerCtx) ICEServers() []types.ICEServer {
return manager.config.ICELite
}
func (manager *WebRTCManagerCtx) ICEServers() []string {
return manager.config.ICEServers return manager.config.ICEServers
} }
@ -423,12 +424,24 @@ func (manager *WebRTCManagerCtx) apiConfiguration() *webrtc.Configuration {
} }
} }
ICEServers := []webrtc.ICEServer{}
for _, server := range manager.config.ICEServers {
var credential interface{}
if server.Credential != "" {
credential = server.Credential
} else {
credential = false
}
ICEServers = append(ICEServers, webrtc.ICEServer{
URLs: server.URLs,
Username: server.Username,
Credential: credential,
})
}
return &webrtc.Configuration{ return &webrtc.Configuration{
ICEServers: []webrtc.ICEServer{ ICEServers: ICEServers,
{
URLs: manager.config.ICEServers,
},
},
SDPSemantics: webrtc.SDPSemanticsUnifiedPlanWithFallback, SDPSemantics: webrtc.SDPSemanticsUnifiedPlanWithFallback,
} }
} }

View File

@ -24,8 +24,7 @@ func (h *MessageHandlerCtx) signalRequest(session types.Session) error {
message.SignalProvide{ message.SignalProvide{
Event: event.SIGNAL_PROVIDE, Event: event.SIGNAL_PROVIDE,
SDP: offer.SDP, SDP: offer.SDP,
Lite: h.webrtc.ICELite(), ICEServers: h.webrtc.ICEServers(),
ICE: h.webrtc.ICEServers(),
Videos: videos, Videos: videos,
Video: defaultVideo, Video: defaultVideo,
}) })