Fix turn client routine leak on close

Clean-up turn connection if task run failed.
This commit is contained in:
Atsushi Watanabe
2020-07-06 15:48:19 +09:00
parent 553df099a0
commit 245c513fed
2 changed files with 52 additions and 2 deletions
+7 -2
View File
@@ -415,11 +415,14 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) {
return locConn.Close()
},
}
candidate, err := NewCandidateRelay(&relayConfig)
if err != nil {
relayConnClose := func() {
if relayConErr := relayConn.Close(); relayConErr != nil {
a.log.Warnf("Failed to close relay %v", relayConErr)
}
}
candidate, err := NewCandidateRelay(&relayConfig)
if err != nil {
relayConnClose()
client.Close()
closeConnAndLog(locConn, a.log, fmt.Sprintf("Failed to create relay candidate: %s %s: %v\n", network, raddr.String(), err))
@@ -427,6 +430,8 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*URL) {
}
if err := a.addCandidate(ctx, candidate, relayConn); err != nil {
relayConnClose()
if closeErr := candidate.close(); closeErr != nil {
a.log.Warnf("Failed to close candidate: %v", closeErr)
}
+45
View File
@@ -3,6 +3,7 @@
package ice
import (
"context"
"fmt"
"net"
"testing"
@@ -412,3 +413,47 @@ func TestVNetGatherWithInterfaceFilter(t *testing.T) {
assert.NoError(t, a.Close())
})
}
func TestVNetGather_TURNConnectionLeak(t *testing.T) {
report := test.CheckRoutines(t)
defer report()
turnServerURL := &URL{
Scheme: SchemeTypeTURN,
Host: vnetSTUNServerIP,
Port: vnetSTUNServerPort,
Username: "user",
Password: "pass",
Proto: ProtoTypeUDP,
}
// buildVNet with a Symmetric NATs for both LANs
natType := &vnet.NATType{
MappingBehavior: vnet.EndpointAddrPortDependent,
FilteringBehavior: vnet.EndpointAddrPortDependent,
}
v, err := buildVNet(natType, natType)
if !assert.NoError(t, err, "should succeed") {
return
}
defer v.close()
cfg0 := &AgentConfig{
Urls: []*URL{
turnServerURL,
},
NetworkTypes: supportedNetworkTypes,
MulticastDNSMode: MulticastDNSModeDisabled,
NAT1To1IPs: []string{vnetGlobalIPA},
Net: v.net0,
}
aAgent, err := NewAgent(cfg0)
if !assert.NoError(t, err, "should succeed") {
return
}
aAgent.gatherCandidatesRelay(context.Background(), []*URL{turnServerURL})
// Assert relay conn leak on close.
assert.NoError(t, aAgent.Close())
}