package tunnel import ( "context" "io" "net" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) func pipe(ctx context.Context, client net.Conn, server net.Conn) (err error) { stop := make(chan bool) go func() { err = relay(client, server, stop) if err != nil { err = errors.WithStack(err) logger.Debug(ctx, "client->server error", logger.E(err)) } }() go func() { err = relay(server, client, stop) if err != nil { err = errors.WithStack(err) logger.Debug(ctx, "server->client error", logger.E(err)) } }() select { case <-stop: return err } } func relay(src net.Conn, dst net.Conn, stop chan bool) (err error) { _, err = io.Copy(dst, src) if errors.Is(err, io.EOF) { err = nil } if err != nil { err = errors.WithStack(err) } stop <- true return }