mirror of https://github.com/jetkvm/kvm.git
feat: add ICE servers and local IP address returned by the API to fix connectivity issues behind NAT
This commit is contained in:
parent
8ffe66a1bc
commit
92e0a06dee
7
cloud.go
7
cloud.go
|
@ -7,13 +7,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"github.com/coder/websocket/wsjson"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/coder/websocket/wsjson"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/coder/websocket"
|
"github.com/coder/websocket"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CloudRegisterRequest struct {
|
type CloudRegisterRequest struct {
|
||||||
|
@ -187,7 +188,7 @@ func handleSessionRequest(ctx context.Context, c *websocket.Conn, req WebRTCSess
|
||||||
return fmt.Errorf("google identity mismatch")
|
return fmt.Errorf("google identity mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := newSession()
|
session, err := newSession(req.ICEServers, req.IP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = wsjson.Write(context.Background(), c, gin.H{"error": err})
|
_ = wsjson.Write(context.Background(), c, gin.H{"error": err})
|
||||||
return err
|
return err
|
||||||
|
|
26
config.go
26
config.go
|
@ -12,16 +12,17 @@ type WakeOnLanDevice struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CloudURL string `json:"cloud_url"`
|
CloudURL string `json:"cloud_url"`
|
||||||
CloudToken string `json:"cloud_token"`
|
CloudToken string `json:"cloud_token"`
|
||||||
GoogleIdentity string `json:"google_identity"`
|
GoogleIdentity string `json:"google_identity"`
|
||||||
JigglerEnabled bool `json:"jiggler_enabled"`
|
JigglerEnabled bool `json:"jiggler_enabled"`
|
||||||
AutoUpdateEnabled bool `json:"auto_update_enabled"`
|
AutoUpdateEnabled bool `json:"auto_update_enabled"`
|
||||||
IncludePreRelease bool `json:"include_pre_release"`
|
IncludePreRelease bool `json:"include_pre_release"`
|
||||||
HashedPassword string `json:"hashed_password"`
|
HashedPassword string `json:"hashed_password"`
|
||||||
LocalAuthToken string `json:"local_auth_token"`
|
LocalAuthToken string `json:"local_auth_token"`
|
||||||
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
|
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
|
||||||
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
|
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
|
||||||
|
FallbackICEServers []string `json:"fallback_ice_servers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const configPath = "/userdata/kvm_config.json"
|
const configPath = "/userdata/kvm_config.json"
|
||||||
|
@ -29,6 +30,11 @@ const configPath = "/userdata/kvm_config.json"
|
||||||
var defaultConfig = &Config{
|
var defaultConfig = &Config{
|
||||||
CloudURL: "https://api.jetkvm.com",
|
CloudURL: "https://api.jetkvm.com",
|
||||||
AutoUpdateEnabled: true, // Set a default value
|
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
|
var config *Config
|
||||||
|
|
8
web.go
8
web.go
|
@ -17,8 +17,10 @@ import (
|
||||||
var staticFiles embed.FS
|
var staticFiles embed.FS
|
||||||
|
|
||||||
type WebRTCSessionRequest struct {
|
type WebRTCSessionRequest struct {
|
||||||
Sd string `json:"sd"`
|
Sd string `json:"sd"`
|
||||||
OidcGoogle string `json:"OidcGoogle,omitempty"`
|
OidcGoogle string `json:"OidcGoogle,omitempty"`
|
||||||
|
IP string `json:"ip,omitempty"`
|
||||||
|
ICEServers []string `json:"iceServers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetPasswordRequest struct {
|
type SetPasswordRequest struct {
|
||||||
|
@ -116,7 +118,7 @@ func handleWebRTCSession(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := newSession()
|
session, err := newSession(nil, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
|
||||||
return
|
return
|
||||||
|
|
21
webrtc.go
21
webrtc.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pion/webrtc/v4"
|
"github.com/pion/webrtc/v4"
|
||||||
|
@ -61,9 +62,23 @@ func (s *Session) ExchangeOffer(offerStr string) (string, error) {
|
||||||
return base64.StdEncoding.EncodeToString(localDescription), nil
|
return base64.StdEncoding.EncodeToString(localDescription), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSession() (*Session, error) {
|
func newSession(iceServers []string, localIP string) (*Session, error) {
|
||||||
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
|
if iceServers == nil {
|
||||||
ICEServers: []webrtc.ICEServer{{}},
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue