Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 714c366

Browse files
authored
chore: Remove WebRTC networking (#3881)
* chore: Remove WebRTC networking * Fix race condition * Fix WebSocket not closing
1 parent 1186e64 commit 714c366

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+315
-4230
lines changed

Makefile

+1-10
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ lint/shellcheck: $(shell shfmt -f .)
386386
gen: \
387387
coderd/database/dump.sql \
388388
coderd/database/querier.go \
389-
peerbroker/proto/peerbroker.pb.go \
390389
provisionersdk/proto/provisioner.pb.go \
391390
provisionerd/proto/provisionerd.pb.go \
392391
site/src/api/typesGenerated.ts
@@ -395,7 +394,7 @@ gen: \
395394
# Mark all generated files as fresh so make thinks they're up-to-date. This is
396395
# used during releases so we don't run generation scripts.
397396
gen/mark-fresh:
398-
files="coderd/database/dump.sql coderd/database/querier.go peerbroker/proto/peerbroker.pb.go provisionersdk/proto/provisioner.pb.go provisionerd/proto/provisionerd.pb.go site/src/api/typesGenerated.ts"
397+
files="coderd/database/dump.sql coderd/database/querier.go provisionersdk/proto/provisioner.pb.go provisionerd/proto/provisionerd.pb.go site/src/api/typesGenerated.ts"
399398
for file in $$files; do
400399
echo "$$file"
401400
if [ ! -f "$$file" ]; then
@@ -417,14 +416,6 @@ coderd/database/dump.sql: coderd/database/gen/dump/main.go $(wildcard coderd/dat
417416
coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $(wildcard coderd/database/queries/*.sql) coderd/database/gen/enum/main.go
418417
./coderd/database/generate.sh
419418

420-
peerbroker/proto/peerbroker.pb.go: peerbroker/proto/peerbroker.proto
421-
protoc \
422-
--go_out=. \
423-
--go_opt=paths=source_relative \
424-
--go-drpc_out=. \
425-
--go-drpc_opt=paths=source_relative \
426-
./peerbroker/proto/peerbroker.proto
427-
428419
provisionersdk/proto/provisioner.pb.go: provisionersdk/proto/provisioner.proto
429420
protoc \
430421
--go_out=. \

agent/agent.go

+1-187
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"io"
1212
"net"
1313
"net/netip"
14-
"net/url"
1514
"os"
1615
"os/exec"
1716
"os/user"
@@ -34,8 +33,6 @@ import (
3433

3534
"cdr.dev/slog"
3635
"github.com/coder/coder/agent/usershell"
37-
"github.com/coder/coder/peer"
38-
"github.com/coder/coder/peerbroker"
3936
"github.com/coder/coder/pty"
4037
"github.com/coder/coder/tailnet"
4138
"github.com/coder/retry"
@@ -64,7 +61,6 @@ var (
6461

6562
type Options struct {
6663
CoordinatorDialer CoordinatorDialer
67-
WebRTCDialer WebRTCDialer
6864
FetchMetadata FetchMetadata
6965

7066
StatsReporter StatsReporter
@@ -80,8 +76,6 @@ type Metadata struct {
8076
Directory string `json:"directory"`
8177
}
8278

83-
type WebRTCDialer func(ctx context.Context, logger slog.Logger) (*peerbroker.Listener, error)
84-
8579
// CoordinatorDialer is a function that constructs a new broker.
8680
// A dialer must be passed in to allow for reconnects.
8781
type CoordinatorDialer func(ctx context.Context) (net.Conn, error)
@@ -95,7 +89,6 @@ func New(options Options) io.Closer {
9589
}
9690
ctx, cancelFunc := context.WithCancel(context.Background())
9791
server := &agent{
98-
webrtcDialer: options.WebRTCDialer,
9992
reconnectingPTYTimeout: options.ReconnectingPTYTimeout,
10093
logger: options.Logger,
10194
closeCancel: cancelFunc,
@@ -111,8 +104,7 @@ func New(options Options) io.Closer {
111104
}
112105

113106
type agent struct {
114-
webrtcDialer WebRTCDialer
115-
logger slog.Logger
107+
logger slog.Logger
116108

117109
reconnectingPTYs sync.Map
118110
reconnectingPTYTimeout time.Duration
@@ -173,9 +165,6 @@ func (a *agent) run(ctx context.Context) {
173165
}
174166
}()
175167

176-
if a.webrtcDialer != nil {
177-
go a.runWebRTCNetworking(ctx)
178-
}
179168
if metadata.DERPMap != nil {
180169
go a.runTailnet(ctx, metadata.DERPMap)
181170
}
@@ -326,49 +315,6 @@ func (a *agent) runCoordinator(ctx context.Context) {
326315
}
327316
}
328317

329-
func (a *agent) runWebRTCNetworking(ctx context.Context) {
330-
var peerListener *peerbroker.Listener
331-
var err error
332-
// An exponential back-off occurs when the connection is failing to dial.
333-
// This is to prevent server spam in case of a coderd outage.
334-
for retrier := retry.New(50*time.Millisecond, 10*time.Second); retrier.Wait(ctx); {
335-
peerListener, err = a.webrtcDialer(ctx, a.logger)
336-
if err != nil {
337-
if errors.Is(err, context.Canceled) {
338-
return
339-
}
340-
if a.isClosed() {
341-
return
342-
}
343-
a.logger.Warn(context.Background(), "failed to dial", slog.Error(err))
344-
continue
345-
}
346-
a.logger.Info(context.Background(), "connected to webrtc broker")
347-
break
348-
}
349-
select {
350-
case <-ctx.Done():
351-
return
352-
default:
353-
}
354-
355-
for {
356-
conn, err := peerListener.Accept()
357-
if err != nil {
358-
if a.isClosed() {
359-
return
360-
}
361-
a.logger.Debug(ctx, "peer listener accept exited; restarting connection", slog.Error(err))
362-
a.runWebRTCNetworking(ctx)
363-
return
364-
}
365-
a.closeMutex.Lock()
366-
a.connCloseWait.Add(1)
367-
a.closeMutex.Unlock()
368-
go a.handlePeerConn(ctx, conn)
369-
}
370-
}
371-
372318
func (a *agent) runStartupScript(ctx context.Context, script string) error {
373319
if script == "" {
374320
return nil
@@ -401,74 +347,6 @@ func (a *agent) runStartupScript(ctx context.Context, script string) error {
401347
return nil
402348
}
403349

404-
func (a *agent) handlePeerConn(ctx context.Context, peerConn *peer.Conn) {
405-
go func() {
406-
select {
407-
case <-a.closed:
408-
case <-peerConn.Closed():
409-
}
410-
_ = peerConn.Close()
411-
a.connCloseWait.Done()
412-
}()
413-
for {
414-
channel, err := peerConn.Accept(ctx)
415-
if err != nil {
416-
if errors.Is(err, peer.ErrClosed) || a.isClosed() {
417-
return
418-
}
419-
a.logger.Debug(ctx, "accept channel from peer connection", slog.Error(err))
420-
return
421-
}
422-
423-
conn := channel.NetConn()
424-
425-
switch channel.Protocol() {
426-
case ProtocolSSH:
427-
go a.sshServer.HandleConn(a.stats.wrapConn(conn))
428-
case ProtocolReconnectingPTY:
429-
rawID := channel.Label()
430-
// The ID format is referenced in conn.go.
431-
// <uuid>:<height>:<width>
432-
idParts := strings.SplitN(rawID, ":", 4)
433-
if len(idParts) != 4 {
434-
a.logger.Warn(ctx, "client sent invalid id format", slog.F("raw-id", rawID))
435-
continue
436-
}
437-
id := idParts[0]
438-
// Enforce a consistent format for IDs.
439-
_, err := uuid.Parse(id)
440-
if err != nil {
441-
a.logger.Warn(ctx, "client sent reconnection token that isn't a uuid", slog.F("id", id), slog.Error(err))
442-
continue
443-
}
444-
// Parse the initial terminal dimensions.
445-
height, err := strconv.Atoi(idParts[1])
446-
if err != nil {
447-
a.logger.Warn(ctx, "client sent invalid height", slog.F("id", id), slog.F("height", idParts[1]))
448-
continue
449-
}
450-
width, err := strconv.Atoi(idParts[2])
451-
if err != nil {
452-
a.logger.Warn(ctx, "client sent invalid width", slog.F("id", id), slog.F("width", idParts[2]))
453-
continue
454-
}
455-
go a.handleReconnectingPTY(ctx, reconnectingPTYInit{
456-
ID: id,
457-
Height: uint16(height),
458-
Width: uint16(width),
459-
Command: idParts[3],
460-
}, a.stats.wrapConn(conn))
461-
case ProtocolDial:
462-
go a.handleDial(ctx, channel.Label(), a.stats.wrapConn(conn))
463-
default:
464-
a.logger.Warn(ctx, "unhandled protocol from channel",
465-
slog.F("protocol", channel.Protocol()),
466-
slog.F("label", channel.Label()),
467-
)
468-
}
469-
}
470-
}
471-
472350
func (a *agent) init(ctx context.Context) {
473351
a.logger.Info(ctx, "generating host key")
474352
// Clients' should ignore the host key when connecting.
@@ -915,70 +793,6 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, msg reconnectingPTYIn
915793
}
916794
}
917795

918-
// dialResponse is written to datachannels with protocol "dial" by the agent as
919-
// the first packet to signify whether the dial succeeded or failed.
920-
type dialResponse struct {
921-
Error string `json:"error,omitempty"`
922-
}
923-
924-
func (a *agent) handleDial(ctx context.Context, label string, conn net.Conn) {
925-
defer conn.Close()
926-
927-
writeError := func(responseError error) error {
928-
msg := ""
929-
if responseError != nil {
930-
msg = responseError.Error()
931-
if !xerrors.Is(responseError, io.EOF) {
932-
a.logger.Warn(ctx, "handle dial", slog.F("label", label), slog.Error(responseError))
933-
}
934-
}
935-
b, err := json.Marshal(dialResponse{
936-
Error: msg,
937-
})
938-
if err != nil {
939-
a.logger.Warn(ctx, "write dial response", slog.F("label", label), slog.Error(err))
940-
return xerrors.Errorf("marshal agent webrtc dial response: %w", err)
941-
}
942-
943-
_, err = conn.Write(b)
944-
return err
945-
}
946-
947-
u, err := url.Parse(label)
948-
if err != nil {
949-
_ = writeError(xerrors.Errorf("parse URL %q: %w", label, err))
950-
return
951-
}
952-
953-
network := u.Scheme
954-
addr := u.Host + u.Path
955-
if strings.HasPrefix(network, "unix") {
956-
if runtime.GOOS == "windows" {
957-
_ = writeError(xerrors.New("Unix forwarding is not supported from Windows workspaces"))
958-
return
959-
}
960-
addr, err = ExpandRelativeHomePath(addr)
961-
if err != nil {
962-
_ = writeError(xerrors.Errorf("expand path %q: %w", addr, err))
963-
return
964-
}
965-
}
966-
967-
d := net.Dialer{Timeout: 3 * time.Second}
968-
nconn, err := d.DialContext(ctx, network, addr)
969-
if err != nil {
970-
_ = writeError(xerrors.Errorf("dial '%v://%v': %w", network, addr, err))
971-
return
972-
}
973-
974-
err = writeError(nil)
975-
if err != nil {
976-
return
977-
}
978-
979-
Bicopy(ctx, conn, nconn)
980-
}
981-
982796
// isClosed returns whether the API is closed or not.
983797
func (a *agent) isClosed() bool {
984798
select {

0 commit comments

Comments
 (0)