diff --git a/cloud.go b/cloud.go index db47727..638ceb5 100644 --- a/cloud.go +++ b/cloud.go @@ -7,13 +7,14 @@ import ( "fmt" "net/http" "net/url" - "github.com/coder/websocket/wsjson" "time" + "github.com/coder/websocket/wsjson" + "github.com/coreos/go-oidc/v3/oidc" - "github.com/gin-gonic/gin" "github.com/coder/websocket" + "github.com/gin-gonic/gin" ) type CloudRegisterRequest struct { @@ -187,7 +188,7 @@ func handleSessionRequest(ctx context.Context, c *websocket.Conn, req WebRTCSess return fmt.Errorf("google identity mismatch") } - session, err := newSession() + session, err := newSession(req.ICEServers, req.IP) if err != nil { _ = wsjson.Write(context.Background(), c, gin.H{"error": err}) return err diff --git a/config.go b/config.go index 1636434..30789ee 100644 --- a/config.go +++ b/config.go @@ -12,16 +12,17 @@ type WakeOnLanDevice struct { } type Config struct { - CloudURL string `json:"cloud_url"` - CloudToken string `json:"cloud_token"` - GoogleIdentity string `json:"google_identity"` - JigglerEnabled bool `json:"jiggler_enabled"` - AutoUpdateEnabled bool `json:"auto_update_enabled"` - IncludePreRelease bool `json:"include_pre_release"` - HashedPassword string `json:"hashed_password"` - LocalAuthToken string `json:"local_auth_token"` - LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration - WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` + CloudURL string `json:"cloud_url"` + CloudToken string `json:"cloud_token"` + GoogleIdentity string `json:"google_identity"` + JigglerEnabled bool `json:"jiggler_enabled"` + AutoUpdateEnabled bool `json:"auto_update_enabled"` + IncludePreRelease bool `json:"include_pre_release"` + HashedPassword string `json:"hashed_password"` + LocalAuthToken string `json:"local_auth_token"` + LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration + WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` + FallbackICEServers []string `json:"fallback_ice_servers"` } const configPath = "/userdata/kvm_config.json" @@ -29,6 +30,11 @@ const configPath = "/userdata/kvm_config.json" var defaultConfig = &Config{ CloudURL: "https://api.jetkvm.com", AutoUpdateEnabled: true, // Set a default value + FallbackICEServers: []string{ + "stun:stun.cloudflare.com:3478", + "stun:stun.cloudflare.com:53", + "stun:stun.l.google.com:19302", + }, } var config *Config diff --git a/web.go b/web.go index 64f8de7..6436b46 100644 --- a/web.go +++ b/web.go @@ -17,8 +17,10 @@ import ( var staticFiles embed.FS type WebRTCSessionRequest struct { - Sd string `json:"sd"` - OidcGoogle string `json:"OidcGoogle,omitempty"` + Sd string `json:"sd"` + OidcGoogle string `json:"OidcGoogle,omitempty"` + IP string `json:"ip,omitempty"` + ICEServers []string `json:"iceServers,omitempty"` } type SetPasswordRequest struct { @@ -116,7 +118,7 @@ func handleWebRTCSession(c *gin.Context) { return } - session, err := newSession() + session, err := newSession(nil, "") if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err}) return diff --git a/webrtc.go b/webrtc.go index 20ffb99..4e79902 100644 --- a/webrtc.go +++ b/webrtc.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "net" "strings" "github.com/pion/webrtc/v4" @@ -61,9 +62,23 @@ func (s *Session) ExchangeOffer(offerStr string) (string, error) { return base64.StdEncoding.EncodeToString(localDescription), nil } -func newSession() (*Session, error) { - peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{ - ICEServers: []webrtc.ICEServer{{}}, +func newSession(iceServers []string, localIP string) (*Session, error) { + if iceServers == nil { + iceServers = config.FallbackICEServers + fmt.Printf("ICE Servers not provided, using fallback %v\n", iceServers) + } + + webrtcSettingEngine := webrtc.SettingEngine{} + if localIP != "" || net.ParseIP(localIP) == nil { + fmt.Printf("Local IP address not provided or invalid, won't set NAT1To1IPs\n") + } else { + webrtcSettingEngine.SetNAT1To1IPs([]string{localIP}, webrtc.ICECandidateTypeSrflx) + } + + // create + api := webrtc.NewAPI(webrtc.WithSettingEngine(webrtcSettingEngine)) + peerConnection, err := api.NewPeerConnection(webrtc.Configuration{ + ICEServers: []webrtc.ICEServer{{URLs: iceServers}}, }) if err != nil { return nil, err