Golang socks5 proxy client

456 views Asked by At

I'm trying to make a proxy:

I need to listen to port 1080 (socks 5), and complete a request to a destination using an external ip:port socks 5, I managed to open this connection with the external ip, but I don't know how I could complete the request to the target destination using that external ip.

could someone help me with this?

package main

import (
    "bufio"
    "errors"
    "fmt"
    "io"
    "log"
    "net"
)

const (
    ConnectCommand   = uint8(1)
    BindCommand      = uint8(2)
    AssociateCommand = uint8(3)
    ipv4Address      = uint8(1)
    fqdnAddress      = uint8(3)
    ipv6Address      = uint8(4)
)

type AddrSpec struct {
    FQDN string
    IP   net.IP
    Port int
}

func main() {
    l, err := net.Listen("tcp", "127.0.0.1:1080")
    if err != nil {
        fmt.Print(err)
    }
    defer l.Close()

    for {
        conn, err := l.Accept()
        if err != nil {
            fmt.Print(err)
        }

        go handle(conn)
    }
}

func handle(conn net.Conn) {
    defer func() {
        _ = conn.Close()
    }()

    bufConn := bufio.NewReader(conn)
    version := []byte{0}
    if _, err := bufConn.Read(version); err != nil {
        log.Fatalf("cannot read version: %s", err.Error())
    }

    if version[0] != uint8(5) {
        log.Fatalf("unsupported SOCKS version: %v", version)
    }

    socks5ExternalConn, err := net.Dial("tcp", externalSOCKS5Proxy())
    if err != nil {
        log.Printf("Connection error: %s", err.Error())
    }

    dest, err := readAddrSpec(bufConn)
    if err != nil {
    }

    // how i can send request to server with external conn?
}

func externalSOCKS5Proxy() string {
    return "externalip:externalport"
}

func readAddrSpec(r io.Reader) (*AddrSpec, error) {
    d := &AddrSpec{}

    // Get the address type
    addrType := []byte{0}
    if _, err := r.Read(addrType); err != nil {
        return nil, err
    }

    // Handle on a per type basis
    switch addrType[0] {
    case ipv4Address:
        addr := make([]byte, 4)
        if _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil {
            return nil, err
        }
        d.IP = net.IP(addr)

    case ipv6Address:
        addr := make([]byte, 16)
        if _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil {
            return nil, err
        }
        d.IP = net.IP(addr)

    case fqdnAddress:
        if _, err := r.Read(addrType); err != nil {
            return nil, err
        }
        addrLen := int(addrType[0])
        fqdn := make([]byte, addrLen)
        if _, err := io.ReadAtLeast(r, fqdn, addrLen); err != nil {
            return nil, err
        }
        d.FQDN = string(fqdn)

    default:
        return nil, errors.New("unrecognizedAddrType")
    }

    // Read the port
    port := []byte{0, 0}
    if _, err := io.ReadAtLeast(r, port, 2); err != nil {
        return nil, err
    }
    d.Port = (int(port[0]) << 8) | int(port[1])

    return d, nil
}
0

There are 0 answers