From 2a915a5c94cec42e018757f20b75cbaf1dbe5881 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Sun, 10 Aug 2025 22:43:31 +0800 Subject: [PATCH] fix: vless server close --- adapter/outbound/vless.go | 10 ++++++---- listener/sing_vless/server.go | 16 ++++++++++++++-- transport/vless/encryption/server.go | 11 +++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index 47128541..bacc41fc 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -463,26 +463,28 @@ func NewVless(option VlessOption) (*Vless, error) { if t == s[0] { return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption) } - i, err := strconv.Atoi(t) + var i int + i, err = strconv.Atoi(t) if err != nil { return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption) } minutes = uint32(i) } - b, err := base64.RawURLEncoding.DecodeString(s[1]) + var b []byte + b, err = base64.RawURLEncoding.DecodeString(s[1]) if err != nil { return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption) } if len(b) == 1184 { v.encryption = &encryption.ClientInstance{} - if err := v.encryption.Init(b, time.Duration(minutes)*time.Minute); err != nil { + if err = v.encryption.Init(b, time.Duration(minutes)*time.Minute); err != nil { return nil, fmt.Errorf("failed to use mlkem768seed: %w", err) } } else { return nil, fmt.Errorf("invaild vless encryption value: %s", option.Encryption) } if option.Flow != "" { - return nil, errors.New(`VLESS users: "encryption" doesn't support "flow" yet`) + return nil, errors.New(`vless "encryption" doesn't support "flow" yet`) } } diff --git a/listener/sing_vless/server.go b/listener/sing_vless/server.go index 06358824..a8165083 100644 --- a/listener/sing_vless/server.go +++ b/listener/sing_vless/server.go @@ -95,13 +95,15 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition) if t == s[0] { return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption) } - i, err := strconv.Atoi(t) + var i int + i, err = strconv.Atoi(t) if err != nil { return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption) } minutes = uint32(i) } - b, err := base64.RawURLEncoding.DecodeString(s[1]) + var b []byte + b, err = base64.RawURLEncoding.DecodeString(s[1]) if err != nil { return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption) } @@ -113,6 +115,13 @@ func New(config LC.VlessServer, tunnel C.Tunnel, additions ...inbound.Addition) } else { return nil, fmt.Errorf("invaild vless decryption value: %s", config.Decryption) } + + defer func() { // decryption must be closed to avoid the goroutine leak + if err != nil { + _ = sl.decryption.Close() + sl.decryption = nil + } + }() } tlsConfig := &tlsC.Config{} @@ -218,6 +227,9 @@ func (l *Listener) Close() error { retErr = err } } + if l.decryption != nil { + _ = l.decryption.Close() + } return retErr } diff --git a/transport/vless/encryption/server.go b/transport/vless/encryption/server.go index 91ec488f..667b813f 100644 --- a/transport/vless/encryption/server.go +++ b/transport/vless/encryption/server.go @@ -27,6 +27,7 @@ type ServerInstance struct { dKeyNfs *mlkem.DecapsulationKey768 minutes time.Duration sessions map[[21]byte]*ServerSession + stop bool } type ServerConn struct { @@ -52,6 +53,9 @@ func (i *ServerInstance) Init(dKeyNfsData []byte, minutes time.Duration) (err er time.Sleep(time.Minute) now := time.Now() i.Lock() + if i.stop { + return + } for index, session := range i.sessions { if now.After(session.expire) { delete(i.sessions, index) @@ -64,6 +68,13 @@ func (i *ServerInstance) Init(dKeyNfsData []byte, minutes time.Duration) (err er return } +func (i *ServerInstance) Close() (err error) { + i.Lock() + defer i.Unlock() + i.stop = true + return +} + func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) { if i.dKeyNfs == nil { return nil, errors.New("uninitialized")