neko/internal/config/webrtc.go

139 lines
4.3 KiB
Go
Raw Normal View History

package config
import (
"strconv"
"strings"
2021-03-11 01:15:18 +13:00
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
2021-02-02 11:50:18 +13:00
"gitlab.com/demodesk/neko/server/internal/types"
"gitlab.com/demodesk/neko/server/internal/utils"
)
2021-09-03 07:37:24 +12:00
// default stun server
const defStunSrv = "stun:stun.l.google.com:19302"
type WebRTC struct {
ICELite bool
2021-02-03 09:12:11 +13:00
ICETrickle bool
2021-03-18 03:47:49 +13:00
ICEServers []types.ICEServer
EphemeralMin uint16
EphemeralMax uint16
2022-02-10 09:45:03 +13:00
TCPMux int
UDPMux int
2021-03-11 01:15:18 +13:00
NAT1To1IPs []string
IpRetrievalUrl string
}
func (WebRTC) Init(cmd *cobra.Command) error {
2021-03-17 03:24:58 +13:00
cmd.PersistentFlags().Bool("webrtc.icelite", false, "configures whether or not the ICE agent should be a lite agent")
if err := viper.BindPFlag("webrtc.icelite", cmd.PersistentFlags().Lookup("webrtc.icelite")); err != nil {
return err
}
2021-03-17 03:24:58 +13:00
cmd.PersistentFlags().Bool("webrtc.icetrickle", true, "configures whether cadidates should be sent asynchronously using Trickle ICE")
if err := viper.BindPFlag("webrtc.icetrickle", cmd.PersistentFlags().Lookup("webrtc.icetrickle")); err != nil {
return err
}
2021-03-18 03:47:49 +13:00
cmd.PersistentFlags().String("webrtc.iceservers", "[]", "STUN and TURN servers in JSON format with `urls`, `username`, `password` keys")
if err := viper.BindPFlag("webrtc.iceservers", cmd.PersistentFlags().Lookup("webrtc.iceservers")); err != nil {
return err
}
2022-02-10 09:45:03 +13:00
cmd.PersistentFlags().String("webrtc.epr", "", "limits the pool of ephemeral ports that ICE UDP connections can allocate from")
if err := viper.BindPFlag("webrtc.epr", cmd.PersistentFlags().Lookup("webrtc.epr")); err != nil {
return err
}
cmd.PersistentFlags().Int("webrtc.tcpmux", 0, "single TCP mux port for all peers")
if err := viper.BindPFlag("webrtc.tcpmux", cmd.PersistentFlags().Lookup("webrtc.tcpmux")); err != nil {
return err
}
cmd.PersistentFlags().Int("webrtc.udpmux", 0, "single UDP mux port for all peers, replaces EPR")
if err := viper.BindPFlag("webrtc.udpmux", cmd.PersistentFlags().Lookup("webrtc.udpmux")); err != nil {
return err
}
2021-03-17 03:24:58 +13:00
cmd.PersistentFlags().StringSlice("webrtc.nat1to1", []string{}, "sets a list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP address is used")
if err := viper.BindPFlag("webrtc.nat1to1", cmd.PersistentFlags().Lookup("webrtc.nat1to1")); err != nil {
return err
}
2021-03-17 03:24:58 +13:00
cmd.PersistentFlags().String("webrtc.ip_retrieval_url", "https://checkip.amazonaws.com", "URL address used for retrieval of the external IP address")
if err := viper.BindPFlag("webrtc.ip_retrieval_url", cmd.PersistentFlags().Lookup("webrtc.ip_retrieval_url")); err != nil {
2021-03-11 01:15:18 +13:00
return err
}
return nil
}
func (s *WebRTC) Set() {
2021-03-17 03:24:58 +13:00
s.ICELite = viper.GetBool("webrtc.icelite")
s.ICETrickle = viper.GetBool("webrtc.icetrickle")
2021-03-18 03:47:49 +13:00
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{
2021-09-03 07:37:24 +12:00
URLs: []string{defStunSrv},
2021-03-18 03:47:49 +13:00
})
}
2022-02-10 09:45:03 +13:00
s.TCPMux = viper.GetInt("webrtc.tcpmux")
s.UDPMux = viper.GetInt("webrtc.udpmux")
epr := viper.GetString("webrtc.epr")
if epr != "" {
ports := strings.SplitN(epr, "-", -1)
if len(ports) > 1 {
min, err := strconv.ParseUint(ports[0], 10, 16)
if err != nil {
log.Panic().Err(err).Msgf("unable to parse ephemeral min port")
}
max, err := strconv.ParseUint(ports[1], 10, 16)
if err != nil {
log.Panic().Err(err).Msgf("unable to parse ephemeral max port")
}
s.EphemeralMin = uint16(min)
s.EphemeralMax = uint16(max)
}
if s.EphemeralMin > s.EphemeralMax {
log.Panic().Msgf("ephemeral min port cannot be bigger than max")
}
}
if epr == "" && s.TCPMux == 0 && s.UDPMux == 0 {
// using default epr range
s.EphemeralMin = 59000
s.EphemeralMax = 59100
log.Warn().
Uint16("min", s.EphemeralMin).
Uint16("max", s.EphemeralMax).
Msgf("no TCP, UDP mux or epr specified, using default epr range")
}
2021-03-17 03:24:58 +13:00
s.NAT1To1IPs = viper.GetStringSlice("webrtc.nat1to1")
s.IpRetrievalUrl = viper.GetString("webrtc.ip_retrieval_url")
2021-03-11 01:15:18 +13:00
if s.IpRetrievalUrl != "" && len(s.NAT1To1IPs) == 0 {
ip, err := utils.HttpRequestGET(s.IpRetrievalUrl)
if err == nil {
s.NAT1To1IPs = append(s.NAT1To1IPs, ip)
2021-03-11 01:15:18 +13:00
} else {
log.Warn().Err(err).Msgf("IP retrieval failed")
}
}
}