mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-06-29 16:33:05 +00:00
Hysteria inbound: Support routing's vlessRoute as well (#6375)
https://github.com/XTLS/Xray-core/pull/6375#issuecomment-4795522284 --------- Co-authored-by: LjhAUMEM <llnu14702@gmail.com>
This commit is contained in:
@@ -3,25 +3,32 @@ package account
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/protocol"
|
||||
"github.com/xtls/xray-core/common/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 {
|
||||
VR = net.PortFromBytes(id[6:8])
|
||||
}
|
||||
return &MemoryAccount{
|
||||
Auth: a.Auth,
|
||||
VR: VR,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type MemoryAccount struct {
|
||||
Auth string
|
||||
VR net.Port
|
||||
}
|
||||
|
||||
func (a *MemoryAccount) Equals(another protocol.Account) bool {
|
||||
if account, ok := another.(*MemoryAccount); ok {
|
||||
return a.Auth == account.Auth
|
||||
func (a *MemoryAccount) Equals(other protocol.Account) bool {
|
||||
if b, ok := other.(*MemoryAccount); ok {
|
||||
return a.Auth == b.Auth
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -33,97 +40,63 @@ func (a *MemoryAccount) ToProto() proto.Message {
|
||||
}
|
||||
|
||||
type Validator struct {
|
||||
emails map[string]struct{}
|
||||
users map[string]*protocol.MemoryUser
|
||||
|
||||
mutex sync.Mutex
|
||||
users sync.Map
|
||||
}
|
||||
|
||||
func NewValidator() *Validator {
|
||||
return &Validator{
|
||||
emails: make(map[string]struct{}),
|
||||
users: make(map[string]*protocol.MemoryUser),
|
||||
}
|
||||
return &Validator{}
|
||||
}
|
||||
|
||||
func (v *Validator) Add(u *protocol.MemoryUser) error {
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
if u.Email != "" {
|
||||
if _, ok := v.emails[u.Email]; ok {
|
||||
return errors.New("User ", u.Email, " already exists.")
|
||||
}
|
||||
v.emails[u.Email] = struct{}{}
|
||||
}
|
||||
v.users[u.Account.(*MemoryAccount).Auth] = u
|
||||
|
||||
func (v *Validator) Add(user *protocol.MemoryUser) error {
|
||||
v.users.Store(user.Account.(*MemoryAccount).Auth, user)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validator) Del(email string) error {
|
||||
if email == "" {
|
||||
return errors.New("Email must not be empty.")
|
||||
func (v *Validator) DelByEmail(email string) error {
|
||||
if user := v.GetByEmail(email); user != nil {
|
||||
v.users.Delete(user.Account.(*MemoryAccount).Auth)
|
||||
}
|
||||
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
if _, ok := v.emails[email]; !ok {
|
||||
return errors.New("User ", email, " not found.")
|
||||
}
|
||||
delete(v.emails, email)
|
||||
for key, user := range v.users {
|
||||
if user.Email == email {
|
||||
delete(v.users, key)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validator) Get(auth string) *protocol.MemoryUser {
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
return v.users[auth]
|
||||
}
|
||||
|
||||
func (v *Validator) GetByEmail(email string) *protocol.MemoryUser {
|
||||
if email == "" {
|
||||
return nil
|
||||
if value, ok := v.users.Load(auth); ok {
|
||||
return value.(*protocol.MemoryUser)
|
||||
}
|
||||
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
if _, ok := v.emails[email]; ok {
|
||||
for _, user := range v.users {
|
||||
if user.Email == email {
|
||||
return user
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Validator) GetAll() []*protocol.MemoryUser {
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
users := make([]*protocol.MemoryUser, 0, len(v.users))
|
||||
for _, user := range v.users {
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
return users
|
||||
func (v *Validator) GetByEmail(email string) (user *protocol.MemoryUser) {
|
||||
v.users.Range(func(key, value any) bool {
|
||||
if value.(*protocol.MemoryUser).Email == email {
|
||||
user = value.(*protocol.MemoryUser)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Validator) GetCount() int64 {
|
||||
v.mutex.Lock()
|
||||
defer v.mutex.Unlock()
|
||||
|
||||
return int64(len(v.users))
|
||||
func (v *Validator) GetAll() (users []*protocol.MemoryUser) {
|
||||
v.users.Range(func(key, value any) bool {
|
||||
users = append(users, value.(*protocol.MemoryUser))
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Validator) GetCount() (count int64) {
|
||||
v.users.Range(func(key, value any) bool {
|
||||
count++
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Validator) NotEmpty() (not_empty bool) {
|
||||
v.users.Range(func(key, value any) bool {
|
||||
not_empty = true
|
||||
return false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ func (s *Server) HysteriaInboundValidator() *account.Validator {
|
||||
return s.validator
|
||||
}
|
||||
|
||||
func (s *Server) AddUser(ctx context.Context, u *protocol.MemoryUser) error {
|
||||
return s.validator.Add(u)
|
||||
func (s *Server) AddUser(ctx context.Context, user *protocol.MemoryUser) error {
|
||||
return s.validator.Add(user)
|
||||
}
|
||||
|
||||
func (s *Server) RemoveUser(ctx context.Context, e string) error {
|
||||
return s.validator.Del(e)
|
||||
func (s *Server) RemoveUser(ctx context.Context, email string) error {
|
||||
return s.validator.DelByEmail(email)
|
||||
}
|
||||
|
||||
func (s *Server) GetUser(ctx context.Context, email string) *protocol.MemoryUser {
|
||||
@@ -91,9 +91,12 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
||||
|
||||
iConn := stat.TryUnwrapStatsConn(conn)
|
||||
|
||||
type User interface{ User() *protocol.MemoryUser }
|
||||
if v, ok := iConn.(User); ok && v.User() != nil {
|
||||
inbound.User = v.User()
|
||||
if v, ok := iConn.(interface{ User() *protocol.MemoryUser }); ok {
|
||||
user := v.User()
|
||||
if user != nil {
|
||||
inbound.User = user
|
||||
inbound.VlessRoute = user.Account.(*account.MemoryAccount).VR
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := iConn.(*hysteria.InterConn); ok {
|
||||
|
||||
Reference in New Issue
Block a user