From 3dc8bf3d8b5d2249ef07f793ab544cafacd18e3c Mon Sep 17 00:00:00 2001 From: LjhAUMEM Date: Sat, 4 Jul 2026 09:28:21 +0800 Subject: [PATCH] Hysteria inbound: Fix dynamic UUID not accepted (#6395) Fixes https://github.com/XTLS/Xray-core/pull/6375#issuecomment-4825923934 --- go.mod | 1 + proxy/hysteria/account/config.go | 64 ++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 1ddc88fdc..d5af7f407 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 github.com/golang/mock v1.7.0-rc.1 github.com/google/go-cmp v0.7.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/klauspost/cpuid/v2 v2.4.0 github.com/miekg/dns v1.1.72 diff --git a/proxy/hysteria/account/config.go b/proxy/hysteria/account/config.go index 299104585..401dfd0b1 100644 --- a/proxy/hysteria/account/config.go +++ b/proxy/hysteria/account/config.go @@ -5,14 +5,14 @@ import ( "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" - "github.com/xtls/xray-core/common/uuid" + "github.com/google/uuid" "google.golang.org/protobuf/proto" ) func (a *Account) AsAccount() (protocol.Account, error) { var VR net.Port - if id, err := uuid.ParseString(a.Auth); err == nil { + if id, err := uuid.Parse(a.Auth); err == nil { VR = net.PortFromBytes(id[6:8]) } return &MemoryAccount{ @@ -41,29 +41,71 @@ func (a *MemoryAccount) ToProto() proto.Message { type Validator struct { users sync.Map + ids sync.Map + mu sync.Mutex } func NewValidator() *Validator { return &Validator{} } -func (v *Validator) Add(user *protocol.MemoryUser) error { +func (v *Validator) Add(user *protocol.MemoryUser) (err error) { + v.mu.Lock() v.users.Store(user.Account.(*MemoryAccount).Auth, user) - return nil + if id, err := uuid.Parse(user.Account.(*MemoryAccount).Auth); err == nil { + id[6] = 0 + id[7] = 0 + v.ids.Store(id, user) + } + v.mu.Unlock() + return } -func (v *Validator) DelByEmail(email string) error { +func (v *Validator) DelByEmail(email string) (err error) { + v.mu.Lock() if user := v.GetByEmail(email); user != nil { - v.users.Delete(user.Account.(*MemoryAccount).Auth) + auth := user.Account.(*MemoryAccount).Auth + v.users.Delete(auth) + if id, err := uuid.Parse(auth); err == nil { + id[6] = 0 + id[7] = 0 + v.ids.Delete(id) + } } - return nil + v.mu.Unlock() + return } -func (v *Validator) Get(auth string) *protocol.MemoryUser { - if value, ok := v.users.Load(auth); ok { - return value.(*protocol.MemoryUser) +func (v *Validator) Get(auth string) (user *protocol.MemoryUser) { + if id, err := uuid.Parse(auth); err == nil { + if user = v.GetByID(id); user != nil { + VR := net.PortFromBytes(id[6:8]) + if user.Account.(*MemoryAccount).VR != VR { + user = &protocol.MemoryUser{ + Email: user.Email, + Level: user.Level, + Account: &MemoryAccount{ + Auth: auth, + VR: VR, + }, + } + } + } + return } - return nil + if value, ok := v.users.Load(auth); ok { + user = value.(*protocol.MemoryUser) + } + return +} + +func (v *Validator) GetByID(id uuid.UUID) (user *protocol.MemoryUser) { + id[6] = 0 + id[7] = 0 + if value, ok := v.ids.Load(id); ok { + user = value.(*protocol.MemoryUser) + } + return } func (v *Validator) GetByEmail(email string) (user *protocol.MemoryUser) {