From ac0633260e7bc7c897a8cd122a4b8165260cfde1 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 20:17:05 +0000 Subject: [PATCH 1/6] fix: Add context to negotiate RTC func --- wsnet/dial.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/wsnet/dial.go b/wsnet/dial.go index 394e6a9f..6ed33bcb 100644 --- a/wsnet/dial.go +++ b/wsnet/dial.go @@ -52,11 +52,11 @@ func DialWebsocket(ctx context.Context, broker string, netOpts *DialOptions, wsO // We should close the socket intentionally. _ = conn.Close(websocket.StatusInternalError, "an error occurred") }() - return Dial(nconn, netOpts) + return Dial(ctx, nconn, netOpts) } // Dial negotiates a connection to a listener. -func Dial(conn net.Conn, options *DialOptions) (*Dialer, error) { +func Dial(ctx context.Context, conn net.Conn, options *DialOptions) (*Dialer, error) { if options == nil { options = &DialOptions{} } @@ -121,7 +121,7 @@ func Dial(conn net.Conn, options *DialOptions) (*Dialer, error) { connClosers: []io.Closer{ctrl}, } - return dialer, dialer.negotiate() + return dialer, dialer.negotiate(ctx) } // Dialer enables arbitrary dialing to any network and address @@ -138,7 +138,7 @@ type Dialer struct { pingMut sync.Mutex } -func (d *Dialer) negotiate() (err error) { +func (d *Dialer) negotiate(ctx context.Context) (err error) { var ( decoder = json.NewDecoder(d.conn) errCh = make(chan error) @@ -173,6 +173,19 @@ func (d *Dialer) negotiate() (err error) { }) }() + go func() { + // If a connection is opened but the other end may not be, negotiation + // can get stuck forever. We don't want this, so we must listen to the + // context as well. + <-ctx.Done() + select { + case <-errCh: + default: + errCh <- ctx.Err() + close(errCh) + } + }() + for { var msg BrokerMessage err = decoder.Decode(&msg) From 128a4dc76bb0ea114ac7add25c5fcecce67646ad Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 20:36:05 +0000 Subject: [PATCH 2/6] Wait for connection open with proper context --- wsnet/dial.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/wsnet/dial.go b/wsnet/dial.go index 6ed33bcb..d6f45461 100644 --- a/wsnet/dial.go +++ b/wsnet/dial.go @@ -153,7 +153,7 @@ func (d *Dialer) negotiate(ctx context.Context) (err error) { defer func() { _ = d.conn.Close() }() - err := waitForConnectionOpen(context.Background(), d.rtc) + err := waitForConnectionOpen(ctx, d.rtc) if err != nil { errCh <- err return @@ -173,19 +173,6 @@ func (d *Dialer) negotiate(ctx context.Context) (err error) { }) }() - go func() { - // If a connection is opened but the other end may not be, negotiation - // can get stuck forever. We don't want this, so we must listen to the - // context as well. - <-ctx.Done() - select { - case <-errCh: - default: - errCh <- ctx.Err() - close(errCh) - } - }() - for { var msg BrokerMessage err = decoder.Decode(&msg) From 6c60541e0988f11029fb3859268d396ee0798de4 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 20:37:37 +0000 Subject: [PATCH 3/6] Add deadline if doesn't exist --- wsnet/rtc.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wsnet/rtc.go b/wsnet/rtc.go index 0b93c57c..e8280969 100644 --- a/wsnet/rtc.go +++ b/wsnet/rtc.go @@ -242,7 +242,10 @@ func waitForConnectionOpen(ctx context.Context, conn *webrtc.PeerConnection) err if conn.ConnectionState() == webrtc.PeerConnectionStateConnected { return nil } - ctx, cancelFunc := context.WithTimeout(ctx, time.Second*15) + ctx, cancelFunc := context.WithCancel(ctx) + if _, deadlineSet := ctx.Deadline(); !deadlineSet { + ctx, cancelFunc = context.WithTimeout(ctx, time.Second*15) + } defer cancelFunc() conn.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { if pcs == webrtc.PeerConnectionStateConnected { From 0760d06c580697b291b275b8299fd82203c52301 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 20:38:24 +0000 Subject: [PATCH 4/6] Defer multiple cancels --- wsnet/rtc.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wsnet/rtc.go b/wsnet/rtc.go index e8280969..38c7073c 100644 --- a/wsnet/rtc.go +++ b/wsnet/rtc.go @@ -243,10 +243,11 @@ func waitForConnectionOpen(ctx context.Context, conn *webrtc.PeerConnection) err return nil } ctx, cancelFunc := context.WithCancel(ctx) + defer cancelFunc() if _, deadlineSet := ctx.Deadline(); !deadlineSet { ctx, cancelFunc = context.WithTimeout(ctx, time.Second*15) + defer cancelFunc() } - defer cancelFunc() conn.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { if pcs == webrtc.PeerConnectionStateConnected { cancelFunc() From b55ed20731bc0397b7f991e6c34f3f55f0c1fc3f Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 14:44:07 -0600 Subject: [PATCH 5/6] Update wsnet/rtc.go Co-authored-by: Dean Sheather --- wsnet/rtc.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/wsnet/rtc.go b/wsnet/rtc.go index 38c7073c..7f0b761b 100644 --- a/wsnet/rtc.go +++ b/wsnet/rtc.go @@ -242,12 +242,13 @@ func waitForConnectionOpen(ctx context.Context, conn *webrtc.PeerConnection) err if conn.ConnectionState() == webrtc.PeerConnectionStateConnected { return nil } - ctx, cancelFunc := context.WithCancel(ctx) - defer cancelFunc() - if _, deadlineSet := ctx.Deadline(); !deadlineSet { - ctx, cancelFunc = context.WithTimeout(ctx, time.Second*15) - defer cancelFunc() + var cancel context.CancelFunc + if _, deadlineSet := ctx.Deadline(); deadlineSet { + ctx, cancel = context.WithCancel(ctx) + } else { + ctx, cancel = context.WithTimeout(ctx, time.Second*15) } + defer cancel() conn.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { if pcs == webrtc.PeerConnectionStateConnected { cancelFunc() From d862c732bbb7f909a785a0833796acf146a5945d Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Wed, 21 Jul 2021 20:46:38 +0000 Subject: [PATCH 6/6] Fix var name --- wsnet/rtc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsnet/rtc.go b/wsnet/rtc.go index 7f0b761b..79702743 100644 --- a/wsnet/rtc.go +++ b/wsnet/rtc.go @@ -251,7 +251,7 @@ func waitForConnectionOpen(ctx context.Context, conn *webrtc.PeerConnection) err defer cancel() conn.OnConnectionStateChange(func(pcs webrtc.PeerConnectionState) { if pcs == webrtc.PeerConnectionStateConnected { - cancelFunc() + cancel() } }) <-ctx.Done()