Connect via a SOCKS server in golang
The function below allows you to setup a SOCKS connection in golang. You should already have connected to the SOCKS server using net.Dial. The function will then send the required header to connect to the target address/port provides in address:port format. For example:
conn, err = net.Dial("tcp", "socksproxy:8080")
err = socks_connect(conn, "hosttoconnectto:80")
You can then communicate with the target server via the SOCKS proxy.
func socks_connect(conn net.Conn, address string) (error) {
host, portstr, err := net.SplitHostPort(address)
port, err2 := strconv.Atoi(portstr)
if err2 != nil {
return errors.New("Unable to parse port")
}
version := []byte{0x04} // socks version 4
cmd := []byte{0x01} // socks stream mode
buffer := bytes.NewBuffer([]byte{})
binary.Write(buffer, binary.BigEndian, version)
binary.Write(buffer, binary.BigEndian, cmd)
binary.Write(buffer, binary.BigEndian, uint16(port))
binary.Write(buffer, binary.BigEndian, []byte{0x00, 0x00, 0x00, 0x01})
binary.Write(buffer, binary.BigEndian, []byte{0x00})
binary.Write(buffer, binary.BigEndian, []byte(host))
binary.Write(buffer, binary.BigEndian, []byte{0x00})
binary.Write(conn, binary.BigEndian, buffer.Bytes())
data := make([]byte, 8) // socks responses are 8 bytes
count, err := conn.Read(data)
if err != nil {
return errors.New("Unable to connect to socks server.")
}
if count == 0 {
return errors.New("Unable to connect to socks server.")
}
if data[1] == 0x5a { // success
return nil
}
return errors.New("Unable to connect to socks server.")
}