@@ -137,6 +137,7 @@ type Dialer struct {
137
137
closedChan chan struct {}
138
138
connClosers []io.Closer
139
139
connClosersMut sync.Mutex
140
+ pingMut sync.Mutex
140
141
}
141
142
142
143
func (d * Dialer ) negotiate () (err error ) {
@@ -160,7 +161,7 @@ func (d *Dialer) negotiate() (err error) {
160
161
return
161
162
}
162
163
d .rtc .OnConnectionStateChange (func (pcs webrtc.PeerConnectionState ) {
163
- if pcs == webrtc .PeerConnectionStateConnected {
164
+ if pcs != webrtc .PeerConnectionStateDisconnected {
164
165
return
165
166
}
166
167
@@ -178,6 +179,7 @@ func (d *Dialer) negotiate() (err error) {
178
179
default :
179
180
}
180
181
close (d .closedChan )
182
+ _ = d .rtc .Close ()
181
183
})
182
184
}()
183
185
@@ -263,7 +265,7 @@ func (d *Dialer) Ping(ctx context.Context) error {
263
265
// Since we control the client and server we could open this
264
266
// data channel with `Negotiated` true to reduce traffic being
265
267
// sent when the RTC connection is opened.
266
- err := waitForDataChannelOpen (context . Background () , d .ctrl )
268
+ err := waitForDataChannelOpen (ctx , d .ctrl )
267
269
if err != nil {
268
270
return err
269
271
}
@@ -273,13 +275,28 @@ func (d *Dialer) Ping(ctx context.Context) error {
273
275
return err
274
276
}
275
277
}
278
+ d .pingMut .Lock ()
279
+ defer d .pingMut .Unlock ()
276
280
_ , err = d .ctrlrw .Write ([]byte {'a' })
277
281
if err != nil {
278
282
return fmt .Errorf ("write: %w" , err )
279
283
}
280
- b := make ([]byte , 4 )
281
- _ , err = d .ctrlrw .Read (b )
282
- return err
284
+ errCh := make (chan error )
285
+ go func () {
286
+ // There's a race in which connections can get lost-mid ping
287
+ // in which case this would block forever.
288
+ defer close (errCh )
289
+ _ , err = d .ctrlrw .Read (make ([]byte , 4 ))
290
+ errCh <- err
291
+ }()
292
+ ctx , cancelFunc := context .WithTimeout (ctx , time .Second * 15 )
293
+ defer cancelFunc ()
294
+ select {
295
+ case err := <- errCh :
296
+ return err
297
+ case <- ctx .Done ():
298
+ return ctx .Err ()
299
+ }
283
300
}
284
301
285
302
// DialContext dials the network and address on the remote listener.
0 commit comments