package untls import ( "crypto/tls" "fmt" "io" "log/slog" "net" "os" g "gobang" ) type _CLIArgs struct { certFile string keyFile string fromAddr string toAddr string } var emitActiveConnection = g.MakeGauge("active-connections") const X = 1 func parseArgs(args []string) _CLIArgs { if len(args) != 5 { fmt.Fprintf( os.Stderr, "Usage: %s CERT.pem PRIVKEY.pem FROM.socket TO.socket\n", args[0], ) os.Exit(2) } return _CLIArgs { certFile: args[1], keyFile: args[2], fromAddr: args[3], toAddr: args[4], } } func listen(certFile string, keyFile string, fromAddr string) net.Listener { certificate, err := tls.LoadX509KeyPair(certFile, keyFile) g.FatalIf(err) config := &tls.Config { MinVersion: tls.VersionTLS13, Certificates: []tls.Certificate { certificate, }, } listener, err := tls.Listen("unix", fromAddr, config) g.FatalIf(err) g.Info("Started listening", "listen-start", "from-address", fromAddr) return listener } func copyData(c chan struct {}, from io.Reader, to io.WriteCloser) { io.Copy(to, from) c <- struct {} {} // connection is closed, send signal to stop proxy FIXME } func start(toAddr string, listener net.Listener) { for { connFrom, err := listener.Accept() if err != nil { g.Warning( "Error accepting connection", "accept-connection-error", "err", err, ) continue } defer connFrom.Close() emitActiveConnection.Inc() connTo, err := net.Dial("unix", toAddr) if err != nil { g.Warning( "Error dialing connection", "dial-connection-error", "err", err, ) continue } defer connTo.Close() c := make(chan struct {}) go copyData(c, connFrom, connTo) go copyData(c, connTo, connFrom) go func() { <- c emitActiveConnection.Dec() }() } } func Main() { g.Init(slog.Group("versions", "gobang", g.Version, "this", Version)) args := parseArgs(os.Args) listener := listen(args.certFile, args.keyFile, args.fromAddr) start(args.toAddr, listener) }