Files
tslink/main.go
T
2026-07-26 14:14:03 +08:00

108 lines
2.8 KiB
Go

package main
import (
"context"
"errors"
"flag"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"tslink/core"
)
func serviceLogic(configPath string, isTsnetDebug bool, configURL string, logger *slog.Logger) bool {
// Determine config source: URL takes priority, then file
configSource := configPath
if configURL != "" {
configSource = configURL
logger.Info("Using config URL", "url", configURL)
}
cfg, err := core.LoadConfig(configSource)
if err != nil {
logger.With(
slog.String("error", err.Error()),
).Error("Error loading config")
os.Exit(1)
}
core.SetDoHServers(cfg.DNS.DoHServers)
if len(cfg.DNS.DoHServers) > 0 {
logger.Info("DNS-over-HTTPS fallback enabled", "servers", cfg.DNS.DoHServers)
}
ctx, cancelAll := context.WithCancel(context.Background())
defer cancelAll()
logger.Info("initializing tsnet server")
srv, err := core.InitTsNet(ctx, &cfg.Core, logger, isTsnetDebug)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
logger.Debug("tsnet initialization timed out, retrying")
return false
}
logger.With(
slog.String("error", err.Error())).Error("Error initializing tsnet")
os.Exit(1)
}
logger.Info("tsnet server initialized")
core.NormalizeConnectRulesDstAddr(ctx, srv, cfg.Connect, logger)
core.StartForwarders(ctx, srv, cfg.Forward)
core.StartConnectors(ctx, srv, cfg.Connect)
core.RunLanDiscoverService(ctx, cfg.Connect, logger.With("from", "lan_service"))
core.StartPeerConnectivityDiagnostics(ctx, logger, srv, cfg.Connect)
sigHandler := make(chan os.Signal, 1)
signal.Notify(sigHandler, os.Interrupt, syscall.SIGTERM)
watchDog := core.StartTimeWatchDog(ctx, logger.With("from", "watchdog"))
go func() {
<-ctx.Done()
logger.Debug("stopping tsnet service")
_ = srv.Close() // just ignore it
}()
for {
select {
case <-sigHandler:
logger.Warn("Ctrl+C received, shutting down")
cancelAll()
time.Sleep(time.Second)
return true
case <-watchDog:
logger.Warn("WatchDog trigged, restarting service")
cancelAll()
time.Sleep(time.Second)
return false
}
}
}
func main() {
useJsonFormatLogger := flag.Bool("json-format", false, "use json format logger")
showTsnetDebugLog := flag.Bool("diagnose", false, "show tsnet debug log on level=debug")
logLevel := flag.String("level", "info", "log level (DEBUG|INFO|WARN|ERROR)")
configPath := flag.String("c", "config.toml", "path to config file")
configURL := flag.String("config-url", core.DefaultConfigURL, "URL to fetch config from (default from build ldflags)")
flag.Parse()
logger := core.NewLogger(*logLevel, *useJsonFormatLogger)
logger.Info("Starting tslink server", "level", *logLevel, "configPath", *configPath)
for {
isStopped := serviceLogic(*configPath, *showTsnetDebugLog, *configURL, logger)
if !isStopped {
logger.Warn("tslink server restart")
} else {
return
}
}
}