Add OpenVPN, TrustTunnel, Sudoku, inbound managers. Fixes

This commit is contained in:
Shtorm
2026-06-04 01:47:50 +03:00
parent 9b3da79c32
commit 195a33379d
164 changed files with 16665 additions and 1332 deletions

View File

@@ -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)
}

View File

@@ -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
}
}

View File

@@ -212,5 +212,5 @@ func (l *TrafficLimiter) UpdateRemainingTraffic() error {
} else {
l.new += new
}
return nil
return err
}