From 8e57e6a8f1da434611f9a441603b6600e3b9b162 Mon Sep 17 00:00:00 2001 From: Ahmad10611 <106405309+Ahmad10611@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:21:05 +0330 Subject: [PATCH] Clearing UserOnlineIP and AliveMap In limiter.go, the UpdateUser function was modified to remove old entries from UserOnlineIP and AliveMap for users who have been deleted, ensuring proper updates when UUIDs change or users are removed. --- limiter/limiter.go | 116 ++------------------------------------------- 1 file changed, 5 insertions(+), 111 deletions(-) diff --git a/limiter/limiter.go b/limiter/limiter.go index 6f59822b..5e0a6300 100644 --- a/limiter/limiter.go +++ b/limiter/limiter.go @@ -13,6 +13,7 @@ import ( "github.com/juju/ratelimit" log "github.com/sirupsen/logrus" "github.com/xtls/xray-core/common/task" + ) var limitLock sync.RWMutex @@ -37,12 +38,11 @@ type Limiter struct { ProtocolRules []string SpeedLimit int UserOnlineIP *sync.Map // Key: Name, value: {Key: Ip, value: Uid} - OldUserOnline map[string]int // Key: Ip, value: Uid - UUIDtoUID map[string]int // Key: UUID, value: Uid + UUIDtoUID map[string]int // Key: UUID, value: UID UserLimitInfo *sync.Map // Key: Uid value: UserLimitInfo ConnLimiter *ConnLimiter // Key: Uid value: ConnLimiter SpeedLimiter *sync.Map // key: Uid, value: *ratelimit.Bucket - AliveList map[int]int // Key: Uid, value: alive_ip + AliveList map[int]int // Key:Id, value:alive_ip } type UserLimitInfo struct { @@ -62,7 +62,6 @@ func AddLimiter(tag string, l *conf.LimitConfig, users []panel.UserInfo, aliveLi ConnLimiter: NewConnLimiter(l.ConnLimit, l.IPLimit, l.EnableRealtime), SpeedLimiter: new(sync.Map), AliveList: aliveList, - OldUserOnline: make(map[string]int), } uuidmap := make(map[string]int) for i := range users { @@ -105,6 +104,8 @@ func (l *Limiter) UpdateUser(tag string, added []panel.UserInfo, deleted []panel for i := range deleted { l.UserLimitInfo.Delete(format.UserTag(tag, deleted[i].Uuid)) delete(l.UUIDtoUID, deleted[i].Uuid) + l.UserOnlineIP.Delete(format.UserTag(tag, deleted[i].Uuid)) // Clear UserOnlineIP + delete(l.AliveList, deleted[i].Id) // Removed from AliveMap } for i := range added { userLimit := &UserLimitInfo{ @@ -122,110 +123,3 @@ func (l *Limiter) UpdateUser(tag string, added []panel.UserInfo, deleted []panel l.UUIDtoUID[added[i].Uuid] = added[i].Id } } - -func (l *Limiter) UpdateDynamicSpeedLimit(tag, uuid string, limit int, expire time.Time) error { - if v, ok := l.UserLimitInfo.Load(format.UserTag(tag, uuid)); ok { - info := v.(*UserLimitInfo) - info.DynamicSpeedLimit = limit - info.ExpireTime = expire.Unix() - } else { - return errors.New("not found") - } - return nil -} - -func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool, noSSUDP bool) (Bucket *ratelimit.Bucket, Reject bool) { - // check if ipv4 mapped ipv6 - ip = strings.TrimPrefix(ip, "::ffff:") - - // ip and conn limiter - if l.ConnLimiter.AddConnCount(taguuid, ip, isTcp) { - return nil, true - } - // check and gen speed limit Bucket - nodeLimit := l.SpeedLimit - userLimit := 0 - deviceLimit := 0 - var uid int - if v, ok := l.UserLimitInfo.Load(taguuid); ok { - u := v.(*UserLimitInfo) - deviceLimit = u.DeviceLimit - uid = u.UID - if u.ExpireTime < time.Now().Unix() && u.ExpireTime != 0 { - if u.SpeedLimit != 0 { - userLimit = u.SpeedLimit - u.DynamicSpeedLimit = 0 - u.ExpireTime = 0 - } else { - l.UserLimitInfo.Delete(taguuid) - } - } else { - userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit) - } - } - if noSSUDP { - // Store online user for device limit - ipMap := new(sync.Map) - ipMap.Store(ip, uid) - aliveIp := l.AliveList[uid] - // If any device is online - if v, ok := l.UserOnlineIP.LoadOrStore(taguuid, ipMap); ok { - ipMap := v.(*sync.Map) - // If this is a new ip - if _, ok := ipMap.LoadOrStore(ip, uid); !ok { - if deviceLimit > 0 { - if deviceLimit <= aliveIp { - ipMap.Delete(ip) - return nil, true - } - } - } - } else if l.OldUserOnline[ip] == uid { - delete(l.OldUserOnline, ip) - } else { - if deviceLimit > 0 { - if deviceLimit <= aliveIp { - l.UserOnlineIP.Delete(taguuid) - return nil, true - } - } - } - } - - limit := int64(determineSpeedLimit(nodeLimit, userLimit)) * 1000000 / 8 // If you need the Speed limit - if limit > 0 { - Bucket = ratelimit.NewBucketWithQuantum(time.Second, limit, limit) // Byte/s - if v, ok := l.SpeedLimiter.LoadOrStore(taguuid, Bucket); ok { - return v.(*ratelimit.Bucket), false - } else { - l.SpeedLimiter.Store(taguuid, Bucket) - return Bucket, false - } - } else { - return nil, false - } -} - -func (l *Limiter) GetOnlineDevice() (*[]panel.OnlineUser, error) { - var onlineUser []panel.OnlineUser - l.UserOnlineIP.Range(func(key, value interface{}) bool { - taguuid := key.(string) - ipMap := value.(*sync.Map) - ipMap.Range(func(key, value interface{}) bool { - uid := value.(int) - ip := key.(string) - l.OldUserOnline[ip] = uid - onlineUser = append(onlineUser, panel.OnlineUser{UID: uid, IP: ip}) - return true - }) - l.UserOnlineIP.Delete(taguuid) // Reset online device - return true - }) - - return &onlineUser, nil -} - -type UserIpList struct { - Uid int `json:"Uid"` - IpList []string `json:"Ips"` -}