diff --git a/internal/config/webrtc.go b/internal/config/webrtc.go index f8419d5f..616081e2 100644 --- a/internal/config/webrtc.go +++ b/internal/config/webrtc.go @@ -1,9 +1,11 @@ package config import ( + "fmt" "strconv" "strings" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -16,32 +18,44 @@ type WebRTC struct { ICEServers []string EphemeralMin uint16 EphemeralMax uint16 - NAT1To1IPs []string + + NAT1To1IPs []string + IpRetrievalUrl string } +const ( + defEprMin = 59000 + defEprMax = 59100 +) + func (WebRTC) Init(cmd *cobra.Command) error { - cmd.PersistentFlags().String("epr", "59000-59100", "limits the pool of ephemeral ports that ICE UDP connections can allocate from") - if err := viper.BindPFlag("epr", cmd.PersistentFlags().Lookup("epr")); err != nil { - return err - } - - cmd.PersistentFlags().StringSlice("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("nat1to1", cmd.PersistentFlags().Lookup("nat1to1")); err != nil { - return err - } - cmd.PersistentFlags().Bool("icelite", false, "configures whether or not the ice agent should be a lite agent") if err := viper.BindPFlag("icelite", cmd.PersistentFlags().Lookup("icelite")); err != nil { return err } + cmd.PersistentFlags().Bool("icetrickle", true, "configures whether cadidates should be sent asynchronously using Trickle ICE") + if err := viper.BindPFlag("icetrickle", cmd.PersistentFlags().Lookup("icetrickle")); err != nil { + return err + } + cmd.PersistentFlags().StringSlice("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") if err := viper.BindPFlag("iceserver", cmd.PersistentFlags().Lookup("iceserver")); err != nil { return err } - cmd.PersistentFlags().Bool("icetrickle", true, "configures whether cadidates should be sent asynchronously using Trickle ICE") - if err := viper.BindPFlag("icetrickle", cmd.PersistentFlags().Lookup("icetrickle")); err != nil { + cmd.PersistentFlags().StringSlice("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("nat1to1", cmd.PersistentFlags().Lookup("nat1to1")); err != nil { + return err + } + + cmd.PersistentFlags().String("ip_retrieval_url", "https://checkip.amazonaws.com", "URL address used for retrieval of the external IP address") + if err := viper.BindPFlag("ip_retrieval_url", cmd.PersistentFlags().Lookup("ip_retrieval_url")); err != nil { + return err + } + + cmd.PersistentFlags().String("epr", fmt.Sprintf("%d-%d", defEprMin, defEprMax), "limits the pool of ephemeral ports that ICE UDP connections can allocate from") + if err := viper.BindPFlag("epr", cmd.PersistentFlags().Lookup("epr")); err != nil { return err } @@ -52,17 +66,21 @@ func (s *WebRTC) Set() { s.ICELite = viper.GetBool("icelite") s.ICETrickle = viper.GetBool("icetrickle") s.ICEServers = viper.GetStringSlice("iceserver") - s.NAT1To1IPs = viper.GetStringSlice("nat1to1") - if len(s.NAT1To1IPs) == 0 { - ip, err := utils.GetIP() + s.NAT1To1IPs = viper.GetStringSlice("nat1to1") + s.IpRetrievalUrl = viper.GetString("ip_retrieval_url") + if s.IpRetrievalUrl != "" && len(s.NAT1To1IPs) == 0 { + ip, err := utils.HttpRequestGET(s.IpRetrievalUrl) if err == nil { s.NAT1To1IPs = append(s.NAT1To1IPs, ip) + } else { + log.Warn().Err(err).Msgf("IP retrieval failed") } } - min := uint16(59000) - max := uint16(59100) + min := uint16(defEprMin) + max := uint16(defEprMax) + epr := viper.GetString("epr") ports := strings.SplitN(epr, "-", -1) if len(ports) > 1 { diff --git a/internal/utils/ip.go b/internal/utils/ip.go deleted file mode 100644 index 67c7d38d..00000000 --- a/internal/utils/ip.go +++ /dev/null @@ -1,35 +0,0 @@ -package utils - -import ( - "bytes" - "io/ioutil" - "net/http" -) - -// dig @resolver1.opendns.com ANY myip.opendns.com +short -4 - -func GetIP() (string, error) { - rsp, err := http.Get("http://checkip.amazonaws.com") - if err != nil { - return "", err - } - defer rsp.Body.Close() - - buf, err := ioutil.ReadAll(rsp.Body) - if err != nil { - return "", err - } - - return string(bytes.TrimSpace(buf)), nil -} - -func ReadUserIP(r *http.Request) string { - IPAddress := r.Header.Get("X-Real-Ip") - if IPAddress == "" { - IPAddress = r.Header.Get("X-Forwarded-For") - } - if IPAddress == "" { - IPAddress = r.RemoteAddr - } - return IPAddress -} diff --git a/internal/utils/request.go b/internal/utils/request.go new file mode 100644 index 00000000..9ba77b01 --- /dev/null +++ b/internal/utils/request.go @@ -0,0 +1,22 @@ +package utils + +import ( + "bytes" + "io/ioutil" + "net/http" +) + +func HttpRequestGET(url string) (string, error) { + rsp, err := http.Get(url) + if err != nil { + return "", err + } + defer rsp.Body.Close() + + buf, err := ioutil.ReadAll(rsp.Body) + if err != nil { + return "", err + } + + return string(bytes.TrimSpace(buf)), nil +}