mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-04 20:50:09 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89ddfff060 | ||
|
|
07d49293d8 | ||
|
|
9e8f87740e | ||
|
|
29a99985c8 | ||
|
|
248ff3764f | ||
|
|
3dfeba7e68 |
12
.github/workflows/Publish Docker image.yml
vendored
12
.github/workflows/Publish Docker image.yml
vendored
@@ -1,16 +1,8 @@
|
|||||||
name: Publish Docker image
|
name: Publish Docker image
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
release:
|
||||||
branches:
|
types: [published]
|
||||||
- dev_new
|
|
||||||
paths:
|
|
||||||
- "**/*.go"
|
|
||||||
- "go.mod"
|
|
||||||
- "go.sum"
|
|
||||||
- ".github/workflows/*.yml"
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- 'dev_new'
|
- 'dev_new'
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TrafficCounter struct {
|
type TrafficCounter struct {
|
||||||
counters map[string]*TrafficStorage
|
counters sync.Map
|
||||||
lock sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TrafficStorage struct {
|
type TrafficStorage struct {
|
||||||
@@ -16,60 +15,52 @@ type TrafficStorage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTrafficCounter() *TrafficCounter {
|
func NewTrafficCounter() *TrafficCounter {
|
||||||
return &TrafficCounter{
|
return &TrafficCounter{}
|
||||||
counters: map[string]*TrafficStorage{},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) GetCounter(id string) *TrafficStorage {
|
func (c *TrafficCounter) GetCounter(id string) *TrafficStorage {
|
||||||
c.lock.RLock()
|
if cts, ok := c.counters.Load(id); ok {
|
||||||
cts, ok := c.counters[id]
|
return cts.(*TrafficStorage)
|
||||||
c.lock.RUnlock()
|
|
||||||
if !ok {
|
|
||||||
cts = &TrafficStorage{}
|
|
||||||
c.counters[id] = cts
|
|
||||||
}
|
}
|
||||||
return cts
|
newStorage := &TrafficStorage{}
|
||||||
|
if cts, loaded := c.counters.LoadOrStore(id, newStorage); loaded {
|
||||||
|
return cts.(*TrafficStorage)
|
||||||
|
}
|
||||||
|
return newStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) GetUpCount(id string) int64 {
|
func (c *TrafficCounter) GetUpCount(id string) int64 {
|
||||||
c.lock.RLock()
|
if cts, ok := c.counters.Load(id); ok {
|
||||||
cts, ok := c.counters[id]
|
return cts.(*TrafficStorage).UpCounter.Load()
|
||||||
c.lock.RUnlock()
|
|
||||||
if ok {
|
|
||||||
return cts.UpCounter.Load()
|
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) GetDownCount(id string) int64 {
|
func (c *TrafficCounter) GetDownCount(id string) int64 {
|
||||||
c.lock.RLock()
|
if cts, ok := c.counters.Load(id); ok {
|
||||||
cts, ok := c.counters[id]
|
return cts.(*TrafficStorage).DownCounter.Load()
|
||||||
c.lock.RUnlock()
|
|
||||||
if ok {
|
|
||||||
return cts.DownCounter.Load()
|
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) Len() int {
|
func (c *TrafficCounter) Len() int {
|
||||||
c.lock.RLock()
|
length := 0
|
||||||
defer c.lock.RUnlock()
|
c.counters.Range(func(_, _ interface{}) bool {
|
||||||
return len(c.counters)
|
length++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return length
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) Reset(id string) {
|
func (c *TrafficCounter) Reset(id string) {
|
||||||
c.lock.RLock()
|
if cts, ok := c.counters.Load(id); ok {
|
||||||
cts := c.GetCounter(id)
|
cts.(*TrafficStorage).UpCounter.Store(0)
|
||||||
c.lock.RUnlock()
|
cts.(*TrafficStorage).DownCounter.Store(0)
|
||||||
cts.UpCounter.Store(0)
|
}
|
||||||
cts.DownCounter.Store(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) Delete(id string) {
|
func (c *TrafficCounter) Delete(id string) {
|
||||||
c.lock.Lock()
|
c.counters.Delete(id)
|
||||||
delete(c.counters, id)
|
|
||||||
c.lock.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) Rx(id string, n int) {
|
func (c *TrafficCounter) Rx(id string, n int) {
|
||||||
@@ -81,11 +72,3 @@ func (c *TrafficCounter) Tx(id string, n int) {
|
|||||||
cts := c.GetCounter(id)
|
cts := c.GetCounter(id)
|
||||||
cts.UpCounter.Add(int64(n))
|
cts.UpCounter.Add(int64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *TrafficCounter) IncConn(auth string) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *TrafficCounter) DecConn(auth string) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/juju/ratelimit"
|
"github.com/juju/ratelimit"
|
||||||
"github.com/sagernet/sing/common/buf"
|
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
|
||||||
"github.com/sagernet/sing/common/network"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewConnRateLimiter(c net.Conn, l *ratelimit.Bucket) *Conn {
|
func NewConnRateLimiter(c net.Conn, l *ratelimit.Bucket) *Conn {
|
||||||
@@ -31,6 +28,7 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
|||||||
return c.Conn.Write(b)
|
return c.Conn.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
type PacketConnCounter struct {
|
type PacketConnCounter struct {
|
||||||
network.PacketConn
|
network.PacketConn
|
||||||
limiter *ratelimit.Bucket
|
limiter *ratelimit.Bucket
|
||||||
@@ -47,10 +45,11 @@ func (p *PacketConnCounter) ReadPacket(buff *buf.Buffer) (destination M.Socksadd
|
|||||||
pLen := buff.Len()
|
pLen := buff.Len()
|
||||||
destination, err = p.PacketConn.ReadPacket(buff)
|
destination, err = p.PacketConn.ReadPacket(buff)
|
||||||
p.limiter.Wait(int64(buff.Len() - pLen))
|
p.limiter.Wait(int64(buff.Len() - pLen))
|
||||||
return
|
return destination, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PacketConnCounter) WritePacket(buff *buf.Buffer, destination M.Socksaddr) (err error) {
|
func (p *PacketConnCounter) WritePacket(buff *buf.Buffer, destination M.Socksaddr) (err error) {
|
||||||
p.limiter.Wait(int64(buff.Len()))
|
p.limiter.Wait(int64(buff.Len()))
|
||||||
return p.PacketConn.WritePacket(buff, destination)
|
return p.PacketConn.WritePacket(buff, destination)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -284,15 +284,23 @@ func (n *Hysteria2node) getMasqHandler(tlsconfig *server.TLSConfig, conn net.Pac
|
|||||||
}
|
}
|
||||||
u, err := url.Parse(c.Masquerade.Proxy.URL)
|
u, err := url.Parse(c.Masquerade.Proxy.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(fmt.Sprintf("masquerade.proxy.url %s", err))
|
return nil, fmt.Errorf("masquerade.proxy.url %s", err)
|
||||||
}
|
}
|
||||||
handler = &httputil.ReverseProxy{
|
handler = &httputil.ReverseProxy{
|
||||||
Rewrite: func(r *httputil.ProxyRequest) {
|
Director: func(req *http.Request) {
|
||||||
r.SetURL(u)
|
req.URL.Scheme = u.Scheme
|
||||||
// SetURL rewrites the Host header,
|
req.URL.Host = u.Host
|
||||||
// but we don't want that if rewriteHost is false
|
|
||||||
|
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
|
||||||
|
xff := req.Header.Get("X-Forwarded-For")
|
||||||
|
if xff != "" {
|
||||||
|
clientIP = xff + ", " + clientIP
|
||||||
|
}
|
||||||
|
req.Header.Set("X-Forwarded-For", clientIP)
|
||||||
|
}
|
||||||
|
|
||||||
if !c.Masquerade.Proxy.RewriteHost {
|
if !c.Masquerade.Proxy.RewriteHost {
|
||||||
r.Out.Host = r.In.Host
|
req.Host = req.URL.Host
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (l *serverLogger) Connect(addr net.Addr, uuid string, tx uint64) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||||
}
|
}
|
||||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ func (l *serverLogger) TCPRequest(addr net.Addr, uuid, reqAddr string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||||
}
|
}
|
||||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ func (l *serverLogger) UDPRequest(addr net.Addr, uuid string, sessionId uint32,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||||
}
|
}
|
||||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ func (h *HookServer) RoutedConnection(_ context.Context, conn net.Conn, m adapte
|
|||||||
return conn, t
|
return conn, t
|
||||||
}
|
}
|
||||||
ip := m.Source.Addr.String()
|
ip := m.Source.Addr.String()
|
||||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true); r {
|
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true, true); r {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
||||||
return conn, t
|
return conn, t
|
||||||
@@ -162,12 +162,12 @@ func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn
|
|||||||
return conn, t
|
return conn, t
|
||||||
}
|
}
|
||||||
ip := m.Source.Addr.String()
|
ip := m.Source.Addr.String()
|
||||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true); r {
|
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, false, false); r {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
||||||
return conn, t
|
return conn, t
|
||||||
} else if b != nil {
|
} else if b != nil {
|
||||||
conn = rate.NewPacketConnCounter(conn, b)
|
//conn = rate.NewPacketConnCounter(conn, b)
|
||||||
}
|
}
|
||||||
if h.EnableConnClear {
|
if h.EnableConnClear {
|
||||||
var key int
|
var key int
|
||||||
|
|||||||
@@ -177,7 +177,8 @@ func (d *DefaultDispatcher) getLink(ctx context.Context, network net.Network) (*
|
|||||||
// Speed Limit and Device Limit
|
// Speed Limit and Device Limit
|
||||||
w, reject := limit.CheckLimit(user.Email,
|
w, reject := limit.CheckLimit(user.Email,
|
||||||
sessionInbound.Source.Address.IP().String(),
|
sessionInbound.Source.Address.IP().String(),
|
||||||
network == net.Network_TCP)
|
network == net.Network_TCP,
|
||||||
|
sessionInbound.Source.Network == net.Network_TCP)
|
||||||
if reject {
|
if reject {
|
||||||
errors.LogInfo(ctx, "Limited ", user.Email, " by conn or ip")
|
errors.LogInfo(ctx, "Limited ", user.Email, " by conn or ip")
|
||||||
common.Close(outboundLink.Writer)
|
common.Close(outboundLink.Writer)
|
||||||
@@ -241,7 +242,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
|
|||||||
protocolString = resComp.ProtocolForDomainResult()
|
protocolString = resComp.ProtocolForDomainResult()
|
||||||
}
|
}
|
||||||
for _, p := range request.OverrideDestinationForProtocol {
|
for _, p := range request.OverrideDestinationForProtocol {
|
||||||
if strings.HasPrefix(protocolString, p) || strings.HasPrefix(protocolString, p) {
|
if strings.HasPrefix(protocolString, p) || strings.HasPrefix(p, protocolString) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
|
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
|
||||||
|
|||||||
19
go.mod
19
go.mod
@@ -14,12 +14,12 @@ require (
|
|||||||
github.com/goccy/go-json v0.10.3
|
github.com/goccy/go-json v0.10.3
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/juju/ratelimit v1.0.2
|
github.com/juju/ratelimit v1.0.2
|
||||||
github.com/sagernet/sing v0.5.0-alpha.12.0.20240717075530-332e47007567
|
github.com/sagernet/sing v0.5.0-alpha.15
|
||||||
github.com/sagernet/sing-box v1.10.0-alpha.22
|
github.com/sagernet/sing-box v1.10.0-alpha.29
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
github.com/spf13/viper v1.15.0
|
github.com/spf13/viper v1.15.0
|
||||||
github.com/xtls/xray-core v1.8.21-0.20240721085503-22535d864399
|
github.com/xtls/xray-core v1.8.23
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/crypto v0.25.0
|
golang.org/x/crypto v0.25.0
|
||||||
golang.org/x/sys v0.22.0
|
golang.org/x/sys v0.22.0
|
||||||
@@ -195,9 +195,9 @@ require (
|
|||||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect
|
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect
|
||||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
|
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
|
||||||
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
|
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
|
||||||
github.com/sagernet/quic-go v0.45.1-beta.2 // indirect
|
github.com/sagernet/quic-go v0.46.0-beta.2 // indirect
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
||||||
github.com/sagernet/sing-dns v0.3.0-beta.10 // indirect
|
github.com/sagernet/sing-dns v0.3.0-beta.14 // indirect
|
||||||
github.com/sagernet/sing-mux v0.2.0 // indirect
|
github.com/sagernet/sing-mux v0.2.0 // indirect
|
||||||
github.com/sagernet/sing-quic v0.2.0-beta.12 // indirect
|
github.com/sagernet/sing-quic v0.2.0-beta.12 // indirect
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
||||||
@@ -250,14 +250,14 @@ require (
|
|||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/ratelimit v0.3.0 // indirect
|
go.uber.org/ratelimit v0.3.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||||
golang.org/x/mod v0.18.0 // indirect
|
golang.org/x/mod v0.19.0 // indirect
|
||||||
golang.org/x/net v0.27.0 // indirect
|
golang.org/x/net v0.27.0 // indirect
|
||||||
golang.org/x/oauth2 v0.21.0 // indirect
|
golang.org/x/oauth2 v0.21.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/text v0.16.0 // indirect
|
golang.org/x/text v0.16.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
golang.org/x/tools v0.22.0 // indirect
|
golang.org/x/tools v0.23.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||||
google.golang.org/api v0.172.0 // indirect
|
google.golang.org/api v0.172.0 // indirect
|
||||||
@@ -273,4 +273,5 @@ require (
|
|||||||
lukechampine.com/blake3 v1.3.0 // indirect
|
lukechampine.com/blake3 v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/sagernet/sing-box v1.10.0-alpha.22 => github.com/wyx2685/sing-box_mod v1.10.0-alpha.22
|
// replace github.com/sagernet/sing-box v1.10.0-alpha.22 => /root/sing-box_mod
|
||||||
|
replace github.com/sagernet/sing-box v1.10.0-alpha.29 => github.com/wyx2685/sing-box_mod v1.10.0-alpha.29
|
||||||
|
|||||||
32
go.sum
32
go.sum
@@ -772,15 +772,15 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN
|
|||||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||||
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
||||||
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
|
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
|
||||||
github.com/sagernet/quic-go v0.45.1-beta.2 h1:zkEeCbhdFFkrxKcuIRBtXNKci/1t2J/39QSG/sPvlmc=
|
github.com/sagernet/quic-go v0.46.0-beta.2 h1:D/k9P3btgg0CvtUFVlQsUyN9GkLj0fMG59FOlEz1In8=
|
||||||
github.com/sagernet/quic-go v0.45.1-beta.2/go.mod h1:+N3FqM9DAzOWfe64uxXuBejVJwX7DeW7BslzLO6N/xI=
|
github.com/sagernet/quic-go v0.46.0-beta.2/go.mod h1:Zt3LVudHvhFRa7uO7hjtLAYJ9wFzYv4F17+LedJSw44=
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||||
github.com/sagernet/sing v0.5.0-alpha.12.0.20240717075530-332e47007567 h1:Sus0pCYn5KPOQmArXdRTtrml6XccSzV87FkFTDqATtU=
|
github.com/sagernet/sing v0.5.0-alpha.15 h1:Jqc+8MukOIdwyzAK48bK0uHmYUnfMdfGcXTxrB7OTVE=
|
||||||
github.com/sagernet/sing v0.5.0-alpha.12.0.20240717075530-332e47007567/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
github.com/sagernet/sing v0.5.0-alpha.15/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||||
github.com/sagernet/sing-dns v0.3.0-beta.10 h1:Js61EjQXVpcu2VDegWEQTH1isCcVwJju8WEHYgG4tQ0=
|
github.com/sagernet/sing-dns v0.3.0-beta.14 h1:/s+fJzYKsvLaNDt/2rjpsrDcN8wmCO2JbX6OFrl8Nww=
|
||||||
github.com/sagernet/sing-dns v0.3.0-beta.10/go.mod h1:nXE6EYMXahB5DV3AcXYbFfuorqF7tbQ86kxweSxRKM4=
|
github.com/sagernet/sing-dns v0.3.0-beta.14/go.mod h1:rscgSr5ixOPk8XM9ZMLuMXCyldEQ1nLvdl0nfv+lp00=
|
||||||
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
||||||
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
|
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
|
||||||
github.com/sagernet/sing-quic v0.2.0-beta.12 h1:BhvA5mmrDFEyDUQB5eeu+9UhF+ieyuNJ5Rsb0dAG3QY=
|
github.com/sagernet/sing-quic v0.2.0-beta.12 h1:BhvA5mmrDFEyDUQB5eeu+9UhF+ieyuNJ5Rsb0dAG3QY=
|
||||||
@@ -941,16 +941,16 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y
|
|||||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||||
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
||||||
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
||||||
github.com/wyx2685/sing-box_mod v1.10.0-alpha.22 h1:3i//NYaaut+RecZAr6rVTxqmtYiU8s61kheBIOmYquE=
|
github.com/wyx2685/sing-box_mod v1.10.0-alpha.29 h1:cHuXdIxX0OJjOVVxBIrphixy7e+zcOFauYRKvUiOS6w=
|
||||||
github.com/wyx2685/sing-box_mod v1.10.0-alpha.22/go.mod h1:tK9s5GiwC01C4Ap7RuKFchVIIa3Qv6KJGrr5pcX2zGo=
|
github.com/wyx2685/sing-box_mod v1.10.0-alpha.29/go.mod h1:zFGCBFxFY0SBoLCzpSpsI2ZkCgHCTi8h1va8WCE/kBY=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
|
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
|
||||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
||||||
github.com/xtls/xray-core v1.8.21-0.20240721085503-22535d864399 h1:oKBzkEXI6eGM7e00mGQPl23Khlj3F0XYdzGwxvb0fdY=
|
github.com/xtls/xray-core v1.8.23 h1:A8Wr50ildMYLpaNu3EiK+Stg/tps6i0h7z5Hr4f9H2k=
|
||||||
github.com/xtls/xray-core v1.8.21-0.20240721085503-22535d864399/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
github.com/xtls/xray-core v1.8.23/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
||||||
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e h1:jLIqA7M9qY31g/Nw/5htVD0DFbxmLnlFZcHKJiG3osI=
|
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e h1:jLIqA7M9qY31g/Nw/5htVD0DFbxmLnlFZcHKJiG3osI=
|
||||||
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
|
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
|
||||||
github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 h1:wtzLQJmghkSUb1YkeFphIh7ST7NNVDaVOJZSAJcjMdw=
|
github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 h1:wtzLQJmghkSUb1YkeFphIh7ST7NNVDaVOJZSAJcjMdw=
|
||||||
@@ -1047,8 +1047,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
@@ -1078,8 +1078,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -1349,8 +1349,8 @@ golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyj
|
|||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package limiter
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -129,7 +130,10 @@ func (l *Limiter) UpdateDynamicSpeedLimit(tag, uuid string, limit int, expire ti
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool) (Bucket *ratelimit.Bucket, Reject bool) {
|
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
|
// ip and conn limiter
|
||||||
if l.ConnLimiter.AddConnCount(taguuid, ip, isTcp) {
|
if l.ConnLimiter.AddConnCount(taguuid, ip, isTcp) {
|
||||||
return nil, true
|
return nil, true
|
||||||
@@ -155,23 +159,24 @@ func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool) (Bucket *rat
|
|||||||
userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit)
|
userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if noSSUDP {
|
||||||
// Store online user for device limit
|
// Store online user for device limit
|
||||||
ipMap := new(sync.Map)
|
ipMap := new(sync.Map)
|
||||||
ipMap.Store(ip, uid)
|
ipMap.Store(ip, uid)
|
||||||
// If any device is online
|
// If any device is online
|
||||||
if v, ok := l.UserOnlineIP.LoadOrStore(taguuid, ipMap); ok {
|
if v, ok := l.UserOnlineIP.LoadOrStore(taguuid, ipMap); ok {
|
||||||
ipMap := v.(*sync.Map)
|
ipMap := v.(*sync.Map)
|
||||||
// If this is a new ip
|
// If this is a new ip
|
||||||
if _, ok := ipMap.LoadOrStore(ip, uid); !ok {
|
if _, ok := ipMap.LoadOrStore(ip, uid); !ok {
|
||||||
counter := 0
|
counter := 0
|
||||||
ipMap.Range(func(key, value interface{}) bool {
|
ipMap.Range(func(key, value interface{}) bool {
|
||||||
counter++
|
counter++
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
if counter > deviceLimit && deviceLimit > 0 {
|
if counter > deviceLimit && deviceLimit > 0 {
|
||||||
ipMap.Delete(ip)
|
ipMap.Delete(ip)
|
||||||
return nil, true
|
return nil, true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
main.go
7
main.go
@@ -1,16 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"net/http"
|
|
||||||
//_ "net/http/pprof"
|
|
||||||
|
|
||||||
"github.com/InazumaV/V2bX/cmd"
|
"github.com/InazumaV/V2bX/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//内存泄漏排查
|
|
||||||
//go func() {
|
|
||||||
// http.ListenAndServe("127.0.0.1:6060", nil)
|
|
||||||
//}()
|
|
||||||
cmd.Run()
|
cmd.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user