From dbee0f656143905887694735f956a8bcb1c95497 Mon Sep 17 00:00:00 2001 From: Fangliding Date: Thu, 8 Oct 2026 04:00:54 +0800 Subject: [PATCH] Track alive hy conn --- transport/internet/hysteria/conn.go | 12 ++++++-- transport/internet/hysteria/dialer.go | 40 ++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/transport/internet/hysteria/conn.go b/transport/internet/hysteria/conn.go index 07b8f6d9f..25b497959 100644 --- a/transport/internet/hysteria/conn.go +++ b/transport/internet/hysteria/conn.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "io" "sync" + "sync/atomic" "time" "github.com/apernet/quic-go" @@ -20,8 +21,10 @@ type interConn struct { local net.Addr remote net.Addr - client bool - user *protocol.MemoryUser + client bool + user *protocol.MemoryUser + closeOnce sync.Once + aliveTCP *atomic.Int64 } func (c *interConn) User() *protocol.MemoryUser { @@ -46,6 +49,11 @@ func (c *interConn) Write(b []byte) (int, error) { func (c *interConn) Close() error { c.stream.CancelRead(0) + if c.aliveTCP != nil { + c.closeOnce.Do(func() { + c.aliveTCP.Add(-1) + }) + } return c.stream.Close() } diff --git a/transport/internet/hysteria/dialer.go b/transport/internet/hysteria/dialer.go index 4b774c353..3cc42ee16 100644 --- a/transport/internet/hysteria/dialer.go +++ b/transport/internet/hysteria/dialer.go @@ -9,6 +9,7 @@ import ( "runtime" "strconv" "sync" + "sync/atomic" "time" "github.com/apernet/quic-go" @@ -35,10 +36,12 @@ type client struct { finalMask *finalmask.FinalMask quicParams *internet.QuicParams - conn *quic.Conn - tr *quic.Transport - pktConn net.PacketConn - udpSM *udpSessionManager + conn *quic.Conn + tr *quic.Transport + pktConn net.PacketConn + udpSM *udpSessionManager + aliveTCP *atomic.Int64 + lastAlive time.Time } func (c *client) status() status { @@ -235,12 +238,15 @@ func (c *client) tcp(ctx context.Context) (stat.Connection, error) { return nil, err } + c.lastAlive = time.Now() + c.aliveTCP.Add(1) return &interConn{ stream: stream, local: c.conn.LocalAddr(), remote: c.conn.RemoteAddr(), - client: true, + client: true, + aliveTCP: c.aliveTCP, }, nil } @@ -258,10 +264,28 @@ func (c *client) udp(ctx context.Context) (stat.Connection, error) { func (c *client) clean() { c.Lock() - if c.status() == StatusInactive { + defer c.Unlock() + switch c.status() { + case StatusInactive: c.close() + return + case StatusNull: + return + } + var udpSessions int + if c.udpSM != nil { + c.udpSM.RLock() + udpSessions = len(c.udpSM.m) + c.udpSM.RUnlock() + } + if udpSessions == 0 && c.aliveTCP.Load() == 0 { + if c.lastAlive.Add(net.ConnIdleTimeout).Before(time.Now()) { + c.close() + return + } + } else { + c.lastAlive = time.Now() } - c.Unlock() } type dialerConf struct { @@ -321,6 +345,8 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me socketConfig: streamSettings.SocketSettings, finalMask: streamSettings.FinalMask, quicParams: streamSettings.QuicParams, + aliveTCP: &atomic.Int64{}, + lastAlive: time.Now(), } manager.m[dialerConf{dest, streamSettings}] = c }