mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
fix: устранены блокеры линтера в obf/multi
errcheck nolint на bufPool.Get в rtpopus3/listen.go; multi.MultiProvider переименован в multi.Provider (revive stutter), дедуп vk.New в buildProvider.
This commit is contained in:
+14
-28
@@ -130,14 +130,9 @@ func main() {
|
||||
return c.User, c.Pass, c.ServerAddrs, nil
|
||||
}
|
||||
|
||||
// При нескольких звонках (links) расширяем пул: каждый звонок даёт
|
||||
// cfg.TURN.N стримов, все объединяются в общий SessionPool.
|
||||
// Это даёт больше TURN-соединений → выше aggregate пропускная способность.
|
||||
numLinks := len(cfg.VK.Links)
|
||||
if numLinks < 1 {
|
||||
numLinks = 1
|
||||
}
|
||||
totalStreams := cfg.TURN.N * numLinks
|
||||
// Несколько -links расширяют пул: каждый звонок даёт cfg.TURN.N стримов,
|
||||
// все объединяются в общий пул (больше параллельных TURN-аллокаций).
|
||||
totalStreams := cfg.TURN.N * max(len(cfg.VK.Links), 1)
|
||||
|
||||
if cfg.Proxy.Mode != config.ProxyModeUDP {
|
||||
tcpDtlsDialer := &dtlsdial.Dialer{
|
||||
@@ -192,32 +187,16 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// buildProvider выбирает реализацию provider.Provider по cfg.Provider.Name.
|
||||
// При нескольких -links создаёт MultiProvider с одним vk.Provider на каждый link.
|
||||
// buildProvider строит provider.Provider по cfg.Provider.Name. Одна -links даёт
|
||||
// обычный vk.Provider; несколько - multi.Provider (один vk.Provider на ссылку).
|
||||
func buildProvider(cfg *config.Client, dialer net.Dialer, connected *atomic.Int32, logger logx.Logger) (provider.Provider, error) {
|
||||
switch cfg.Provider.Name {
|
||||
case config.ProviderVK:
|
||||
if len(cfg.VK.Links) == 0 {
|
||||
return nil, fmt.Errorf("vk: no links configured")
|
||||
}
|
||||
// Одна ссылка — обычный vk.Provider (backward compat).
|
||||
if len(cfg.VK.Links) == 1 {
|
||||
newVK := func(link string) (provider.Provider, error) {
|
||||
return vk.New(vk.Config{
|
||||
Link: cfg.VK.Links[0],
|
||||
Dialer: dialer,
|
||||
ManualOnly: cfg.VK.ManualCaptcha,
|
||||
Browser: string(cfg.VK.Browser),
|
||||
StreamsPerCache: cfg.VK.StreamsPerCred,
|
||||
StreamsAlive: connected.Load,
|
||||
Log: logger,
|
||||
Debug: cfg.Log.Debug,
|
||||
}, vk.DefaultManualSolver)
|
||||
}
|
||||
// Несколько ссылок — MultiProvider. Каждый звонок даёт свой пул
|
||||
// TURN-реквизитов → больше параллельных стримов.
|
||||
providers := make([]provider.Provider, 0, len(cfg.VK.Links))
|
||||
for i, link := range cfg.VK.Links {
|
||||
p, err := vk.New(vk.Config{
|
||||
Link: link,
|
||||
Dialer: dialer,
|
||||
ManualOnly: cfg.VK.ManualCaptcha,
|
||||
@@ -227,12 +206,19 @@ func buildProvider(cfg *config.Client, dialer net.Dialer, connected *atomic.Int3
|
||||
Log: logger,
|
||||
Debug: cfg.Log.Debug,
|
||||
}, vk.DefaultManualSolver)
|
||||
}
|
||||
if len(cfg.VK.Links) == 1 {
|
||||
return newVK(cfg.VK.Links[0])
|
||||
}
|
||||
providers := make([]provider.Provider, 0, len(cfg.VK.Links))
|
||||
for i, link := range cfg.VK.Links {
|
||||
p, err := newVK(link)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("vk provider [%d]: %w", i, err)
|
||||
}
|
||||
providers = append(providers, p)
|
||||
}
|
||||
logger.Infof("created MultiProvider with %d VK links (%d total streams)", len(providers), cfg.TURN.N*len(providers))
|
||||
logger.Infof("multi-provider: %d VK links, %d total streams", len(providers), cfg.TURN.N*len(providers))
|
||||
return multi.New(providers), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown provider %q", cfg.Provider.Name)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Package multi - MultiProvider: объединяет несколько provider.Provider
|
||||
// в один, распределяя streamID по всем провайдерам round-robin.
|
||||
// Позволяет использовать несколько VK-звонков одновременно для пула TURN-стримов.
|
||||
// Package multi объединяет несколько provider.Provider в один, распределяя
|
||||
// streamID по вложенным провайдерам round-robin. Применение: несколько
|
||||
// VK-звонков как единый пул TURN-стримов (больше параллельных аллокаций).
|
||||
package multi
|
||||
|
||||
import (
|
||||
@@ -10,102 +10,58 @@ import (
|
||||
"github.com/samosvalishe/free-turn-proxy/internal/provider"
|
||||
)
|
||||
|
||||
// TCP mode (-mode tcp):
|
||||
// Локальный TCP-поток (Xray)
|
||||
//
|
||||
// │
|
||||
// ├─ без bond: pool.Pick() → round-robin по всем 30 smux-сессиям
|
||||
// └─ с bond: bondclient.Handle → страйпинг по всем 30 сессиям
|
||||
// │
|
||||
// │ Каждая smux-сессия:
|
||||
// │ DTLS → KCP → TURN allocate → Server DTLS
|
||||
// │
|
||||
// ▼
|
||||
// Backend (Xray TCP)
|
||||
//
|
||||
// UDP mode (-mode udp):
|
||||
// Локальный UDP (WireGuard)
|
||||
//
|
||||
// │
|
||||
// ▼
|
||||
// inboundChan → broadcast во все 30 DTLS-стримов
|
||||
// │
|
||||
// │ Каждый DTLS-стрим:
|
||||
// │ (DTLS) → OBF → TURN allocate → Server DTLS
|
||||
// │
|
||||
// ▼
|
||||
// Backend (WireGuard UDP)
|
||||
//
|
||||
// MultiProvider распределяет streamID по вложенным провайдерам.
|
||||
// StreamID 1-based: (streamID-1) % n → выбор провайдера.
|
||||
// Внутренний streamID: ((streamID-1) / n) + 1 → передаётся выбранному провайдеру.
|
||||
//
|
||||
// Например, 3 провайдера × 10 стримов = 30 стримов:
|
||||
//
|
||||
// streamID 1,4,7,10,13,16,19,22,25,28 → provider[0] (internal 1..10)
|
||||
// streamID 2,5,8,11,14,17,20,23,26,29 → provider[1] (internal 1..10)
|
||||
// streamID 3,6,9,12,15,18,21,24,27,30 → provider[2] (internal 1..10)
|
||||
type MultiProvider struct {
|
||||
// Provider распределяет 1-based streamID round-robin: провайдер = (streamID-1) % n,
|
||||
// внутренний streamID = ((streamID-1) / n) + 1 (биекция, без коллизий).
|
||||
// Без изменяемого состояния - thread-safe.
|
||||
type Provider struct {
|
||||
providers []provider.Provider
|
||||
n int
|
||||
}
|
||||
|
||||
// New создаёт MultiProvider. Паникует если providers пуст.
|
||||
func New(providers []provider.Provider) *MultiProvider {
|
||||
func New(providers []provider.Provider) *Provider {
|
||||
if len(providers) == 0 {
|
||||
panic("multi: empty providers")
|
||||
}
|
||||
return &MultiProvider{
|
||||
providers: providers,
|
||||
n: len(providers),
|
||||
}
|
||||
return &Provider{providers: providers, n: len(providers)}
|
||||
}
|
||||
|
||||
// providerFor возвращает провайдера и внутренний streamID для глобального streamID.
|
||||
func (m *MultiProvider) providerFor(streamID int) (provider.Provider, int) {
|
||||
func (m *Provider) providerFor(streamID int) (provider.Provider, int) {
|
||||
idx := (streamID - 1) % m.n
|
||||
innerID := ((streamID - 1) / m.n) + 1
|
||||
return m.providers[idx], innerID
|
||||
}
|
||||
|
||||
// GetCredentials делегирует выбранному провайдеру.
|
||||
func (m *MultiProvider) GetCredentials(ctx context.Context, streamID int) (provider.Credentials, error) {
|
||||
func (m *Provider) GetCredentials(ctx context.Context, streamID int) (provider.Credentials, error) {
|
||||
p, innerID := m.providerFor(streamID)
|
||||
return p.GetCredentials(ctx, innerID)
|
||||
}
|
||||
|
||||
// IsAuthError делегирует первому провайдеру (все VK провайдеры используют
|
||||
// одинаковую эвристику auth-ошибки — проверку строки ошибки).
|
||||
func (m *MultiProvider) IsAuthError(err error) bool {
|
||||
// IsAuthError делегирует первому провайдеру: все вложенные однотипны (VK).
|
||||
func (m *Provider) IsAuthError(err error) bool {
|
||||
return m.providers[0].IsAuthError(err)
|
||||
}
|
||||
|
||||
// HandleAuthError делегирует провайдеру, соответствующему streamID.
|
||||
func (m *MultiProvider) HandleAuthError(streamID int) bool {
|
||||
func (m *Provider) HandleAuthError(streamID int) bool {
|
||||
p, innerID := m.providerFor(streamID)
|
||||
return p.HandleAuthError(innerID)
|
||||
}
|
||||
|
||||
// ResetErrors делегирует провайдеру, соответствующему streamID.
|
||||
func (m *MultiProvider) ResetErrors(streamID int) {
|
||||
func (m *Provider) ResetErrors(streamID int) {
|
||||
p, innerID := m.providerFor(streamID)
|
||||
p.ResetErrors(innerID)
|
||||
}
|
||||
|
||||
// BackoffUntilUnix возвращает максимальный backoff среди всех провайдеров.
|
||||
// Консервативно: если хотя бы один провайдер в блокировке, все стримы
|
||||
// делают короткую паузу вместо tight-spin.
|
||||
func (m *MultiProvider) BackoffUntilUnix() int64 {
|
||||
var max int64
|
||||
// BackoffUntilUnix - максимум среди провайдеров (один в блокировке -> пауза для всех).
|
||||
func (m *Provider) BackoffUntilUnix() int64 {
|
||||
var until int64
|
||||
for _, p := range m.providers {
|
||||
if v := p.BackoffUntilUnix(); v > max {
|
||||
max = v
|
||||
if v := p.BackoffUntilUnix(); v > until {
|
||||
until = v
|
||||
}
|
||||
}
|
||||
return max
|
||||
return until
|
||||
}
|
||||
|
||||
// Name возвращает "multi(N)".
|
||||
func (m *MultiProvider) Name() string {
|
||||
func (m *Provider) Name() string {
|
||||
return fmt.Sprintf("multi(%d)", m.n)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ type packetConn struct {
|
||||
}
|
||||
|
||||
func (c *packetConn) ReadFrom(p []byte) (int, net.Addr, error) {
|
||||
bp := bufPool.Get().(*[]byte)
|
||||
bp := bufPool.Get().(*[]byte) //nolint:errcheck // pool New always returns *[]byte
|
||||
buf := *bp
|
||||
need := len(p) + overhead
|
||||
if cap(buf) < need {
|
||||
@@ -86,7 +86,7 @@ func (c *packetConn) ReadFrom(p []byte) (int, net.Addr, error) {
|
||||
func (c *packetConn) WriteTo(p []byte, addr net.Addr) (int, error) {
|
||||
wireLen := overhead + len(p)
|
||||
|
||||
bp := bufPool.Get().(*[]byte)
|
||||
bp := bufPool.Get().(*[]byte) //nolint:errcheck // pool New always returns *[]byte
|
||||
out := *bp
|
||||
if cap(out) < wireLen {
|
||||
out = make([]byte, wireLen)
|
||||
|
||||
Reference in New Issue
Block a user