58 lines
1.2 KiB

package socks
import (
// Dialer is used to provided the transport of the proxy
type Dialer interface {
Dial(string) (io.ReadWriteCloser, *AddrSpec, error)
// NetDialer is a standard TCP dialer
type NetDialer struct {
// NewNetDialer creates a new dialer
func NewNetDialer() Dialer {
return &NetDialer{}
// Dial is a base TCP dialer
func (d *NetDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) {
c, err := net.Dial("tcp", address)
if err != nil {
return nil, nil, err
local := c.LocalAddr().(*net.TCPAddr)
addr := AddrSpec{IP: local.IP, Port: local.Port}
return c, &addr, nil
// ConnDialer is like NetDialer but with an existing TCP dialer already created
type ConnDialer struct {
conn net.Conn
// NewConnDialer creates a new dialer with a already created net.conn (TCP expected)
func NewConnDialer(conn net.Conn) Dialer {
return &ConnDialer{
conn: conn,
// Dial is a TCP dialer but already created
func (d *ConnDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) {
local, ok := d.conn.LocalAddr().(*net.TCPAddr)
if !ok {
return nil, nil, fmt.Errorf("not a tcp connection")
addr := AddrSpec{IP: local.IP, Port: local.Port}
return d.conn, &addr, nil