mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
ee30afc922
Тот же DTLS с обфускацией, сервер не меняется. По умолчанию один поток.
95 lines
3.0 KiB
Go
95 lines
3.0 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"sync/atomic"
|
|
|
|
"github.com/samosvalishe/free-turn-proxy/internal/config"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/logx"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/provider"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/provider/multi"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/provider/vk"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/proxy/allocpace"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/proxy/udprelay"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/transport/turndial"
|
|
)
|
|
|
|
func (s *Session) link(dialer net.Dialer, peer *net.UDPAddr) (udprelay.AuthHandler, udprelay.DialFunc, error) {
|
|
log := s.deps.Logger
|
|
if s.cfg.Provider.Name == config.ProviderDirect {
|
|
log.Infof("provider=%s", config.ProviderDirect)
|
|
return udprelay.NopAuth{}, func(ctx context.Context, _ int) (*turndial.Stream, error) {
|
|
return turndial.Direct(ctx, peer)
|
|
}, nil
|
|
}
|
|
|
|
prov, err := buildProvider(s.cfg, dialer, &s.connected, s.deps.Solver, log, s.total)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
log.Infof("provider=%s", prov.Name())
|
|
getCreds := func(ctx context.Context, streamID int) (string, string, []string, error) {
|
|
c, err := prov.GetCredentials(ctx, streamID)
|
|
if err != nil {
|
|
return "", "", nil, err
|
|
}
|
|
return c.User, c.Pass, c.ServerAddrs, nil
|
|
}
|
|
pacer := allocpace.New(allocpace.DefaultInterval)
|
|
turn := s.cfg.TURN
|
|
return prov, func(ctx context.Context, streamID int) (*turndial.Stream, error) {
|
|
if !pacer.Wait(ctx) {
|
|
return nil, ctx.Err()
|
|
}
|
|
return udprelay.DialTURN(ctx, turn.Host, turn.Port, turn.TransportUDP, peer, streamID, getCreds, log)
|
|
}, nil
|
|
}
|
|
|
|
// buildProvider создаёт экземпляр provider.Provider в зависимости от конфигурации.
|
|
func buildProvider(
|
|
cfg *config.Client,
|
|
dialer net.Dialer,
|
|
connected *atomic.Int32,
|
|
solver vk.ManualSolverFunc,
|
|
logger logx.Logger,
|
|
total int,
|
|
) (provider.Provider, error) {
|
|
switch cfg.Provider.Name {
|
|
case config.ProviderVK:
|
|
if len(cfg.VK.Links) == 0 {
|
|
return nil, fmt.Errorf("vk: no links configured")
|
|
}
|
|
newVK := func(link string) (provider.Provider, error) {
|
|
return vk.New(vk.Config{
|
|
Link: link,
|
|
Dialer: dialer,
|
|
ManualOnly: cfg.VK.ManualCaptcha,
|
|
Platform: string(cfg.VK.Platform),
|
|
StreamsPerCache: cfg.VK.StreamsPerCred,
|
|
StreamsAlive: connected.Load,
|
|
FingerprintSeed: cfg.ClientID,
|
|
StatePaths: vk.DefaultStatePaths(),
|
|
Log: logger,
|
|
Debug: cfg.Log.Debug,
|
|
}, solver)
|
|
}
|
|
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("multi-provider: %d VK links, %d total streams", len(providers), total)
|
|
return multi.New(providers), nil
|
|
default:
|
|
return nil, fmt.Errorf("unknown provider %q", cfg.Provider.Name)
|
|
}
|
|
}
|