mirror of
https://github.com/wyx2685/V2bX.git
synced 2025-01-22 18:08:14 -05:00
15c36a9580
refactor limiter fix getLink bug add connection limit move limit config to ControllerConfig del dynamic speed limit (next version will be re add) del online ip sync (next version will be re add)
97 lines
1.7 KiB
Go
97 lines
1.7 KiB
Go
package limiter
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
type ConnLimiter struct {
|
|
ipLimit int
|
|
connLimit int
|
|
count sync.Map //map[string]int
|
|
ip sync.Map //map[string]map[string]*sync.Map
|
|
}
|
|
|
|
func NewConnLimiter(conn int, ip int) *ConnLimiter {
|
|
return &ConnLimiter{
|
|
connLimit: conn,
|
|
ipLimit: ip,
|
|
count: sync.Map{},
|
|
ip: sync.Map{},
|
|
}
|
|
}
|
|
|
|
func (c *ConnLimiter) AddConnCount(user string, ip string) (limit bool) {
|
|
if c.connLimit != 0 {
|
|
if v, ok := c.count.Load(user); ok {
|
|
if v.(int) >= c.connLimit {
|
|
return true
|
|
} else {
|
|
c.count.Store(user, v.(int)+1)
|
|
}
|
|
} else {
|
|
c.count.Store(user, 1)
|
|
}
|
|
}
|
|
if c.ipLimit == 0 {
|
|
return false
|
|
}
|
|
ipMap := new(sync.Map)
|
|
ipMap.Store(ip, 1)
|
|
if v, ok := c.ip.LoadOrStore(user, ipMap); ok {
|
|
// have online ip
|
|
ips := v.(*sync.Map)
|
|
cn := 0
|
|
if online, ok := ips.Load(ip); !ok {
|
|
ips.Range(func(key, value interface{}) bool {
|
|
cn++
|
|
if cn >= c.ipLimit {
|
|
limit = true
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
if limit {
|
|
return
|
|
}
|
|
ips.Store(ip, 1)
|
|
} else {
|
|
// have this ip
|
|
ips.Store(ip, online.(int)+1)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (c *ConnLimiter) DelConnCount(user string, ip string) {
|
|
if c.connLimit != 0 {
|
|
if v, ok := c.count.Load(user); ok {
|
|
if v.(int) == 1 {
|
|
c.count.Delete(user)
|
|
} else {
|
|
c.count.Store(user, v.(int)-1)
|
|
}
|
|
}
|
|
}
|
|
if c.ipLimit == 0 {
|
|
return
|
|
}
|
|
if i, ok := c.ip.Load(user); ok {
|
|
is := i.(*sync.Map)
|
|
if i, ok := is.Load(ip); ok {
|
|
if i.(int) == 1 {
|
|
is.Delete(ip)
|
|
} else {
|
|
is.Store(user, i.(int)-1)
|
|
}
|
|
notDel := false
|
|
c.ip.Range(func(_, _ any) bool {
|
|
notDel = true
|
|
return true
|
|
})
|
|
if !notDel {
|
|
c.ip.Delete(user)
|
|
}
|
|
}
|
|
}
|
|
}
|