fix: tcp concurrent force close when context done
This commit is contained in:
parent
0d55b28805
commit
f979491013
1 changed files with 32 additions and 28 deletions
|
@ -4,11 +4,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -171,25 +170,31 @@ func dualStackDialContext(ctx context.Context, network, address string, opt *opt
|
||||||
go startRacer(ctx, network+"4", host, opt.direct, false)
|
go startRacer(ctx, network+"4", host, opt.direct, false)
|
||||||
go startRacer(ctx, network+"6", host, opt.direct, true)
|
go startRacer(ctx, network+"6", host, opt.direct, true)
|
||||||
|
|
||||||
for res := range results {
|
count := 2
|
||||||
if res.error == nil {
|
for i := 0; i < count; i++ {
|
||||||
return res.Conn, nil
|
select {
|
||||||
}
|
case res := <-results:
|
||||||
|
if res.error == nil {
|
||||||
if !res.ipv6 {
|
return res.Conn, nil
|
||||||
primary = res
|
|
||||||
} else {
|
|
||||||
fallback = res
|
|
||||||
}
|
|
||||||
|
|
||||||
if primary.done && fallback.done {
|
|
||||||
if primary.resolved {
|
|
||||||
return nil, primary.error
|
|
||||||
} else if fallback.resolved {
|
|
||||||
return nil, fallback.error
|
|
||||||
} else {
|
|
||||||
return nil, primary.error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !res.ipv6 {
|
||||||
|
primary = res
|
||||||
|
} else {
|
||||||
|
fallback = res
|
||||||
|
}
|
||||||
|
|
||||||
|
if primary.done && fallback.done {
|
||||||
|
if primary.resolved {
|
||||||
|
return nil, primary.error
|
||||||
|
} else if fallback.resolved {
|
||||||
|
return nil, fallback.error
|
||||||
|
} else {
|
||||||
|
return nil, primary.error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +230,6 @@ func concurrentDialContext(ctx context.Context, network string, ips []netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make(chan dialResult)
|
results := make(chan dialResult)
|
||||||
|
|
||||||
tcpRacer := func(ctx context.Context, ip netip.Addr) {
|
tcpRacer := func(ctx context.Context, ip netip.Addr) {
|
||||||
result := dialResult{ip: ip}
|
result := dialResult{ip: ip}
|
||||||
|
|
||||||
|
@ -252,13 +256,13 @@ func concurrentDialContext(ctx context.Context, network string, ips []netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
connCount := len(ips)
|
connCount := len(ips)
|
||||||
for res := range results {
|
for i := 0; i < connCount; i++ {
|
||||||
connCount--
|
select {
|
||||||
if res.error == nil {
|
case res := <-results:
|
||||||
return res.Conn, nil
|
if res.error == nil {
|
||||||
}
|
return res.Conn, nil
|
||||||
|
}
|
||||||
if connCount == 0 {
|
case <-ctx.Done():
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue