diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 3310a062..2063fad0 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -93,6 +93,7 @@ func (w *tcpWorker) handleConnections(conns <-chan internet.Connection) { for { select { case conn := <-conns: + conn.SetReusable(false) conn.Close() default: break L diff --git a/transport/internet/kcp/listener.go b/transport/internet/kcp/listener.go index bc5822b6..1b125ba2 100644 --- a/transport/internet/kcp/listener.go +++ b/transport/internet/kcp/listener.go @@ -202,6 +202,7 @@ func (v *Listener) OnReceive(payload *buf.Buffer, src v2net.Destination, origina select { case v.conns <- netConn: case <-time.After(time.Second * 5): + conn.SetReusable(false) conn.Close() return } diff --git a/transport/internet/tcp/hub.go b/transport/internet/tcp/hub.go index 999dfabf..f14507c8 100644 --- a/transport/internet/tcp/hub.go +++ b/transport/internet/tcp/hub.go @@ -4,13 +4,13 @@ import ( "context" "crypto/tls" "net" - "sync" "time" "v2ray.com/core/app/log" "v2ray.com/core/common" "v2ray.com/core/common/errors" v2net "v2ray.com/core/common/net" + "v2ray.com/core/common/retry" "v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet/internal" v2tls "v2ray.com/core/transport/internet/tls" @@ -21,7 +21,6 @@ var ( ) type TCPListener struct { - sync.Mutex ctx context.Context listener *net.TCPListener tlsConfig *tls.Config @@ -76,13 +75,20 @@ func (v *TCPListener) KeepAccepting() { return default: } - conn, err := v.listener.Accept() - v.Lock() + var conn net.Conn + err := retry.ExponentialBackoff(5, 200).On(func() error { + rawConn, err := v.listener.Accept() + if err != nil { + return err + } + conn = rawConn + return nil + }) if err != nil { log.Warning("TCP|Listener: Failed to accepted raw connections: ", err) - v.Unlock() continue } + if v.tlsConfig != nil { conn = tls.Server(conn, v.tlsConfig) } @@ -95,19 +101,16 @@ func (v *TCPListener) KeepAccepting() { case <-time.After(time.Second * 5): conn.Close() } - - v.Unlock() } } func (v *TCPListener) Put(id internal.ConnectionID, conn net.Conn) { select { - case <-v.ctx.Done(): - conn.Close() - return case v.conns <- internal.NewConnection(internal.ConnectionID{}, conn, v, internal.ReuseConnection(v.config.IsConnectionReuse())): case <-time.After(time.Second * 5): conn.Close() + case <-v.ctx.Done(): + conn.Close() } }