mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-14 00:51:12 +03:00
108 lines
3.0 KiB
Go
108 lines
3.0 KiB
Go
package limiter
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
"github.com/sagernet/sing-box/protocol/limiter/bandwidth"
|
|
CM "github.com/sagernet/sing-box/service/manager/constant"
|
|
"github.com/sagernet/sing-box/service/node/constant"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
)
|
|
|
|
type ManagedBandwidthStrategy interface {
|
|
UpdateStrategies(strategies map[string]bandwidth.BandwidthStrategy)
|
|
}
|
|
|
|
type BandwidthLimiterManager struct {
|
|
managers map[string]*BandwidthLimiterStrategyManager
|
|
|
|
mtx sync.Mutex
|
|
}
|
|
|
|
func NewBandwidthLimiterManager() *BandwidthLimiterManager {
|
|
return &BandwidthLimiterManager{
|
|
managers: make(map[string]*BandwidthLimiterStrategyManager),
|
|
}
|
|
}
|
|
|
|
func (m *BandwidthLimiterManager) AddBandwidthLimiterStrategyManager(outbound adapter.Outbound) error {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
limiter, ok := outbound.(*bandwidth.Outbound)
|
|
if !ok {
|
|
return E.New("invalid bandwidth limiter: ", outbound.Tag())
|
|
}
|
|
strategy, ok := limiter.GetStrategy().(ManagedBandwidthStrategy)
|
|
if !ok {
|
|
return E.New("strategy for outbound ", outbound.Tag(), " is not manager")
|
|
}
|
|
m.managers[outbound.Tag()] = &BandwidthLimiterStrategyManager{
|
|
strategy: strategy,
|
|
strategiesMap: make(map[string]bandwidth.BandwidthStrategy),
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *BandwidthLimiterManager) GetBandwidthLimiterStrategyManager(tag string) (constant.BandwidthLimiterStrategyManager, bool) {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
manager, ok := m.managers[tag]
|
|
return manager, ok
|
|
}
|
|
|
|
func (m *BandwidthLimiterManager) GetBandwidthLimiterStrategyManagerTags() []string {
|
|
m.mtx.Lock()
|
|
defer m.mtx.Unlock()
|
|
tags := make([]string, 0, len(m.managers))
|
|
for tag, _ := range m.managers {
|
|
tags = append(tags, tag)
|
|
}
|
|
return tags
|
|
}
|
|
|
|
type BandwidthLimiterStrategyManager struct {
|
|
strategy ManagedBandwidthStrategy
|
|
strategiesMap map[string]bandwidth.BandwidthStrategy
|
|
|
|
mtx sync.Mutex
|
|
}
|
|
|
|
func (i *BandwidthLimiterStrategyManager) postUpdate() {
|
|
i.strategy.UpdateStrategies(i.strategiesMap)
|
|
}
|
|
|
|
func (i *BandwidthLimiterStrategyManager) UpdateBandwidthLimiter(limiter CM.BandwidthLimiter) {
|
|
i.mtx.Lock()
|
|
defer i.mtx.Unlock()
|
|
strategy, err := bandwidth.CreateStrategy(limiter.Strategy, limiter.Mode, limiter.ConnectionType, limiter.RawSpeed)
|
|
if err != nil {
|
|
return
|
|
}
|
|
i.strategiesMap[limiter.Username] = strategy
|
|
i.postUpdate()
|
|
}
|
|
|
|
func (i *BandwidthLimiterStrategyManager) UpdateBandwidthLimiters(limiters []CM.BandwidthLimiter) {
|
|
i.mtx.Lock()
|
|
defer i.mtx.Unlock()
|
|
clear(i.strategiesMap)
|
|
newStrategiesMap := make(map[string]bandwidth.BandwidthStrategy)
|
|
for _, limiter := range limiters {
|
|
strategy, err := bandwidth.CreateStrategy(limiter.Strategy, limiter.Mode, limiter.ConnectionType, limiter.RawSpeed)
|
|
if err != nil {
|
|
return
|
|
}
|
|
newStrategiesMap[limiter.Username] = strategy
|
|
}
|
|
i.strategiesMap = newStrategiesMap
|
|
i.postUpdate()
|
|
}
|
|
|
|
func (i *BandwidthLimiterStrategyManager) DeleteBandwidthLimiter(username string) {
|
|
i.mtx.Lock()
|
|
defer i.mtx.Unlock()
|
|
delete(i.strategiesMap, username)
|
|
i.postUpdate()
|
|
}
|