Skip to content

Commit 0d7efe5

Browse files
authored
feat: add ICE servers and local IP address returned by the API to fix connectivity issues behind NAT (#146)
Add ICE servers and local IP address returned by the API to fix connectivity issues behind NAT
1 parent 15768ee commit 0d7efe5

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

cloud.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import (
77
"fmt"
88
"net/http"
99
"net/url"
10-
"github.com/coder/websocket/wsjson"
1110
"time"
1211

12+
"github.com/coder/websocket/wsjson"
13+
1314
"github.com/coreos/go-oidc/v3/oidc"
1415

15-
"github.com/gin-gonic/gin"
1616
"github.com/coder/websocket"
17+
"github.com/gin-gonic/gin"
1718
)
1819

1920
type CloudRegisterRequest struct {
@@ -192,7 +193,11 @@ func handleSessionRequest(ctx context.Context, c *websocket.Conn, req WebRTCSess
192193
return fmt.Errorf("google identity mismatch")
193194
}
194195

195-
session, err := newSession()
196+
session, err := newSession(SessionConfig{
197+
ICEServers: req.ICEServers,
198+
LocalIP: req.IP,
199+
IsCloud: true,
200+
})
196201
if err != nil {
197202
_ = wsjson.Write(context.Background(), c, gin.H{"error": err})
198203
return err

web.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import (
1717
var staticFiles embed.FS
1818

1919
type WebRTCSessionRequest struct {
20-
Sd string `json:"sd"`
21-
OidcGoogle string `json:"OidcGoogle,omitempty"`
20+
Sd string `json:"sd"`
21+
OidcGoogle string `json:"OidcGoogle,omitempty"`
22+
IP string `json:"ip,omitempty"`
23+
ICEServers []string `json:"iceServers,omitempty"`
2224
}
2325

2426
type SetPasswordRequest struct {
@@ -116,7 +118,7 @@ func handleWebRTCSession(c *gin.Context) {
116118
return
117119
}
118120

119-
session, err := newSession()
121+
session, err := newSession(SessionConfig{})
120122
if err != nil {
121123
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
122124
return

webrtc.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/base64"
55
"encoding/json"
66
"fmt"
7+
"net"
78
"strings"
89

910
"github.com/pion/webrtc/v4"
@@ -19,6 +20,12 @@ type Session struct {
1920
shouldUmountVirtualMedia bool
2021
}
2122

23+
type SessionConfig struct {
24+
ICEServers []string
25+
LocalIP string
26+
IsCloud bool
27+
}
28+
2229
func (s *Session) ExchangeOffer(offerStr string) (string, error) {
2330
b, err := base64.StdEncoding.DecodeString(offerStr)
2431
if err != nil {
@@ -61,9 +68,29 @@ func (s *Session) ExchangeOffer(offerStr string) (string, error) {
6168
return base64.StdEncoding.EncodeToString(localDescription), nil
6269
}
6370

64-
func newSession() (*Session, error) {
65-
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
66-
ICEServers: []webrtc.ICEServer{{}},
71+
func newSession(config SessionConfig) (*Session, error) {
72+
webrtcSettingEngine := webrtc.SettingEngine{}
73+
iceServer := webrtc.ICEServer{}
74+
75+
if config.IsCloud {
76+
if config.ICEServers == nil {
77+
fmt.Printf("ICE Servers not provided by cloud")
78+
} else {
79+
iceServer.URLs = config.ICEServers
80+
fmt.Printf("Using ICE Servers provided by cloud: %v\n", iceServer.URLs)
81+
}
82+
83+
if config.LocalIP == "" || net.ParseIP(config.LocalIP) == nil {
84+
fmt.Printf("Local IP address %v not provided or invalid, won't set NAT1To1IPs\n", config.LocalIP)
85+
} else {
86+
webrtcSettingEngine.SetNAT1To1IPs([]string{config.LocalIP}, webrtc.ICECandidateTypeSrflx)
87+
fmt.Printf("Setting NAT1To1IPs to %s\n", config.LocalIP)
88+
}
89+
}
90+
91+
api := webrtc.NewAPI(webrtc.WithSettingEngine(webrtcSettingEngine))
92+
peerConnection, err := api.NewPeerConnection(webrtc.Configuration{
93+
ICEServers: []webrtc.ICEServer{iceServer},
6794
})
6895
if err != nil {
6996
return nil, err

0 commit comments

Comments
 (0)