mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-06-09 21:08:15 +03:00
Add OpenVPN, TrustTunnel, Sudoku, inbound managers. Fixes
This commit is contained in:
@@ -2,6 +2,7 @@ package limiter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -50,6 +51,7 @@ func (m *BandwidthLimiterManager) AddBandwidthLimiterStrategyManager(outbound ad
|
||||
manager: m,
|
||||
strategy: strategy,
|
||||
strategiesMap: make(map[string]bandwidth.BandwidthStrategy),
|
||||
limitersMap: make(map[string]CM.BandwidthLimiter),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -75,6 +77,7 @@ type BandwidthLimiterStrategyManager struct {
|
||||
manager *BandwidthLimiterManager
|
||||
strategy ManagedBandwidthStrategy
|
||||
strategiesMap map[string]bandwidth.BandwidthStrategy
|
||||
limitersMap map[string]CM.BandwidthLimiter
|
||||
|
||||
mtx sync.Mutex
|
||||
}
|
||||
@@ -86,12 +89,25 @@ func (i *BandwidthLimiterStrategyManager) postUpdate() {
|
||||
func (i *BandwidthLimiterStrategyManager) UpdateBandwidthLimiter(limiter CM.BandwidthLimiter) {
|
||||
i.mtx.Lock()
|
||||
defer i.mtx.Unlock()
|
||||
if existing, ok := i.strategiesMap[limiter.Username]; ok {
|
||||
oldLimiter := i.limitersMap[limiter.Username]
|
||||
if isSameStrategy(oldLimiter, limiter) {
|
||||
if oldLimiter.RawSpeed != limiter.RawSpeed {
|
||||
if s, ok := existing.(bandwidth.SpeedUpdater); ok {
|
||||
s.SetSpeed(limiter.RawSpeed)
|
||||
}
|
||||
}
|
||||
i.limitersMap[limiter.Username] = limiter
|
||||
return
|
||||
}
|
||||
}
|
||||
strategy, err := bandwidth.CreateStrategy(limiter.Strategy, limiter.Mode, limiter.ConnectionType, limiter.RawSpeed, limiter.FlowKeys)
|
||||
if err != nil {
|
||||
i.manager.logger.ErrorContext(i.manager.ctx, err)
|
||||
return
|
||||
}
|
||||
i.strategiesMap[limiter.Username] = strategy
|
||||
i.limitersMap[limiter.Username] = limiter
|
||||
i.postUpdate()
|
||||
}
|
||||
|
||||
@@ -118,3 +134,10 @@ func (i *BandwidthLimiterStrategyManager) DeleteBandwidthLimiter(username string
|
||||
delete(i.strategiesMap, username)
|
||||
i.postUpdate()
|
||||
}
|
||||
|
||||
func isSameStrategy(a, b CM.BandwidthLimiter) bool {
|
||||
return a.Strategy == b.Strategy &&
|
||||
a.Mode == b.Mode &&
|
||||
a.ConnectionType == b.ConnectionType &&
|
||||
slices.Equal(a.FlowKeys, b.FlowKeys)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/onclose"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/protocol/limiter/connection"
|
||||
CM "github.com/sagernet/sing-box/service/manager/constant"
|
||||
@@ -45,7 +46,7 @@ func (m *ConnectionLimiterManager) AddConnectionLimiterStrategyManager(outbound
|
||||
}
|
||||
strategy, ok := limiter.GetStrategy().(ManagedConnectionStrategy)
|
||||
if !ok {
|
||||
return E.New("strategy ", strategy, " is not manager")
|
||||
return E.New("strategy for outbound ", outbound.Tag(), " is not manager")
|
||||
}
|
||||
m.managers[outbound.Tag()] = &ConnectionLimiterStrategyManager{
|
||||
manager: m,
|
||||
@@ -152,7 +153,7 @@ type ManagerLock struct {
|
||||
func (i *ConnectionLimiterStrategyManager) newManagerLock(limiterId int) connection.LockIDGetter {
|
||||
conns := make(map[string]*ManagerLock)
|
||||
mtx := sync.Mutex{}
|
||||
return func(id string) (connection.CloseHandlerFunc, context.Context, error) {
|
||||
return func(id string) (onclose.CloseHandlerFunc, context.Context, error) {
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
conn, ok := conns[id]
|
||||
@@ -171,6 +172,7 @@ func (i *ConnectionLimiterStrategyManager) newManagerLock(limiterId int) connect
|
||||
case <-time.After(time.Second * 5):
|
||||
err := nodeManager.RefreshLock(limiterId, id, handleId)
|
||||
if err != nil {
|
||||
i.manager.logger.ErrorContext(ctx, "failed to refresh lock: ", err)
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
@@ -185,18 +187,17 @@ func (i *ConnectionLimiterStrategyManager) newManagerLock(limiterId int) connect
|
||||
conns[id] = conn
|
||||
}
|
||||
conn.handles++
|
||||
var once sync.Once
|
||||
return func() {
|
||||
once.Do(func() {
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
conn.handles--
|
||||
if conn.handles == 0 {
|
||||
conn.cancel()
|
||||
i.manager.nodeManager.ReleaseLock(limiterId, id, conn.handleId)
|
||||
delete(conns, id)
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
conn.handles--
|
||||
if conn.handles == 0 {
|
||||
conn.cancel()
|
||||
if err := i.manager.nodeManager.ReleaseLock(limiterId, id, conn.handleId); err != nil {
|
||||
i.manager.logger.ErrorContext(i.manager.ctx, "failed to release lock: ", err)
|
||||
}
|
||||
})
|
||||
delete(conns, id)
|
||||
}
|
||||
}, conn.ctx, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,5 +212,5 @@ func (l *TrafficLimiter) UpdateRemainingTraffic() error {
|
||||
} else {
|
||||
l.new += new
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user