Fix dial contexts cancelled while connections are still in use

This commit is contained in:
世界
2026-09-20 22:24:38 +08:00
parent 9cf7a7a28a
commit 9be5fcf4e1
10 changed files with 229 additions and 52 deletions
+13 -2
View File
@@ -20,6 +20,7 @@ import (
type slowOpenConn struct {
dialer *tfo.Dialer
ctx context.Context
cancel context.CancelFunc
network string
destination M.Socksaddr
conn atomic.Pointer[net.TCPConn]
@@ -39,9 +40,11 @@ func DialSlowContext(dialer *tfo.Dialer, ctx context.Context, network string, de
return dialer.Dialer.DialContext(ctx, network, destination.AddrString())
}
}
dialCtx, cancel := context.WithCancel(context.WithoutCancel(ctx))
return &slowOpenConn{
dialer: dialer,
ctx: ctx,
ctx: dialCtx,
cancel: cancel,
network: network,
destination: destination,
create: make(chan struct{}),
@@ -86,7 +89,14 @@ func (c *slowOpenConn) Write(b []byte) (n int, err error) {
if err != nil {
c.err = err
} else {
c.conn.Store(conn.(*net.TCPConn))
select {
case <-c.done:
conn.Close()
err = os.ErrClosed
c.err = err
default:
c.conn.Store(conn.(*net.TCPConn))
}
}
n = len(b)
close(c.create)
@@ -96,6 +106,7 @@ func (c *slowOpenConn) Write(b []byte) (n int, err error) {
func (c *slowOpenConn) Close() error {
c.closeOnce.Do(func() {
close(c.done)
c.cancel()
conn := c.conn.Load()
if conn != nil {
conn.Close()