Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

feat: Use internal TURN server for proxying #322

Merged
merged 3 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: Use internal TURN server for proxying
  • Loading branch information
kylecarbs committed Apr 22, 2021
commit f889e54eccd58c3cb7ada52d7c3a9755abb3ec59
6 changes: 5 additions & 1 deletion agent/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ func (s *stream) processMessage(msg proto.Message) {
}

if msg.Offer != nil {
rtc, err := xwebrtc.NewPeerConnection()
if msg.Servers == nil {
s.fatal(fmt.Errorf("servers must be sent with offer"))
return
}
rtc, err := xwebrtc.NewPeerConnection(msg.Servers)
if err != nil {
s.fatal(fmt.Errorf("create connection: %w", err))
return
Expand Down
29 changes: 20 additions & 9 deletions internal/cmd/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net"
"net/url"
"os"
"strconv"
"time"
Expand Down Expand Up @@ -57,7 +58,7 @@ coder tunnel my-dev 3000 3000
}
baseURL := sdk.BaseURL()

envs, err := sdk.Environments(ctx)
envs, err := getEnvs(ctx, sdk, coder.Me)
if err != nil {
return err
}
Expand All @@ -79,8 +80,8 @@ coder tunnel my-dev 3000 3000
localPort: uint16(localPort),
remotePort: uint16(remotePort),
ctx: context.Background(),
logger: log,
brokerAddr: baseURL.String(),
logger: log.Leveled(slog.LevelDebug),
brokerAddr: baseURL,
token: sdk.Token(),
}

Expand All @@ -98,7 +99,7 @@ coder tunnel my-dev 3000 3000

type client struct {
ctx context.Context
brokerAddr string
brokerAddr url.URL
token string
logger slog.Logger
id string
Expand All @@ -108,8 +109,9 @@ type client struct {
}

func (c *client) start() error {
url := fmt.Sprintf("%s%s%s%s%s", c.brokerAddr, "/api/private/envagent/", c.id, "/connect?session_token=", c.token)
c.logger.Info(c.ctx, "connecting to broker", slog.F("url", url))
url := fmt.Sprintf("%s%s%s%s%s", c.brokerAddr.String(), "/api/private/envagent/", c.id, "/connect?session_token=", c.token)
tcpProxy := fmt.Sprintf("turn:%s:5349?transport=tcp", c.brokerAddr.Host)
c.logger.Info(c.ctx, "connecting to broker", slog.F("url", url), slog.F("tcp-proxy", tcpProxy))

conn, resp, err := websocket.Dial(c.ctx, url, nil)
if err != nil && resp == nil {
Expand All @@ -122,7 +124,15 @@ func (c *client) start() error {
}
nconn := websocket.NetConn(context.Background(), conn, websocket.MessageBinary)

rtc, err := xwebrtc.NewPeerConnection()
// Only enabled under a private feature flag for now,
// so insecure connections are entirely fine to allow.
servers := []webrtc.ICEServer{{
URLs: []string{tcpProxy},
Username: "insecure",
Credential: "pass",
CredentialType: webrtc.ICECredentialTypePassword,
}}
rtc, err := xwebrtc.NewPeerConnection(servers)
if err != nil {
return fmt.Errorf("create connection: %w", err)
}
Expand Down Expand Up @@ -150,16 +160,17 @@ func (c *client) start() error {
if err != nil {
return fmt.Errorf("set local desc: %w", err)
}
flushCandidates()

c.logger.Debug(context.Background(), "writing offer")
b, _ := json.Marshal(&proto.Message{
Offer: &localDesc,
Offer: &localDesc,
Servers: servers,
})
_, err = nconn.Write(b)
if err != nil {
return fmt.Errorf("write offer: %w", err)
}
flushCandidates()

go func() {
err = xwebrtc.WaitForDataChannelOpen(context.Background(), channel)
Expand Down
8 changes: 2 additions & 6 deletions internal/x/xwebrtc/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ import "github.com/pion/webrtc/v3"

// NewPeerConnection creates a new peer connection.
// It uses the Google stun server by default.
func NewPeerConnection() (*webrtc.PeerConnection, error) {
func NewPeerConnection(servers []webrtc.ICEServer) (*webrtc.PeerConnection, error) {
se := webrtc.SettingEngine{}
se.DetachDataChannels()
api := webrtc.NewAPI(webrtc.WithSettingEngine(se))

return api.NewPeerConnection(webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
ICEServers: servers,
})
}
1 change: 1 addition & 0 deletions pkg/proto/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Message struct {
Error string `json:"error"`
Candidate string `json:"candidate"`
Offer *webrtc.SessionDescription `json:"offer"`
Servers []webrtc.ICEServer `json:"servers"`
Answer *webrtc.SessionDescription `json:"answer"`
}

Expand Down