// package socksproxy implements a limited subset of the SOCKS 5 (RFC1928)
// protocol in the form of a pluggable Proxy object. However, this
// implementation is _not_ RFC1928 compliant, as it does not implement GSSAPI
// (which is mandated by the spec). It currently only implements CONNECT
// requests to IPv4/IPv6 addresses. It also doesn't implement any
// timeout/keepalive system for killing inactive connections.
//
// The intended use of the library is internally within Metropolis development
// environments for contacting test clusters. The code is simple and robust, but
// not really productionized (as noted above - no timeouts and no authentication
// make it a bad idea to ever expose this proxy server publicly).
//
// There are multiple other, existing Go SOCKS4/5 server implementations, but
// many of them are either not context aware, part of a larger project (and thus
// difficult to extract) or are brand new/untested/bleeding edge code.
package socksproxy

import (
	"context"
	"fmt"
	"io"
	"log"
	"net"
	"strconv"
)

// Handler should be implemented by socksproxy users to allow SOCKS connections
// to be proxied in any other way than via the HostHandler.
type Handler interface {
	// Connect is called by the server any time a SOCKS client sends a CONNECT
	// request. The function should return a ConnectResponse describing some
	// 'backend' connection, ie. the connection that will then be exposed to the
	// SOCKS client.
	//
	// Connect should return with Error set to a non-default value to abort/deny the
	// connection request.
	//
	// The underlying incoming socket is managed by the proxy server and is not
	// visible to the client. However, any sockets/connections/files opened by the
	// Handler should be cleaned up by tying them to the given context, which will
	// be canceled whenever the connection is closed.
	Connect(context.Context, *ConnectRequest) *ConnectResponse
}

// ConnectRequest represents a pending CONNECT request from a client.
type ConnectRequest struct {
	// Address is an IPv4 or IPv6 address that the client requested to connect to.
	// This address might be invalid/malformed/internal, and the Connect method
	// should sanitize it before using it.
	Address net.IP
	// Port is the TCP port number that the client requested to connect to.
	Port uint16
}

// ConnectResponse indicates a 'backend' connection that the proxy should expose
// to the client, or an error if the connection cannot be made.
type ConnectResponse struct {
	// Error will cause an error to be returned if it is anything else than the
	// default value (ReplySucceeded).
	Error Reply

	// Backend is the ReadWriteCloser that will be bridged over to the connecting
	// client if no Error is set.
	Backend io.ReadWriteCloser
	// LocalAddress is the IP address that is returned to the client as the local
	// address of the newly established backend connection.
	LocalAddress net.IP
	// LocalPort is the local TCP port number that is returned to the client as the
	// local port of the newly established backend connection.
	LocalPort uint16
}

// ConnectResponseFromConn builds a ConnectResponse from a net.Conn. This can be
// used by custom Handlers to easily return a ConnectResponse for a newly
// established net.Conn, eg. from a Dial call.
//
// An error is returned if the given net.Conn does not carry a properly formed
// LocalAddr.
func ConnectResponseFromConn(c net.Conn) (*ConnectResponse, error) {
	laddr := c.LocalAddr().String()
	host, port, err := net.SplitHostPort(laddr)
	if err != nil {
		return nil, fmt.Errorf("could not parse LocalAddr %q: %w", laddr, err)
	}
	addr := net.ParseIP(host)
	if addr == nil {
		return nil, fmt.Errorf("could not parse LocalAddr host %q as IP", host)
	}
	portNum, err := strconv.ParseUint(port, 10, 16)
	if err != nil {
		return nil, fmt.Errorf("could not parse LocalAddr port %q", port)
	}
	return &ConnectResponse{
		Backend:      c,
		LocalAddress: addr,
		LocalPort:    uint16(portNum),
	}, nil
}

type hostHandler struct{}

func (h *hostHandler) Connect(ctx context.Context, req *ConnectRequest) *ConnectResponse {
	port := fmt.Sprintf("%d", req.Port)
	addr := net.JoinHostPort(req.Address.String(), port)
	s, err := net.Dial("tcp", addr)
	if err != nil {
		log.Printf("HostHandler could not dial %q: %v", addr, err)
		return &ConnectResponse{Error: ReplyConnectionRefused}
	}
	go func() {
		<-ctx.Done()
		s.Close()
	}()
	res, err := ConnectResponseFromConn(s)
	if err != nil {
		log.Printf("HostHandler could not build response: %v", err)
		return &ConnectResponse{Error: ReplyGeneralFailure}
	}
	return res
}

var (
	// HostHandler is an unsafe SOCKS5 proxy Handler which passes all incoming
	// connections into the local network stack. The incoming addresses/ports are
	// not sanitized, and as the proxy does not perform authentication, this handler
	// is an open proxy. This handler should never be used in cases where the proxy
	// server is publicly available.
	HostHandler = &hostHandler{}
)

// Serve runs a SOCKS5 proxy server for a given Handler at a given listener.
//
// When the given context is canceled, the server will stop and the listener
// will be closed. All pending connections will also be canceled and their
// sockets closed.
func Serve(ctx context.Context, handler Handler, lis net.Listener) error {
	go func() {
		<-ctx.Done()
		lis.Close()
	}()

	for {
		con, err := lis.Accept()
		if err != nil {
			// Context cancellation will close listener socket with a generic 'use of closed
			// network connection' error, translate that back to context error.
			if ctx.Err() != nil {
				return ctx.Err()
			}
			return err
		}
		go handle(ctx, handler, con)
	}
}

// handle runs in a goroutine per incoming SOCKS connection. Its lifecycle
// corresponds to the lifecycle of a running proxy connection.
func handle(ctx context.Context, handler Handler, con net.Conn) {
	// ctxR is a per-request context, and will be canceled whenever the handler
	// exits or the server is stopped.
	ctxR, ctxRC := context.WithCancel(ctx)
	defer ctxRC()

	go func() {
		<-ctxR.Done()
		con.Close()
	}()

	// Perform method negotiation with the client.
	if err := negotiateMethod(con); err != nil {
		return
	}

	// Read request from the client and translate problems into early error replies.
	req, err := readRequest(con)
	switch err {
	case errNotConnect:
		writeReply(con, ReplyCommandNotSupported, net.IPv4(0, 0, 0, 0), 0)
		return
	case errUnsupportedAddressType:
		writeReply(con, ReplyAddressTypeNotSupported, net.IPv4(0, 0, 0, 0), 0)
		return
	case nil:
	default:
		writeReply(con, ReplyGeneralFailure, net.IPv4(0, 0, 0, 0), 0)
		return
	}

	// Ask handler.Connect for a backend.
	conRes := handler.Connect(ctxR, &ConnectRequest{
		Address: req.address,
		Port:    req.port,
	})
	// Handle programming error when returned value is nil.
	if conRes == nil {
		writeReply(con, ReplyGeneralFailure, net.IPv4(0, 0, 0, 0), 0)
		return
	}
	// Handle returned errors.
	if conRes.Error != ReplySucceeded {
		writeReply(con, conRes.Error, net.IPv4(0, 0, 0, 0), 0)
		return
	}

	// Ensure Bound.* fields are set.
	if conRes.Backend == nil || conRes.LocalAddress == nil || conRes.LocalPort == 0 {
		writeReply(con, ReplyGeneralFailure, net.IPv4(0, 0, 0, 0), 0)
		return
	}
	// Send reply.
	if err := writeReply(con, ReplySucceeded, conRes.LocalAddress, conRes.LocalPort); err != nil {
		return
	}

	// Pipe returned backend into connection.
	go func() {
		io.Copy(conRes.Backend, con)
		conRes.Backend.Close()
	}()
	io.Copy(con, conRes.Backend)
	conRes.Backend.Close()
}
