Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clearing UserOnlineIP and AliveMap #22

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 5 additions & 111 deletions limiter/limiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
import (
"errors"
"regexp"
"strings"

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, 386)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, arm, 7)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (android, arm64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, amd64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, amd64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (darwin, arm64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 7)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, arm64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 5)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 6)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (darwin, amd64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, 386)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips64le)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, ppc64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mipsle)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, s390x)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (windows, 386)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (windows, amd64)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, ppc64le)

"strings" imported and not used

Check failure on line 6 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, riscv64)

"strings" imported and not used
"sync"
"time"

"github.com/InazumaV/V2bX/api/panel"
"github.com/InazumaV/V2bX/common/format"
"github.com/InazumaV/V2bX/conf"
"github.com/juju/ratelimit"

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, 386)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, arm, 7)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (android, arm64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, amd64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, amd64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (darwin, arm64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 7)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (freebsd, arm64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 5)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm, 6)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (darwin, amd64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, 386)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mips64le)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, ppc64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, mipsle)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, s390x)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, arm64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (windows, 386)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (windows, amd64)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, ppc64le)

"github.com/juju/ratelimit" imported and not used

Check failure on line 13 in limiter/limiter.go

View workflow job for this annotation

GitHub Actions / build (linux, riscv64)

"github.com/juju/ratelimit" imported and not used
log "github.com/sirupsen/logrus"
"github.com/xtls/xray-core/common/task"

)

var limitLock sync.RWMutex
Expand All @@ -37,12 +38,11 @@
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 {
Expand All @@ -62,7 +62,6 @@
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 {
Expand Down Expand Up @@ -105,6 +104,8 @@
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{
Expand All @@ -122,110 +123,3 @@
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"`
}
Loading