package main import ( "fmt" "log" "net" "os" "strings" "ben.soroos.net/tsnet-proxy/netforward" "tailscale.com/tsnet" ) var hostname = os.Args[1] type Dialer struct{ proto string; addr string; } type Forward struct{ proto string; port string; dst string; } func (dialer Dialer) Dial() (net.Conn, error) { return net.Dial(dialer.proto, dialer.addr) } func (forward Forward) Run(server *tsnet.Server, finish chan error) { ln, err := server.Listen(forward.proto, fmt.Sprint(":", forward.port)) defer ln.Close() if err != nil { finish <- err } err = netforward.Forward(Dialer { proto: forward.proto, addr: forward.dst }, ln) if err != nil { finish <- err } } func main() { if !(hostname != "") { fmt.Println("Usage: tsnet-proxy HOSTNAME FORWARDS...") os.Exit(1) } dir, valid := os.LookupEnv("RUNTIME_DIRECTORY") if !valid { log.Fatal("RUNTIME_DIRECTORY must be set") } s := &tsnet.Server{ Hostname: hostname, Dir: dir, } defer s.Close() err_chan := make(chan error) for _, arg := range os.Args[2:] { args := strings.SplitN(arg, ":", 3) proto, port, dst := args[0], args[1], args[2] go func() { Forward { proto, port, dst }.Run(s, err_chan); }(); } err := <- err_chan log.Fatal(err) }