Files
tslink/core/forwarder.go

66 lines
1.5 KiB
Go

package core
import (
"context"
"fmt"
"log/slog"
"tailscale.com/tsnet"
)
func StartForwarders(ctx context.Context, srv *tsnet.Server, rules map[string][]ForwardRule) {
for tag, rrs := range rules {
for _, rule := range rrs {
slog.Info("starting forwarder",
slog.String("tag", tag),
slog.String("protocol", rule.Protocol),
slog.Int("tailscale_port", rule.TailscalePort),
slog.String("local_addr", rule.LocalAddr),
)
go runForwarder(ctx, srv, rule, tag)
}
}
}
func RuleLogger(rule any, tag string) *slog.Logger {
var args []any
switch r := rule.(type) {
case ForwardRule:
args = []any{
slog.String("protocol", r.Protocol),
slog.Int("tailscale_port", r.TailscalePort),
slog.String("local_addr", r.LocalAddr),
}
case ConnectRule:
args = []any{
slog.String("protocol", r.Protocol),
slog.Int("local_port", r.LocalPort),
slog.String("dst_addr", r.DstAddr),
}
if r.LocalAddr != "" {
args = append(args, slog.String("local_addr", r.LocalAddr))
}
default:
args = []any{
slog.String("type", fmt.Sprintf("%T", rule)),
}
}
if tag != "" {
args = append(args, slog.String("tag", tag))
}
return slog.With(args...)
}
func runForwarder(ctx context.Context, srv *tsnet.Server, rule ForwardRule, tag string) {
logger := RuleLogger(rule, tag)
switch rule.Protocol {
case "tcp":
runTCPForwarder(ctx, srv, rule, logger)
case "udp":
runUDPForwarder(ctx, srv, rule, logger)
default:
logger.Error("unsupported protocol, expected tcp or udp")
}
}