mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-04 04:30:08 +00:00
update example, add realtime option, fix ip limit bug for packet protocol
This commit is contained in:
@@ -2,13 +2,13 @@ package limiter
|
||||
|
||||
import "log"
|
||||
|
||||
func ClearPacketOnlineIP() error {
|
||||
log.Println("Limiter: Clear packet online ip...")
|
||||
func ClearOnlineIP() error {
|
||||
log.Println("Limiter: Clear online ip...")
|
||||
limitLock.RLock()
|
||||
for _, l := range limiter {
|
||||
l.ConnLimiter.ClearPacketOnlineIP()
|
||||
l.ConnLimiter.ClearOnlineIP()
|
||||
}
|
||||
limitLock.RUnlock()
|
||||
log.Println("Limiter: Clear packet online ip done")
|
||||
log.Println("Limiter: Clear online ip done")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,15 +5,16 @@ import (
|
||||
)
|
||||
|
||||
type ConnLimiter struct {
|
||||
realTime bool
|
||||
realtime bool
|
||||
ipLimit int
|
||||
connLimit int
|
||||
count sync.Map // map[string]int
|
||||
ip sync.Map // map[string]map[string]int
|
||||
}
|
||||
|
||||
func NewConnLimiter(conn int, ip int) *ConnLimiter {
|
||||
func NewConnLimiter(conn int, ip int, realtime bool) *ConnLimiter {
|
||||
return &ConnLimiter{
|
||||
realtime: realtime,
|
||||
connLimit: conn,
|
||||
ipLimit: ip,
|
||||
count: sync.Map{},
|
||||
@@ -38,10 +39,14 @@ func (c *ConnLimiter) AddConnCount(user string, ip string, isTcp bool) (limit bo
|
||||
}
|
||||
// default user map
|
||||
ipMap := new(sync.Map)
|
||||
if isTcp {
|
||||
ipMap.Store(ip, 2)
|
||||
if c.realtime {
|
||||
if isTcp {
|
||||
ipMap.Store(ip, 2)
|
||||
} else {
|
||||
ipMap.Store(ip, 1)
|
||||
}
|
||||
} else {
|
||||
ipMap.Store(ip, 1)
|
||||
ipMap.Store(ip, struct{}{})
|
||||
}
|
||||
// check user online ip
|
||||
if v, ok := c.ip.LoadOrStore(user, ipMap); ok {
|
||||
@@ -50,9 +55,11 @@ func (c *ConnLimiter) AddConnCount(user string, ip string, isTcp bool) (limit bo
|
||||
cn := 0
|
||||
if online, ok := ips.Load(ip); ok {
|
||||
// online ip
|
||||
if isTcp {
|
||||
// count add
|
||||
ips.Store(ip, online.(int)+2)
|
||||
if c.realtime {
|
||||
if online.(int)%2 == 0 && isTcp {
|
||||
// count add
|
||||
ips.Store(ip, online.(int)+2)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// not online ip
|
||||
@@ -67,10 +74,14 @@ func (c *ConnLimiter) AddConnCount(user string, ip string, isTcp bool) (limit bo
|
||||
if limit {
|
||||
return
|
||||
}
|
||||
if isTcp {
|
||||
ips.Store(ip, 2)
|
||||
if c.realtime {
|
||||
if isTcp {
|
||||
ips.Store(ip, 2)
|
||||
} else {
|
||||
ips.Store(ip, 1)
|
||||
}
|
||||
} else {
|
||||
ips.Store(ip, 1)
|
||||
ips.Store(ip, struct{}{})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +90,9 @@ func (c *ConnLimiter) AddConnCount(user string, ip string, isTcp bool) (limit bo
|
||||
|
||||
// DelConnCount Delete tcp connection count, no tcp do not use
|
||||
func (c *ConnLimiter) DelConnCount(user string, ip string) {
|
||||
if !c.realtime {
|
||||
return
|
||||
}
|
||||
if c.connLimit != 0 {
|
||||
if v, ok := c.count.Load(user); ok {
|
||||
if v.(int) == 1 {
|
||||
@@ -111,12 +125,18 @@ func (c *ConnLimiter) DelConnCount(user string, ip string) {
|
||||
}
|
||||
}
|
||||
|
||||
// ClearPacketOnlineIP Clear udp,icmp and other packet protocol online ip
|
||||
func (c *ConnLimiter) ClearPacketOnlineIP() {
|
||||
// ClearOnlineIP Clear udp,icmp and other packet protocol online ip
|
||||
func (c *ConnLimiter) ClearOnlineIP() {
|
||||
c.ip.Range(func(_, v any) bool {
|
||||
userIp := v.(*sync.Map)
|
||||
userIp.Range(func(ip, v any) bool {
|
||||
if c.realtime {
|
||||
// clear not realtime ip
|
||||
userIp.Delete(ip)
|
||||
return true
|
||||
}
|
||||
if v.(int) == 1 {
|
||||
// clear packet ip for realtime
|
||||
userIp.Delete(ip)
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestConnLimiter_DelConnCount(t *testing.T) {
|
||||
func TestConnLimiter_ClearPacketOnlineIP(t *testing.T) {
|
||||
t.Log(c.AddConnCount("1", "1", false))
|
||||
t.Log(c.AddConnCount("1", "2", false))
|
||||
c.ClearPacketOnlineIP()
|
||||
c.ClearOnlineIP()
|
||||
t.Log(c.AddConnCount("1", "2", true))
|
||||
c.DelConnCount("1", "2")
|
||||
t.Log(c.AddConnCount("1", "1", false))
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Yuzuki616/V2bX/api/panel"
|
||||
"github.com/Yuzuki616/V2bX/conf"
|
||||
"github.com/juju/ratelimit"
|
||||
"github.com/xtls/xray-core/common/task"
|
||||
"log"
|
||||
@@ -18,10 +19,10 @@ func Init() {
|
||||
limiter = map[string]*Limiter{}
|
||||
c := task.Periodic{
|
||||
Interval: time.Minute * 2,
|
||||
Execute: ClearPacketOnlineIP,
|
||||
Execute: ClearOnlineIP,
|
||||
}
|
||||
go func() {
|
||||
log.Println("Limiter: ClearPacketOnlineIP started")
|
||||
log.Println("Limiter: ClearOnlineIP started")
|
||||
time.Sleep(time.Minute * 2)
|
||||
c.Start()
|
||||
}()
|
||||
@@ -43,17 +44,11 @@ type UserLimitInfo struct {
|
||||
ExpireTime int64
|
||||
}
|
||||
|
||||
type LimitConfig struct {
|
||||
SpeedLimit int
|
||||
IpLimit int
|
||||
ConnLimit int
|
||||
}
|
||||
|
||||
func AddLimiter(tag string, l *LimitConfig, users []panel.UserInfo) *Limiter {
|
||||
func AddLimiter(tag string, l *conf.LimitConfig, users []panel.UserInfo) *Limiter {
|
||||
info := &Limiter{
|
||||
SpeedLimit: l.SpeedLimit,
|
||||
UserLimitInfo: new(sync.Map),
|
||||
ConnLimiter: NewConnLimiter(l.ConnLimit, l.IpLimit),
|
||||
ConnLimiter: NewConnLimiter(l.ConnLimit, l.IPLimit, l.EnableRealtime),
|
||||
SpeedLimiter: new(sync.Map),
|
||||
}
|
||||
for i := range users {
|
||||
|
||||
Reference in New Issue
Block a user