Skip to content

Commit 1357c1e

Browse files
committed
Allow cancelling TURN Allocate phase, which can block for ~7.8s if TURN server is not responding.
1 parent 753c2a0 commit 1357c1e

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

gather.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,17 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) {
836836
return
837837
}
838838

839+
allocDoneCh := make(chan struct{})
840+
go func() {
841+
select {
842+
case <-ctx.Done():
843+
client.Close()
844+
case <-allocDoneCh:
845+
}
846+
}()
847+
839848
relayConn, err := client.Allocate()
849+
close(allocDoneCh)
840850
if err != nil {
841851
client.Close()
842852
closeConnAndLog(locConn, a.log, "failed to allocate on TURN client %s %s", turnServerAddr, err)

gather_vnet_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"net"
1313
"testing"
14+
"time"
1415

1516
"github.com/pion/logging"
1617
"github.com/pion/stun/v3"
@@ -435,3 +436,49 @@ func TestVNetGather_TURNConnectionLeak(t *testing.T) {
435436

436437
aAgent.gatherCandidatesRelay(context.Background(), []*stun.URI{turnServerURL})
437438
}
439+
440+
func TestVNetGather_TURNAllocationAbort(t *testing.T) {
441+
defer test.CheckRoutines(t)()
442+
443+
// configure unreachable TURN server
444+
turnServerURL := &stun.URI{
445+
Scheme: stun.SchemeTypeTURN,
446+
Host: vnetSTUNServerIP,
447+
Port: vnetSTUNServerPort,
448+
Username: "user",
449+
Password: "pass",
450+
Proto: stun.ProtoTypeUDP,
451+
}
452+
453+
loggerFactory := logging.NewDefaultLoggerFactory()
454+
router, err := vnet.NewRouter(&vnet.RouterConfig{
455+
CIDR: "10.0.0.0/24",
456+
LoggerFactory: loggerFactory,
457+
})
458+
459+
nw, err := vnet.NewNet(&vnet.NetConfig{})
460+
require.NoError(t, err)
461+
require.NoError(t, router.AddNet(nw))
462+
463+
cfg0 := &AgentConfig{
464+
Urls: []*stun.URI{
465+
turnServerURL,
466+
},
467+
NetworkTypes: supportedNetworkTypes(),
468+
MulticastDNSMode: MulticastDNSModeDisabled,
469+
Net: nw,
470+
}
471+
aAgent, err := NewAgent(cfg0)
472+
require.NoError(t, err, "should succeed")
473+
defer func() {
474+
require.NoError(t, aAgent.Close())
475+
}()
476+
477+
// if not cancelled, gatherCandidatesRelay() will block for ~7.8s
478+
defer test.TimeOut(time.Second * 1).Stop()
479+
480+
ctx, cancelFunc := context.WithTimeout(context.Background(), 500*time.Millisecond)
481+
defer cancelFunc()
482+
483+
aAgent.gatherCandidatesRelay(ctx, []*stun.URI{turnServerURL})
484+
}

0 commit comments

Comments
 (0)