Files
free-turn-proxy/cmd/client/main.go
T

100 lines
2.7 KiB
Go

package main
import (
"context"
"errors"
"flag"
"fmt"
"log"
"os"
"github.com/samosvalishe/free-turn-proxy/internal/clientid"
"github.com/samosvalishe/free-turn-proxy/internal/config"
"github.com/samosvalishe/free-turn-proxy/internal/logx"
"github.com/samosvalishe/free-turn-proxy/internal/provider/vk"
"github.com/samosvalishe/free-turn-proxy/internal/proxy/udprelay"
"github.com/samosvalishe/free-turn-proxy/internal/session"
"github.com/samosvalishe/free-turn-proxy/internal/shutdown"
"github.com/samosvalishe/free-turn-proxy/internal/sub"
"github.com/samosvalishe/free-turn-proxy/internal/tunnel"
"github.com/samosvalishe/free-turn-proxy/internal/wire/rtpopus"
)
// version is populated at build time via -ldflags "-X main.version=...".
var version = "dev"
func main() {
args := os.Args[1:]
// Резолв подписки до парсинга даёт обязательный peer для валидации.
if subURL := config.PeekSubURL(args); subURL != "" {
sub.SetLogger(logx.New(false))
s, ferr := sub.Fetch(context.Background(), subURL)
if ferr != nil {
log.Fatalf("failed to fetch subscription: %v", ferr)
}
if len(s.Nodes) == 0 || s.Nodes[0].URI == nil {
log.Fatalf("no nodes found in subscription")
}
args = append(args, s.Nodes[0].URI.String())
}
cfg, err := config.ParseClient(args, os.Stderr)
if err != nil {
if errors.Is(err, flag.ErrHelp) {
os.Exit(0)
}
log.Fatalf("%v", err)
}
if cfg.Obf.GenKey {
key, gerr := rtpopus.GenKeyHex()
if gerr != nil {
log.Fatalf("gen-obf-key: %v", gerr)
}
fmt.Println(key)
return
}
logger := logx.New(cfg.Log.Debug)
logger.Infof("Free Turn Proxy client version=%s", version)
idPaths := clientid.DefaultPaths()
id, persisted, err := clientid.Resolve(cfg.ClientID, idPaths)
if err != nil {
logger.Errorf("%v", err)
os.Exit(1)
}
if !persisted {
logger.Warnf("client ID не сохранён ни по одному пути (%v) - будет новым при следующем запуске", idPaths)
}
cfg.ClientID = id
logger.Infof("Client ID: %s", cfg.ClientID)
if cfg.Tunnel.Enabled() {
logger.Warnf("ссылка содержит конфиг %s: CLI встроенный туннель не поднимает, запустите WireGuard/AmneziaWG отдельно", cfg.Tunnel.Mode)
cfg.Tunnel.Mode = tunnel.ModeNone
}
ctx, stop := shutdown.Watch(context.Background(), logger)
defer stop()
sess, err := session.New(cfg, session.Deps{
Logger: logger,
Solver: vk.DefaultManualSolver,
})
if err != nil {
logger.Errorf("%v", err)
os.Exit(1)
}
if err := sess.Run(ctx); err != nil {
if errors.Is(err, udprelay.ErrFatal) {
logger.Errorf("fatal: %v", err)
} else {
logger.Errorf("%v", err)
}
os.Exit(1)
}
}