Documentation
¶
Overview ¶
Package socksgo implements SOCKS proxy client and server (SOCKS4, SOCKS4a, SOCKS5) with extensions for Gost and Tor compatibility.
Index ¶
- Variables
- func GetTestListenCloseHook() func(net.Conn)
- func GetTestListenSmuxHook() func() error
- func GetTestLookupAddrHook() func(protocol.Addr) protocol.Addr
- func GetTestLookupIPHook() func(protocol.Addr) protocol.Addr
- func GetTestRequestHook() ...
- func LoopbackFilter(_, address string) bool
- func MatchAllFilter(_, _ string) bool
- func PassAllFilter(_, _ string) bool
- func ResetTestHooks()
- func SetTestListenCloseHook(hook func(net.Conn))
- func SetTestListenSmuxHook(hook func() error)
- func SetTestLookupAddrHook(hook func(protocol.Addr) protocol.Addr)
- func SetTestLookupIPHook(hook func(protocol.Addr) protocol.Addr)
- func SetTestRequestHook(...)
- func TestAddrFromFQDN(fqdn string, port uint16, network string) protocol.Addr
- func TestAddrFromIP(ip net.IP, port uint16, network string) protocol.Addr
- type AddrDisallowedError
- type Client
- func ClientFromENV(scheme string) (*Client, error)
- func ClientFromENVSafe(scheme string) (*Client, error)
- func ClientFromURL(urlstr string) (*Client, error)
- func ClientFromURLObj(u *url.URL) *Client
- func ClientFromURLObjSafe(u *url.URL) *Client
- func ClientFromURLSafe(urlstr string) (*Client, error)
- func ClientNoProxy() *Client
- func (c *Client) CheckNetworkSupport(net string) error
- func (c *Client) Connect(ctx context.Context) (conn net.Conn, err error)
- func (c *Client) Dial(ctx context.Context, network, address string) (net.Conn, error)
- func (c *Client) DialPacket(ctx context.Context, network, address string) (PacketConn, error)
- func (c *Client) DoFilter(network, address string) bool
- func (c *Client) GetAddr() string
- func (c *Client) GetDialer() Dialer
- func (c *Client) GetHandshakeTimeout() time.Duration
- func (c *Client) GetListener() Listener
- func (c *Client) GetNet() string
- func (c *Client) GetPacketDialer() PacketDialer
- func (c *Client) GetPacketListener() PacketListener
- func (c *Client) GetResolver() Resolver
- func (c *Client) GetTLSConfig() (config *tls.Config)
- func (c *Client) GetWsDialer() *websocket.Dialer
- func (c *Client) IsNoProxy() bool
- func (c *Client) IsTLS() bool
- func (c *Client) IsUDPAllowed() bool
- func (c *Client) Listen(ctx context.Context, network, address string) (net.Listener, error)
- func (c *Client) ListenPacket(ctx context.Context, network, address string) (PacketConn, error)
- func (c *Client) LookupAddr(ctx context.Context, address string) ([]string, error)
- func (c *Client) LookupIP(ctx context.Context, network, address string) ([]net.IP, error)
- func (c *Client) Request(ctx context.Context, cmd protocol.Cmd, address protocol.Addr) (proxy net.Conn, addr protocol.Addr, err error)
- func (c *Client) Version() string
- func (c *Client) WithTorIsolation(id *string) *Client
- type CommandHandler
- type Dialer
- type Filter
- type Listener
- type NilHandlerError
- type PacketConn
- type PacketDialer
- type PacketListener
- type RejectdError
- type Resolver
- type Server
- func (s *Server) Accept(ctx context.Context, conn net.Conn, isTLS bool) (err error)
- func (s *Server) AcceptWS(ctx context.Context, conn *websocket.Conn, isTLS bool) error
- func (s *Server) CheckBothAddr(laddr, raddr *protocol.Addr) error
- func (s *Server) CheckLaddr(laddr *protocol.Addr) error
- func (s *Server) CheckRaddr(raddr *protocol.Addr) error
- func (s *Server) CheckUseIDENT(user string, clientAddr net.Addr) bool
- func (s *Server) GetAuth() *protocol.AuthHandlers
- func (s *Server) GetDefaultListenHost() string
- func (s *Server) GetDialer() Dialer
- func (s *Server) GetHandler(cmd protocol.Cmd) *CommandHandler
- func (s *Server) GetHandshakeTimeout() time.Duration
- func (s *Server) GetListener() Listener
- func (s *Server) GetPacketDialer() PacketDialer
- func (s *Server) GetPacketListener() PacketListener
- func (s *Server) GetPool() bufpool.Pool
- func (s *Server) GetResolver() Resolver
- func (s *Server) GetSmux() *smux.Config
- func (s *Server) GetUDPBufferSize() int
- func (s *Server) GetUDPTimeout() time.Duration
- func (s *Server) IsPreferIPv4() bool
- func (s *Server) ListenForAssoc(ctx context.Context, ctrl net.Conn) (assoc PacketConn, err error)
- type UnknownSocksVersionError
- type UnsupportedAddrError
- type UnsupportedCommandError
- type WebSocketConfig
- type WrongNetworkError
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUDPDisallowed is returned when attempting plaintext UDP over TLS/WSS // proxies without the insecureudp option enabled. ErrUDPDisallowed = errors.New( "plaintext UDP is disallowed for tls/wss proxies", ) // ErrResolveDisabled is returned when Tor lookup extension is requested // but not enabled on the client. ErrResolveDisabled = errors.New( "tor resolve extension for socks is disabled", ) // ErrWrongAddrInLookupResponse is returned when a Tor resolve response // contains an unexpected address type. ErrWrongAddrInLookupResponse = errors.New( "wrong addr type in lookup response", ) // ErrClientAuthFailed is returned when client authentication fails. ErrClientAuthFailed = errors.New("client auth failed") )
Client-side error variables.
var DefaultBindHandler = CommandHandler{ Socks4: true, Socks5: true, TLSCompat: true, Handler: func( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) error { pool := server.GetPool() addr = addr.WithDefaultHost(server.GetDefaultListenHost()) err := server.CheckLaddr(&addr) if err != nil { protocol.Reject(ver, conn, protocol.DisallowReply, pool) return err } tcp := "tcp" if ver == "4" || ver == "4a" { tcp = "tcp4" } listener, err := server.GetListener()(ctx, tcp, addr.ToHostPort()) if err != nil { protocol.Reject(ver, conn, errorToReplyStatus(err), pool) return err } defer func() { _ = listener.Close() }() err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromNetAddr(listener.Addr()), pool, ) if err != nil { return err } proxy, err := listener.Accept() if err != nil { return err } err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromNetAddr(proxy.RemoteAddr()), pool, ) if err != nil { return err } return protocol.PipeConn(conn, proxy) }, }
DefaultBindHandler handles the BIND command.
DefaultBindHandler creates a TCP listener on the proxy server that forwards incoming connections to the client.
Protocol Support ¶
- SOCKS4: Yes
- SOCKS4a: Yes
- SOCKS5: Yes
- TLS: Yes
Behavior ¶
- Applies default listen host if address is unspecified
- Validates local address against LaddrFilter
- Creates TCP listener on requested address
- Sends first reply with bound address (listener.Addr())
- Waits for single incoming connection
- Sends second reply with remote address (incoming client)
- Pipes data bidirectionally
Two-Reply Protocol ¶
BIND uses a two-reply protocol:
- First reply: Contains the address where the client should direct the peer to connect (listener address)
- Second reply: Contains the address of the incoming connection (after Accept returns)
Use Cases ¶
BIND is used for protocols that require reverse connections:
- FTP passive mode
- Remote debugging
- Any protocol requiring server-to-client connections
Reply ¶
Sends success reply (0x00) with:
- First reply: Listener address
- Second reply: Incoming connection's remote address
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- FailReply (0x01): Listen failed
Examples ¶
// Default handler is used automatically
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- RFC 1928: SOCKS5 Protocol (Section 4)
- protocol.PipeConn: Connection piping implementation
- server_handler_mbind.go: Gost multiplexed BIND
var DefaultCommandHandlers = map[protocol.Cmd]CommandHandler{ protocol.CmdConnect: DefaultConnectHandler, protocol.CmdBind: DefaultBindHandler, protocol.CmdUDPAssoc: DefaultUDPAssocHandler, protocol.CmdTorResolve: DefaultResolveHandler, protocol.CmdTorResolvePtr: DefaultResolvePtrHandler, protocol.CmdGostUDPTun: DefaultGostUDPTUNHandler, protocol.CmdGostMuxBind: DefaultGostMBindHandler, }
DefaultCommandHandlers is the default map of command handlers.
DefaultCommandHandlers provides standard implementations for all supported SOCKS commands:
- CmdConnect: Forward TCP connections
- CmdBind: Listen for incoming connections (BIND)
- CmdUDPAssoc: UDP association (standard SOCKS5)
- CmdTorResolve: Forward DNS lookup (Tor extension)
- CmdTorResolvePtr: Reverse DNS lookup (Tor extension)
- CmdGostUDPTun: UDP tunnel over TCP (Gost extension)
- CmdGostMuxBind: Multiplexed BIND (Gost extension)
Usage ¶
Use as-is for standard SOCKS server, or copy and modify for custom behavior:
handlers := make(map[protocol.Cmd]CommandHandler)
for k, v := range socksgo.DefaultCommandHandlers {
handlers[k] = v
}
handlers[protocol.CmdConnect] = myCustomHandler
server.Handlers = handlers
See Also ¶
- server_handler_connect.go: CONNECT handler implementation
- server_handler_bind.go: BIND handler implementation
- server_handler_assoc.go: UDP ASSOC handler implementation
- server_handler_resolve.go: Tor resolve handler implementation
- server_handler_mbind.go: Gost MBIND handler implementation
- server_handler_tun.go: Gost UDP tunnel handler implementation
var DefaultConnectHandler = CommandHandler{ Socks4: true, Socks5: true, TLSCompat: true, Handler: func( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) error { pool := server.GetPool() err := server.CheckRaddr(&addr) if err != nil { protocol.Reject(ver, conn, protocol.DisallowReply, pool) return err } conn2, err := server.GetDialer()(ctx, addr.Network(), addr.String()) if err != nil { protocol.Reject(ver, conn, errorToReplyStatus(err), pool) return err } defer func() { _ = conn2.Close() }() err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromNetAddr(conn2.RemoteAddr()), pool, ) if err != nil { return err } return protocol.PipeConn(conn, conn2) }, }
DefaultConnectHandler handles the CONNECT command.
DefaultConnectHandler establishes a TCP connection to the target address and pipes data between the client and target.
Protocol Support ¶
- SOCKS4: Yes
- SOCKS4a: Yes
- SOCKS5: Yes
- TLS: Yes
Behavior ¶
- Validates remote address against RaddrFilter
- Dials target address using server's Dialer
- Sends success reply with bound address
- Pipes data bidirectionally until EOF or error
Reply ¶
Sends success reply (0x00) with the target's address.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- HostUnreachReply (0x04): Dial failed
- FailReply (0x01): Other errors
Examples ¶
// Default handler is used automatically
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- RFC 1928: SOCKS5 Protocol (Section 4)
- protocol.PipeConn: Connection piping implementation
var DefaultGostMBindHandler = CommandHandler{ Socks4: true, Socks5: true, TLSCompat: true, Handler: func( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) error { pool := server.GetPool() addr = addr.WithDefaultHost(server.GetDefaultListenHost()) err := server.CheckLaddr(&addr) if err != nil { protocol.Reject(ver, conn, protocol.DisallowReply, pool) return err } listener, err := server.GetListener()(ctx, "tcp", addr.ToHostPort()) if err != nil { protocol.Reject(ver, conn, errorToReplyStatus(err), pool) return err } defer func() { _ = listener.Close() }() err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromNetAddr(listener.Addr()), pool, ) if err != nil { return err } session, err := smux.Client(conn, server.GetSmux()) if err != nil { _ = conn.Close() return err } defer func() { _ = conn.Close() _ = session.Close() }() var wg sync.WaitGroup wg.Go(func() { for { rw, err := session.Accept() if err != nil { _ = session.Close() _ = listener.Close() return } _ = rw.Close() } }) for { var inc net.Conn inc, err = listener.Accept() if err != nil { break } stream, err := session.OpenStream() if err != nil { break } wg.Go(func() { _ = protocol.PipeConn(inc, stream) }) } wg.Wait() return internal.ClosedNetworkErrToNil(err) }, }
DefaultGostMBindHandler handles the Gost multiplexed BIND command.
DefaultGostMBindHandler creates a TCP listener and uses smux to multiplex multiple incoming connections over a single TCP connection to the client.
Protocol Support ¶
- SOCKS4: Yes (Gost extension)
- SOCKS5: Yes (Gost extension)
- TLS: Yes
Behavior ¶
Applies default listen host if address is unspecified
Validates local address against LaddrFilter
Creates TCP listener on requested address
Sends success reply with bound address
Upgrades connection to smux session
Spawns goroutine to accept smux streams (and discard)
Accepts incoming connections on listener
For each incoming connection: - Opens new smux stream - Pipes data between listener connection and stream
Continues until listener or session closes
Multiplexing ¶
MBIND uses smux (stream multiplexing) to carry multiple independent connections over a single TCP connection.
Reply ¶
Sends success reply (0x00) with the listener address.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- FailReply (0x01): Listen failed
Examples ¶
// Enable on server
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
Smux: &smux.Config{
MaxFrameSize: 65535,
MaxReceiveBuffer: 4194304,
},
}
See Also ¶
- github.com/xtaci/smux: Stream multiplexing library
- server_handler_bind.go: Standard BIND handler
- protocol.PipeConn: Connection piping implementation
var DefaultGostUDPTUNHandler = CommandHandler{ Socks4: false, Socks5: true, TLSCompat: false, Handler: func( ctx context.Context, server *Server, tun net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) (err error) { addr.NetTyp = "udp" pool := server.GetPool() var proxy PacketConn binded := false if addr.IsUnspecified() { laddr := addr.WithDefaultHost(server.GetDefaultListenHost()) err = server.CheckLaddr(&addr) if err == nil { proxy, err = server.GetPacketListener()( ctx, laddr.Network(), laddr.ToHostPort(), ) } } else { err = server.CheckRaddr(&addr) if err == nil { binded = true proxy, err = server.GetPacketDialer()( ctx, addr.Network(), addr.ToHostPort(), ) } } if err != nil { protocol.Reject(ver, tun, errorToReplyStatus(err), pool) return err } err = protocol.Reply( ver, tun, protocol.SuccReply, protocol.AddrFromNetAddr(proxy.LocalAddr()), pool, ) if err != nil { return err } return protocol.ProxySocks5UDPTun( tun, proxy, binded, nil, pool, server.GetUDPBufferSize(), ) }, }
DefaultGostUDPTUNHandler handles the Gost UDP Tunnel command.
DefaultGostUDPTUNHandler creates a UDP tunnel over TCP, encapsulating UDP packets in a custom TCP framing format.
Protocol Support ¶
- SOCKS4: No (Gost extension)
- SOCKS5: Yes (Gost extension)
- TLS: No (UDP over TLS is problematic)
Behavior ¶
Sets address network type to "udp"
If address is unspecified (0.0.0.0:0): - Creates UDP listener (server mode) - Validates against LaddrFilter
If address is specified: - Creates UDP connection to target (client mode) - Validates against RaddrFilter
Sends success reply with proxy's UDP address
Proxies UDP packets with Gost framing over TCP
Reply ¶
Sends success reply (0x00) with the proxy's UDP address.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- FailReply (0x01): Listen/dial failed
Examples ¶
// Enable on client
client.GostUDPTun = true
// Server handles automatically with DefaultCommandHandlers
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- server_handler_assoc.go: Standard UDP ASSOC handler
- protocol.ProxySocks5UDPTun: UDP tunnel proxy implementation
var DefaultResolveHandler = CommandHandler{ Socks4: true, Socks5: true, TLSCompat: true, Handler: func( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) error { pool := server.GetPool() err := server.CheckRaddr(&addr) if err != nil { protocol.Reject(ver, conn, protocol.DisallowReply, pool) return err } ips, err := server.GetResolver(). LookupIP(ctx, addr.IpNetwork(), addr.ToFQDN()) if err != nil { protocol.Reject(ver, conn, protocol.HostUnreachReply, pool) return err } if len(ips) < 1 { protocol.Reject(ver, conn, protocol.HostUnreachReply, pool) return &net.DNSError{ Err: "zero IPs found", Name: addr.ToFQDN(), IsNotFound: true, } } ip := ips[0] if server.IsPreferIPv4() { for _, elem := range ips { if ip4 := elem.To4(); ip4 != nil { ip = ip4 break } } } err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromIP(ip, 0, ""), pool, ) return err }, }
DefaultResolveHandler handles the Tor forward DNS lookup command.
DefaultResolveHandler performs DNS forward lookup (A/AAAA records) through the server's configured resolver and returns the resolved IP address to the client.
Protocol Support ¶
- SOCKS4: Yes (with Tor extension)
- SOCKS4a: Yes (with Tor extension)
- SOCKS5: Yes (with Tor extension)
- TLS: Yes
Behavior ¶
Validates remote address (hostname) against RaddrFilter
Performs DNS lookup using server's Resolver
If DoNotPreferIP4 is false (default): - Prefers IPv4 address if both IPv4 and IPv6 found
Sends success reply with resolved IP address
IPv4 Preference ¶
By default (DoNotPreferIP4 = false), if the DNS lookup returns both IPv4 and IPv6 addresses, the first IPv4 address is returned. This provides better compatibility with clients that expect IPv4.
Reply ¶
Sends success reply (0x00) with the resolved IP address. The port in the reply is set to 0.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- HostUnreachReply (0x04): DNS lookup failed or no results
Examples ¶
// Enable on client
client.TorLookup = true
ips, err := client.LookupIP(ctx, "ip4", "example.com")
// Server handles automatically with DefaultCommandHandlers
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- server_handler_resolveptr.go: Reverse DNS lookup
- client.go#LookupIP: Client-side forward lookup
var DefaultResolvePtrHandler = CommandHandler{ Socks4: false, Socks5: true, TLSCompat: true, Handler: func( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) error { pool := server.GetPool() err := server.CheckRaddr(&addr) if err != nil { protocol.Reject(ver, conn, protocol.DisallowReply, pool) return err } names, err := server.GetResolver().LookupAddr(ctx, addr.ToIP().String()) if err != nil { protocol.Reject(ver, conn, protocol.HostUnreachReply, pool) return err } if len(names) < 1 { protocol.Reject(ver, conn, protocol.HostUnreachReply, pool) return &net.DNSError{ Err: "zero addrs found", Name: addr.ToFQDN(), IsNotFound: true, } } err = protocol.Reply( ver, conn, protocol.SuccReply, protocol.AddrFromFQDNNoDot(names[0], 0, ""), pool, ) return err }, }
DefaultResolvePtrHandler handles the Tor reverse DNS lookup command.
DefaultResolvePtrHandler performs DNS reverse lookup (PTR records) through the server's configured resolver and returns the resolved hostname to the client.
Protocol Support ¶
- SOCKS4: No
- SOCKS4a: No
- SOCKS5: Yes (with Tor extension)
- TLS: Yes
Behavior ¶
- Validates remote address (IP) against RaddrFilter
- Performs reverse DNS lookup using server's Resolver
- Sends success reply with resolved hostname
Reply ¶
Sends success reply (0x00) with the resolved hostname. The port in the reply is set to 0.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- HostUnreachReply (0x04): DNS lookup failed or no results
Examples ¶
// Enable on client
client.TorLookup = true
names, err := client.LookupAddr(ctx, "8.8.8.8")
// Server handles automatically with DefaultCommandHandlers
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- server_handler_resolve.go: Forward DNS lookup
- client.go#LookupAddr: Client-side reverse lookup
var DefaultUDPAssocHandler = CommandHandler{ Socks4: false, Socks5: true, TLSCompat: false, Handler: func( ctx context.Context, server *Server, ctrl net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr) (err error) { addr.NetTyp = "udp" pool := server.GetPool() var proxy PacketConn binded := false if addr.IsUnspecified() { laddr := addr.WithDefaultHost(server.GetDefaultListenHost()) err = server.CheckLaddr(&addr) if err == nil { proxy, err = server.GetPacketListener()( ctx, laddr.Network(), laddr.ToHostPort(), ) } } else { err = server.CheckRaddr(&addr) if err == nil { binded = true proxy, err = server.GetPacketDialer()( ctx, addr.Network(), addr.ToHostPort(), ) } } if err != nil { protocol.Reject(ver, ctrl, errorToReplyStatus(err), pool) return err } assoc, err := server.ListenForAssoc(ctx, ctrl) if err != nil { protocol.Reject(ver, ctrl, errorToReplyStatus(err), pool) return err } err = protocol.Reply( ver, ctrl, protocol.SuccReply, protocol.AddrFromNetAddr(assoc.LocalAddr()), pool, ) if err != nil { return err } return protocol.ProxySocks5UDPAssoc( assoc, proxy, ctrl, binded, nil, pool, server.GetUDPBufferSize(), server.GetUDPTimeout(), ) }, }
DefaultUDPAssocHandler handles the UDP ASSOCIATE command.
DefaultUDPAssocHandler creates a UDP association that proxies packets between the client and target using standard SOCKS5 UDP encapsulation.
Protocol Support ¶
- SOCKS4: No
- SOCKS5: Yes
- TLS: No
Behavior ¶
Sets address network type to "udp"
If address is unspecified (0.0.0.0:0): - Creates UDP listener (server mode) - Validates against LaddrFilter
If address is specified: - Creates UDP connection to target (client mode) - Validates against RaddrFilter
Creates UDP association listener
Sends success reply with association address
Proxies UDP packets with SOCKS5 UDP headers
UDP Encapsulation ¶
SOCKS5 UDP packets include a header:
+----+------+------+----------+----------+----------+ |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +----+------+------+----------+----------+----------+ - RSV: Reserved (0x0000) - FRAG: Fragment number (0x00 = no fragmentation) - ATYP: Address type (IP4=0x01, IP6=0x04, FQDN=0x03) - DST.ADDR: Destination address - DST.PORT: Destination port - DATA: UDP payload
Association Lifecycle ¶
The UDP association remains active until:
- UDPTimeout expires (default: 3 minutes)
- Control TCP connection closes
- Error occurs during proxying
Reply ¶
Sends success reply (0x00) with the UDP association address.
Errors ¶
Returns error and sends appropriate reply status:
- DisallowReply (0x02): Address filtered
- FailReply (0x01): Listen/dial failed
Examples ¶
// Default handler is used automatically
server := &socksgo.Server{
Handlers: socksgo.DefaultCommandHandlers,
}
See Also ¶
- RFC 1928: SOCKS5 Protocol (Section 7)
- protocol.ProxySocks5UDPAssoc: UDP proxy implementation
- server_handler_tun.go: Gost UDP tunnel (UDP over TCP)
Functions ¶
func GetTestListenCloseHook ¶
func GetTestListenSmuxHook ¶
func GetTestListenSmuxHook() func() error
func GetTestRequestHook ¶
func LoopbackFilter ¶
LoopbackFilter returns true for localhost and loopback addresses. Use this filter to route local traffic directly while sending external traffic through the proxy.
func MatchAllFilter ¶
MatchAllFilter is a Filter that always returns true. All connections bypass the proxy and use direct connection.
func PassAllFilter ¶
PassAllFilter is a Filter that always returns false. All connections will use the proxy (none bypass to direct connection).
func ResetTestHooks ¶
func ResetTestHooks()
func SetTestListenCloseHook ¶
func SetTestListenSmuxHook ¶
func SetTestListenSmuxHook(hook func() error)
func SetTestLookupIPHook ¶
Stub functions for production builds (no-op)
func SetTestRequestHook ¶
func TestAddrFromFQDN ¶
Types ¶
type AddrDisallowedError ¶
AddrDisallowedError is returned when an address is blocked by a filter.
func (AddrDisallowedError) Error ¶
func (e AddrDisallowedError) Error() string
type Client ¶
type Client struct {
// SocksVersion specifies the SOCKS protocol version.
//
// Valid values:
// - "4": SOCKS4 (no domain name support)
// - "4a": SOCKS4a (supports domain names)
// - "5": SOCKS5 (full feature support)
// - "": Empty string defaults to "5"
//
// Default: "5"
SocksVersion string
// ProxyNet specifies the network type for connecting to the proxy.
//
// Valid values: "tcp", "tcp4", "tcp6"
//
// Default: "tcp"
ProxyNet string
// ProxyAddr is the proxy server address in host:port format.
//
// If port is omitted (e.g., "proxy.example.com"), port 1080 is used.
// Ignored when WebSocketURL is set.
//
// Examples:
// - "proxy.example.com:1080"
// - "192.168.1.1:9050"
// - "proxy.example.com" (uses default port 1080)
ProxyAddr string
// Auth contains authentication methods for SOCKS5.
//
// Multiple methods can be added; the server selects one during negotiation.
//
// Examples:
//
// client.Auth = (&protocol.AuthMethods{}).
// Add(&protocol.PassAuthMethod{User: "user", Pass: "pass"}).
// Add(&protocol.NoAuthMethod{})
Auth *protocol.AuthMethods
// InsecureUDP allows plaintext UDP over TLS connections.
//
// WARNING: This is a security risk! When true, UDP packets are sent
// unencrypted even when the control TCP connection uses TLS.
//
// Only enable in trusted networks or when you understand the implications.
//
// Default: false
InsecureUDP bool
// DoNotSpawnUDPAsocProbber disables the UDP ASSOC prober goroutine.
//
// When false (default), a goroutine monitors the control TCP connection
// and closes the UDP association when the control connection closes.
//
// Set to true to disable this behavior (manual cleanup required).
DoNotSpawnUDPAsocProbber bool
// GostMbind enables Gost multiplexed BIND extension.
//
// When enabled, the client can use MBIND command for multiplexed
// incoming connections over a single TCP connection using smux.
//
// Default: false
GostMbind bool
// GostUDPTun enables Gost UDP Tunnel extension.
//
// When enabled, UDP traffic is tunneled over TCP instead of using
// standard UDP ASSOCIATE.
//
// Default: false
GostUDPTun bool
// TorLookup enables Tor DNS resolution extensions.
//
// When enabled, LookupIP and LookupAddr methods use Tor's SOCKS
// extensions for DNS resolution through the proxy.
//
// Default: false
TorLookup bool
// Filter determines which connections bypass the proxy.
//
// When Filter returns true, connections use direct dialing instead
// of going through the proxy. Commonly used for NO_PROXY-style rules.
//
// Default: LoopbackFilter (bypasses localhost and loopback addresses)
//
// Examples:
//
// client.Filter = socksgo.BuildFilter("localhost,192.168.0.0/16")
Filter Filter
// Dialer is used to establish TCP connections to the proxy.
//
// Also used for direct connections when Filter returns true.
//
// Default: net.Dialer.DialContext
Dialer Dialer
// PacketDialer is used to establish UDP connections for proxy operations.
//
// Also used for direct UDP when Filter returns true.
//
// Default: net.DialUDP
PacketDialer PacketDialer
// DirectListener is used for direct TCP listening (BIND) when
// Filter returns true.
//
// Default: net.ListenConfig.Listen
DirectListener Listener
// DirectPacketListener is used for direct UDP listening when
// Filter returns true.
//
// Default: net.ListenUDP
DirectPacketListener PacketListener
// Resolver is used for DNS lookups.
//
// Used for SOCKS4 (non-4a) clients and Tor LookupIP/LookupAddr
// requests when Filter returns true.
//
// Default: net.DefaultResolver
Resolver Resolver
// HandshakeTimeout specifies the timeout for SOCKS handshake.
//
// If zero, uses context deadline or no timeout.
//
// Default: 0 (no explicit timeout)
HandshakeTimeout time.Duration
// Smux configures connection multiplexing for Gost MBIND.
//
// Only used when GostMbind is true.
//
// Example:
//
// client.Smux = &smux.Config{
// MaxFrameSize: 65535,
// MaxReceiveBuffer: 4194304,
// }
Smux *smux.Config
// TLS enables TLS for the proxy connection.
//
// When true, the connection to ProxyAddr is wrapped in TLS.
// TLSConfig controls certificate verification and other TLS settings.
//
// Default: false
TLS bool
// TLSConfig configures TLS behavior.
//
// If nil, a default config is used with:
// - InsecureSkipVerify: true (disable with "secure" URL option)
// - ServerName: Auto-set from ProxyAddr or WebSocketURL
//
// Example for secure connections:
//
// client.TLSConfig = &tls.Config{
// InsecureSkipVerify: false,
// ServerName: "proxy.example.com",
// }
TLSConfig *tls.Config
// WebSocketURL enables SOCKS over WebSocket transport.
//
// When non-empty, connects to this WebSocket URL instead of
// ProxyAddr. ProxyNet and ProxyAddr are ignored.
//
// URL scheme determines encryption:
// - "ws://": Plaintext WebSocket
// - "wss://": Encrypted WebSocket (TLS)
//
// Examples:
// - "ws://proxy.example.com/ws"
// - "wss://proxy.example.com/socks"
WebSocketURL string
// WebSocketConfig configures WebSocket-specific options.
//
// If nil, default WebSocket settings are used.
//
// See WebSocketConfig for available options.
WebSocketConfig *WebSocketConfig
// Pool is a buffer pool for memory-efficient operations.
//
// If nil, a no pool is used.
//
// Using a shared pool across multiple clients can reduce
// memory allocations and GC pressure.
Pool bufpool.Pool
}
Client is a SOCKS proxy client configuration.
Client provides a high-level interface for connecting through SOCKS4, SOCKS4a, and SOCKS5 proxies. It supports TCP connections, UDP associations, BIND commands, and extensions for Gost and Tor compatibility.
Quick Start ¶
// Basic SOCKS5 client
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "proxy.example.com:1080",
}
conn, err := client.Dial(ctx, "tcp", "example.com:80")
// With authentication
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "proxy.example.com:1080",
Auth: (&protocol.AuthMethods{}).Add(&protocol.PassAuthMethod{
User: "username",
Pass: "password",
}),
}
// SOCKS over TLS
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "proxy.example.com:1080",
TLS: true,
}
// SOCKS over WebSocket
client := &socksgo.Client{
SocksVersion: "5",
WebSocketURL: "wss://proxy.example.com/ws",
}
// Tor stream isolation
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "127.0.0.1:9050",
}
isolatedClient := client.WithTorIsolation(nil) // Random isolation
sessionID := "my-session"
isolatedClient = client.WithTorIsolation(&sessionID) // Specific isolation
Thread Safety ¶
Client is safe for concurrent use after initialization. Do not modify fields after calling Dial, Listen, or other methods.
See Also ¶
- ClientFromURL: Create client from URL string
- ClientFromENV: Create client from environment variables
- ClientNoProxy: Create client that bypasses proxy
- Client.WithTorIsolation: Enable Tor stream isolation
func ClientFromENV ¶
ClientFromENV creates a Client from environment variables with all options.
Reads the proxy URL from environment variables and creates a Client with all options enabled. Uses ClientFromURL which supports insecure options if specified in the URL.
Examples ¶
// Reads SOCKS5_PROXY environment variable
client, err := socksgo.ClientFromENV("socks5")
See Also ¶
- ClientFromENVSafe: Safe version without insecure options
- ClientFromURL: Parse URL string with all options
func ClientFromENVSafe ¶
ClientFromENVSafe creates a Client from environment variables safely.
Reads the proxy URL from standard environment variables:
- ALL_PROXY, all_proxy: Fallback for any scheme
- {scheme}_proxy, {scheme}_PROXY: Scheme-specific (e.g., http_proxy)
Returns ClientNoProxy() if no environment variable is set.
Examples ¶
// Reads HTTP_PROXY or ALL_PROXY
client, err := socksgo.ClientFromENVSafe("http")
Environment Variable Priority ¶
1. {scheme}_proxy (lowercase) 2. {scheme}_PROXY (uppercase) 3. ALL_PROXY (lowercase) 4. all_proxy (uppercase)
See Also ¶
- ClientFromURLObjSafe: Parse URL safely
- ClientNoProxy: Default when no env var set
func ClientFromURL ¶
ClientFromURL creates a Client from a URL string with all options.
Wrapper around ClientFromURLObj that parses the URL string first. Supports all options including insecure ones.
Examples ¶
client, err := socksgo.ClientFromURL("socks5://user:pass@proxy.example.com:1080?pass")
See Also ¶
- ClientFromURLObj: Parse *url.URL with all options
- ClientFromURLSafe: Safe version without insecure options
func ClientFromURLObj ¶
ClientFromURLObj creates a Client from a URL with all options.
This is the unsafe constructor that supports all URL options including insecure ones. Use ClientFromURLObjSafe for secure defaults.
Supported Options ¶
- pass: Enable PassAllFilter (all connections through proxy, no bypass)
- gost: Enable Gost extensions (MBIND, UDPTun)
- tor: Enable Tor lookup extensions
- secure: Disable TLS certificate verification (default: skip)
- insecureudp: Allow plaintext UDP over TLS (security risk!)
- assocprob: Enable UDP assoc prober (monitors control connection)
Security Warning ¶
Using "insecureudp" allows plaintext UDP even when the control connection is encrypted. This can lead to security vulnerabilities.
The "pass" Option ¶
The "pass" option enables PassAllFilter, which forces ALL connections through the proxy with no bypass. Without this option, LoopbackFilter is used by default (localhost and loopback addresses bypass the proxy).
Examples ¶
// With insecure UDP over TLS (NOT RECOMMENDED)
u, _ := url.Parse("socks5+tls://proxy.example.com:1080?insecureudp")
client := socksgo.ClientFromURLObj(u)
// Force all traffic through proxy (no bypass)
u, _ := url.Parse("socks5://proxy.example.com:1080?pass")
client := socksgo.ClientFromURLObj(u)
See Also ¶
- ClientFromURLObjSafe: Safe version without insecure options
- ClientFromURL: Parse URL string with all options
func ClientFromURLObjSafe ¶
ClientFromURLObjSafe creates a Client from a URL without insecure options.
This is a safe constructor that parses a URL and creates a Client with secure defaults. Insecure options like insecureudp are ignored.
URL Format ¶
socks[4|4a|5][+tls|+ws|+wss]://[user:pass@]host[:port][?options]
Supported Options ¶
- pass: Enable PassAllFilter (all connections through proxy, no bypass)
- gost: Enable Gost extensions (MBIND, UDPTun)
- tor: Enable Tor lookup extensions
- secure: Enable TLS certificate verification (default: skip verification)
Defaults ¶
- TLS: InsecureSkipVerify = true (disable with "secure" option)
- UDP: Plaintext UDP over TLS disabled (use "insecureudp" in unsafe version)
- Filter: LoopbackFilter (bypass proxy for localhost)
The "pass" Option ¶
The "pass" option enables PassAllFilter, which forces ALL connections through the proxy with no bypass. Without this option, LoopbackFilter is used by default ("localhost" and loopback addresses bypass the proxy).
Examples ¶
// Basic SOCKS5 proxy
u, _ := url.Parse("socks5://proxy.example.com:1080")
client := socksgo.ClientFromURLObjSafe(u)
// With authentication (credentials in URL)
u, _ := url.Parse("socks5://user:pass@proxy.example.com:1080")
client := socksgo.ClientFromURLObjSafe(u)
// Force all traffic through proxy (no bypass)
u, _ := url.Parse("socks5://proxy.example.com:1080?pass")
client := socksgo.ClientFromURLObjSafe(u)
// SOCKS5 over TLS with certificate verification
u, _ := url.Parse("socks5+tls://proxy.example.com:1080?secure")
client := socksgo.ClientFromURLObjSafe(u)
// SOCKS5 over WebSocket
u, _ := url.Parse("socks5+ws://proxy.example.com:8080/ws")
client := socksgo.ClientFromURLObjSafe(u)
func ClientFromURLSafe ¶
ClientFromURLSafe creates a Client from a URL string safely.
Wrapper around ClientFromURLObjSafe that parses the URL string first. Returns an error if the URL cannot be parsed.
Examples ¶
client, err := socksgo.ClientFromURLSafe("socks5://proxy.example.com:1080")
See Also ¶
- ClientFromURLObjSafe: Parse *url.URL safely
- ClientFromURL: Unsafe version with all options
func ClientNoProxy ¶
func ClientNoProxy() *Client
ClientNoProxy returns a Client that bypasses any proxy.
This client passes all connections directly without using a proxy. It's equivalent to setting Filter to MatchAllFilter.
Examples ¶
// Direct connections only client := socksgo.ClientNoProxy() conn, err := client.Dial(ctx, "tcp", "example.com:80") // conn is a direct TCP connection to example.com:80
See Also ¶
- MatchAllFilter: Filter that always returns true
func (*Client) CheckNetworkSupport ¶
CheckNetworkSupport validates network support for the SOCKS version.
CheckNetworkSupport checks if the requested network type is supported by the configured SOCKS protocol version.
Parameters ¶
- net: Network type to validate ("tcp", "tcp4", "tcp6", "udp", etc.)
Returns ¶
nil if supported, WrongNetworkError if not.
Supported Networks ¶
SOCKS5:
- tcp, tcp4, tcp6
- udp, udp4, udp6
SOCKS4/4a:
- tcp, tcp4 (UDP not supported)
Examples ¶
err := client.CheckNetworkSupport("tcp") // nil
err := client.CheckNetworkSupport("udp") // nil for SOCKS5
err := client.CheckNetworkSupport("unix") // WrongNetworkError
client.SocksVersion = "4"
err := client.CheckNetworkSupport("udp") // WrongNetworkError
func (*Client) Connect ¶
Connect establishes a connection to the SOCKS proxy server.
Connect creates a TCP or WebSocket connection to the proxy server and applies TLS if configured. It's used internally by Request() but can be called directly for low-level control.
Returns ¶
Established net.Conn to the proxy server or error.
Behavior ¶
- If WebSocketURL is set: Establishes WebSocket connection
- Otherwise: Dials ProxyAddr using Dialer
- If TLS enabled: Wraps connection in TLS
- Sets handshake timeout deadline
WebSocket ¶
When WebSocketURL is set, connects via WebSocket and returns a wrapped connection. ProxyAddr is ignored.
TLS ¶
When TLS is true (or WebSocketURL starts with "wss"), wraps the connection in TLS using GetTLSConfig().
Timeout ¶
Uses HandshakeTimeout if set, otherwise uses context deadline.
Examples ¶
// Direct connection to proxy
conn, err := client.Connect(ctx)
if err != nil {
return err
}
defer conn.Close()
// Use with Request for manual control
conn, err := client.Connect(ctx)
// Send custom SOCKS request...
See Also ¶
- Request: High-level SOCKS request
- Dial: High-level TCP connection
- GetTLSConfig: TLS configuration
func (*Client) Dial ¶
Dial establishes a TCP connection through the SOCKS proxy.
Dial is the primary method for creating TCP connections through the proxy. It handles network validation, filter checking, and SOCKS protocol handshake.
Parameters ¶
- ctx: Context for cancellation and timeouts
- network: Network type ("tcp", "tcp4", "tcp6")
- address: Target address in host:port format
Returns ¶
Established net.Conn or error.
Behavior ¶
- Validates network support for the SOCKS version
- Checks Filter - if true, dials directly
- Sends CONNECT command through proxy
- Returns established connection
UDP Networks ¶
If network is "udp", "udp4", or "udp6", DialPacket is called instead.
Examples ¶
// Basic connection
conn, err := client.Dial(ctx, "tcp", "example.com:80")
// With timeout context
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
conn, err := client.Dial(ctx, "tcp", "example.com:443")
// Direct connection via filter
client.Filter = socksgo.BuildFilter("localhost")
conn, err := client.Dial(ctx, "tcp", "localhost:8080") // Direct, not via proxy
Errors ¶
Returns WrongNetworkError for unsupported networks. Returns RejectdError if server rejects the connection.
See Also ¶
- DialPacket: UDP connections
- Listen: BIND command for incoming connections
- Request: Low-level SOCKS request
func (*Client) DialPacket ¶
DialPacket establishes a UDP connection through the SOCKS proxy.
DialPacket creates a PacketConn for UDP communication through the proxy. It supports both standard UDP ASSOCIATE and Gost UDP Tunnel extensions.
Parameters ¶
- ctx: Context for cancellation and timeouts
- network: Network type ("udp", "udp4", "udp6")
- address: Target address in host:port format
Returns ¶
PacketConn for UDP communication or error.
Behavior ¶
- Validates network support
- Checks Filter - if true, dials UDP directly
- If GostUDPTun enabled: Uses UDP tunnel over TCP
- Otherwise: Uses standard UDP ASSOCIATE
Gost UDP Tunnel ¶
When GostUDPTun is true, UDP is encapsulated in TCP.
Examples ¶
// DNS query through proxy
conn, err := client.DialPacket(ctx, "udp", "8.8.8.8:53")
if err == nil {
_, err := conn.Write(dnsQuery)
_, err = conn.Read(response)
}
// Gost UDP tunnel
client.GostUDPTun = true
conn, err := client.DialPacket(ctx, "udp", "target:123")
See Also ¶
- ListenPacket: Listen for UDP packets
- Dial: TCP connections
func (*Client) DoFilter ¶
DoFilter checks if a connection should bypass the proxy.
DoFilter evaluates the Filter function to determine if a connection should use direct dialing instead of going through the proxy.
Parameters ¶
- network: Network type (may be "" if unknown)
- address: Target address (host:port format)
Returns ¶
- true: Use direct connection (bypass proxy)
- false: Use SOCKS proxy
Behavior ¶
- If IsNoProxy() returns true: Always returns true (all direct)
- If Filter is nil: Uses LoopbackFilter
- Otherwise: Calls Filter(network, address)
Examples ¶
client.Filter = socksgo.BuildFilter("localhost,192.168.0.0/16")
client.DoFilter("tcp", "localhost:8080") // true (direct)
client.DoFilter("tcp", "example.com:80") // false (proxy)
func (*Client) GetAddr ¶
GetAddr returns the proxy server address with default port.
If ProxyAddr doesn't contain a port, appends ":1080" (default SOCKS port).
Returns ¶
ProxyAddr or ProxyAddr:1080 if no port specified.
Examples ¶
client.ProxyAddr = "proxy.example.com" addr := client.GetAddr() // Returns "proxy.example.com:1080" client.ProxyAddr = "proxy.example.com:9050" addr := client.GetAddr() // Returns "proxy.example.com:9050"
func (*Client) GetDialer ¶
GetDialer returns the dialer for TCP connections.
Returns Dialer if set, otherwise uses net.Dialer.DialContext.
Returns ¶
Dialer function for establishing TCP connections.
See Also ¶
- Dialer: Custom dialer configuration
func (*Client) GetHandshakeTimeout ¶
GetHandshakeTimeout returns the SOCKS handshake timeout.
Returns ¶
HandshakeTimeout duration, or 0 if not set.
func (*Client) GetListener ¶
GetListener returns the TCP listener for direct connections.
Returns DirectListener if set, otherwise uses net.ListenConfig.Listen.
Returns ¶
Listener function for creating TCP listeners.
See Also ¶
- DirectListener: Custom listener configuration
func (*Client) GetNet ¶
GetNet returns the network type for proxy connections.
Returns "tcp" as default if ProxyNet is empty.
Returns ¶
ProxyNet or "tcp" (default)
func (*Client) GetPacketDialer ¶
func (c *Client) GetPacketDialer() PacketDialer
GetPacketDialer returns the dialer for UDP connections.
Returns PacketDialer if set, otherwise creates UDP connections using net.DialUDP.
Returns ¶
PacketDialer function for establishing UDP connections.
See Also ¶
- PacketDialer: Custom dialer configuration
func (*Client) GetPacketListener ¶
func (c *Client) GetPacketListener() PacketListener
GetPacketListener returns the UDP packet listener for direct connections.
Returns DirectPacketListener if set, otherwise creates a UDP listener using net.ListenUDP.
Returns ¶
PacketListener function for creating UDP listeners.
See Also ¶
- DirectPacketListener: Custom listener configuration
func (*Client) GetResolver ¶
GetResolver returns the DNS resolver for lookups.
Returns Resolver if set, otherwise uses net.DefaultResolver.
Returns ¶
Resolver for DNS lookups.
See Also ¶
- Resolver: Custom resolver configuration
- net.DefaultResolver: System default resolver
func (*Client) GetTLSConfig ¶
GetTLSConfig builds the TLS configuration for secure connections.
GetTLSConfig creates a TLS configuration from TLSConfig field or returns a default configuration. If TLS is not enabled, returns nil.
Behavior ¶
- If !IsTLS(): Returns nil
- If TLSConfig is nil: Creates default config
- Clones TLSConfig to avoid mutation
- Sets ServerName from ProxyAddr if empty
ServerName ¶
If TLSConfig.ServerName is empty, extracts the hostname from GetAddr() (removes port).
Returns ¶
*tls.Config for TLS connections, or nil if TLS is disabled.
Examples ¶
// Default TLS config
client.TLS = true
config := client.GetTLSConfig()
// config.InsecureSkipVerify = true (default)
// config.ServerName = "proxy.example.com" (from ProxyAddr)
// Custom TLS config
client.TLSConfig = &tls.Config{
InsecureSkipVerify: false,
ServerName: "custom.example.com",
}
config := client.GetTLSConfig()
func (*Client) GetWsDialer ¶
GetWsDialer builds the WebSocket dialer for SOCKS over WS.
GetWsDialer creates a websocket.Dialer configured from WebSocketConfig, GetDialer, and GetTLSConfig. Returns nil if WebSocketURL is empty.
Configuration ¶
The dialer is configured with:
- NetDialContext: From GetDialer()
- TLSClientConfig: From GetTLSConfig()
- WriteBufferPool: Uses client's Pool
- HandshakeTimeout: From GetHandshakeTimeout()
- ReadBufferSize, Subprotocols, etc.: From WebSocketConfig
Returns ¶
*websocket.Dialer for WebSocket connections, or nil if WebSocketURL is empty.
See Also ¶
- WebSocketConfig: WebSocket configuration options
- github.com/gorilla/websocket: Underlying WebSocket library
func (*Client) IsNoProxy ¶
IsNoProxy reports whether the client bypasses the proxy.
Returns true if:
- Client is nil
- Both ProxyAddr and WebSocketURL are empty
When true, all connections use direct.
func (*Client) IsTLS ¶
IsTLS reports whether TLS is enabled for the proxy connection.
Returns true if:
- TLS field is true, or
- WebSocketURL starts with "wss"
Examples ¶
client.TLS = true client.IsTLS() // true client.WebSocketURL = "wss://proxy.example.com/ws" client.IsTLS() // true
func (*Client) IsUDPAllowed ¶
IsUDPAllowed reports whether UDP operations are permitted.
Returns true if:
- TLS is not enabled, or
- InsecureUDP is true (allows plaintext UDP over TLS)
Security Warning ¶
When TLS is enabled and InsecureUDP is true, UDP packets are sent unencrypted. This is a security risk!
Examples ¶
client.TLS = false client.IsUDPAllowed() // true client.TLS = true client.InsecureUDP = false client.IsUDPAllowed() // false (UDP blocked over TLS) client.TLS = true client.InsecureUDP = true // NOT RECOMMENDED client.IsUDPAllowed() // true (but UDP is plaintext!)
func (*Client) Listen ¶
Listen establishes a TCP listener through the SOCKS proxy (BIND command).
Listen uses the SOCKS BIND command to create a listener on the proxy server that forwards incoming connections to the client.
Parameters ¶
- ctx: Context for cancellation and timeouts
- network: Network type ("tcp", "tcp4", "tcp6")
- address: Local address to bind (use "0.0.0.0:0" for any)
Returns ¶
net.Listener for accepting connections or error.
Behavior ¶
- Validates network support
- Checks Filter - if true, listens directly
- Sends BIND command to proxy
- Returns listener for incoming connections
Examples ¶
// Listen for incoming connections
listener, err := client.Listen(ctx, "tcp", "0.0.0.0:0")
if err == nil {
for {
conn, err := listener.Accept()
if err != nil {
break
}
go handleConnection(conn)
}
}
See Also ¶
- Dial: Outgoing TCP connections
- DialPacket: UDP connections
func (*Client) ListenPacket ¶
ListenPacket listens for UDP packets through the SOCKS proxy.
ListenPacket creates a UDP listener that receives packets through the SOCKS proxy. It supports both standard UDP ASSOCIATE and Gost UDP Tunnel extensions.
Parameters ¶
- ctx: Context for cancellation and timeouts
- network: Network type ("udp", "udp4", "udp6")
- address: Local address to listen on (use "0.0.0.0:0" for any)
Returns ¶
PacketConn for receiving UDP packets or error.
Behavior ¶
- Validates network support
- Checks Filter - if true, listens directly
- If GostUDPTun enabled: Uses UDP tunnel over TCP
- Otherwise: Uses standard UDP ASSOCIATE
Gost UDP Tunnel ¶
When GostUDPTun is true, creates a bound UDP tunnel. The server acts like NAT and doesn't return the bound address - use STUN or similar to discover the external address.
Standard UDP ASSOCIATE ¶
For standard UDP ASSOCIATE, the laddr parameter is ignored. The server assigns a UDP port and returns it in the BIND address.
Examples ¶
// Listen on any available port conn, err := client.ListenPacket(ctx, "udp", "0.0.0.0:0") // Gost UDP tunnel (bound) client.GostUDPTun = true conn, err := client.ListenPacket(ctx, "udp", "0.0.0.0:0") // Use STUN to discover external address
See Also ¶
- DialPacket: Send UDP packets
- Listen: TCP BIND command
func (*Client) LookupAddr ¶
LookupAddr performs a reverse DNS lookup through the SOCKS proxy.
LookupAddr uses Tor's SOCKS extension to resolve IP addresses to hostnames through the proxy. This provides DNS privacy for reverse lookups.
Parameters ¶
- ctx: Context for cancellation and timeouts
- address: IP address to resolve (as string)
Returns ¶
Slice of resolved hostnames or error.
Requirements ¶
TorLookup must be enabled. Returns ErrResolveDisabled if not set.
Examples ¶
// Enable Tor lookup
client.TorLookup = true
// Reverse lookup
names, err := client.LookupAddr(ctx, "8.8.8.8")
if err == nil && len(names) > 0 {
fmt.Printf("Resolved to: %s\n", names[0])
}
Errors ¶
Returns *net.DNSError with ErrResolveDisabled if TorLookup is false.
See Also ¶
- LookupIP: Forward DNS lookup
- net.Resolver.LookupAddr: Standard reverse lookup
func (*Client) LookupIP ¶
LookupIP performs a forward DNS lookup through the SOCKS proxy.
LookupIP uses Tor's SOCKS extension to resolve hostnames to IP addresses through the proxy. This provides DNS privacy by preventing DNS leaks.
Parameters ¶
- ctx: Context for cancellation and timeouts
- network: IP version ("ip", "ip4", "ip6")
- address: Hostname to resolve
Returns ¶
Slice of resolved IP addresses or error.
Requirements ¶
TorLookup must be enabled. Returns ErrResolveDisabled if not set.
IP types Note ¶
Due to Tor SOCKS extension limitations, the returned IP version may differ from the requested network (e.g., ipv6 when ipv4 was requested or vise versa).
Examples ¶
// Enable Tor lookup
client.TorLookup = true
// Resolve hostname
ips, err := client.LookupIP(ctx, "ip4", "example.com")
if err == nil && len(ips) > 0 {
fmt.Printf("Resolved to: %v\n", ips[0])
}
Errors ¶
Returns *net.DNSError with ErrResolveDisabled if TorLookup is false.
See Also ¶
- LookupAddr: Reverse DNS lookup
- net.Resolver.LookupIP: Standard DNS lookup
func (*Client) Request ¶
func (c *Client) Request( ctx context.Context, cmd protocol.Cmd, address protocol.Addr, ) ( proxy net.Conn, addr protocol.Addr, err error, )
Request sends a low-level SOCKS request to the proxy.
Request establishes a connection to the proxy, performs authentication if needed, and sends the specified command for the given address.
Parameters ¶
- ctx: Context for cancellation and timeouts
- cmd: SOCKS command (Connect, Bind, UDPAssoc, or extensions)
- address: Target address for the command
Returns ¶
- proxy: Established connection to proxy (or target for CONNECT)
- addr: Bound address from server (relevant for BIND/UDPAssoc)
- err: Error if connection, auth, or request fails
Behavior ¶
On success, the connection deadline is cleared for indefinite use. On error, the connection is closed.
Examples ¶
// CONNECT command
conn, _, err := client.Request(ctx, protocol.CmdConnect,
protocol.AddrFromHostPort("example.com:80", "tcp"))
// BIND command
listener, bindAddr, err := client.Request(ctx, protocol.CmdBind,
protocol.AddrFromHostPort("0.0.0.0:0", "tcp"))
See Also ¶
- Dial: High-level TCP connection
- DialPacket: High-level UDP connection
- Listen: High-level BIND
func (*Client) Version ¶
Version returns the SOCKS protocol version.
Returns "5" as default if SocksVersion is empty.
Returns ¶
"4", "4a", "5", or "5" (default)
func (*Client) WithTorIsolation ¶
WithTorIsolation creates a copy of the Client with Tor stream isolation enabled.
WithTorIsolation implements the Tor SOCKS extension for stream isolation as specified in https://spec.torproject.org/socks-extensions.html#extended-auth
The method configures the client to use extended authentication with format type 0, where the stream isolation parameter is sent in the password field.
Parameters ¶
- id: Pointer to stream isolation ID string. If nil, a random ID is generated.
Behavior ¶
- Creates a shallow copy of the Client
- Generates or uses the provided stream isolation ID
- Trims the ID if it exceeds the maximum password length (255 bytes)
- Sets username to "<torS0X>0" (magic prefix + format type 0)
- Sets password to the stream isolation ID
- Removes all other authentication methods
Stream Isolation ¶
Streams with different isolation IDs will use separate Tor circuits. Streams with the same isolation ID may share a circuit.
Examples ¶
// Client with random stream isolation
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "127.0.0.1:9050",
}
isolatedClient := client.WithTorIsolation(nil)
// Client with specific isolation ID
client := &socksgo.Client{
SocksVersion: "5",
ProxyAddr: "127.0.0.1:9050",
}
sessionID := "user-session-123"
isolatedClient := client.WithTorIsolation(&sessionID)
// Long IDs are automatically trimmed
longID := strings.Repeat("x", 300)
isolatedClient := client.WithTorIsolation(&longID)
Notes ¶
- This method is designed for SOCKS5 clients connecting to Tor
- For SOCKS4 or non-Tor proxies, the credentials are sent as-is (behavior depends on proxy implementation)
- The original client is not modified; a copy is returned
type CommandHandler ¶
type CommandHandler struct {
Socks4 bool
Socks5 bool
TLSCompat bool
// Handler is the function that executes the command.
//
// Parameters:
// - ctx: Context for cancellation and timeouts
// - server: Server instance (for accessing config, dialers, etc.)
// - conn: Client connection
// - ver: SOCKS version ("4", "4a", "5")
// - info: Authentication information from handshake
// - cmd: Command code being executed
// - addr: Target address from client request
//
// Returns:
// - error: Non-nil error closes the connection
//
// The handler is responsible for sending the appropriate reply
// to the client before proxying data. Use protocol.Reply()
// for standard replies or protocol.Reject() for errors.
//
// # See Also
//
// - protocol.Reply: Send success reply
// - protocol.Reject: Send error reply
// - protocol.PipeConn: Proxy data between connections
Handler func(
ctx context.Context,
server *Server,
conn net.Conn,
ver string,
info protocol.AuthInfo,
cmd protocol.Cmd,
addr protocol.Addr,
) error
}
CommandHandler defines a handler for a SOCKS command.
CommandHandler encapsulates the implementation of a SOCKS command along with metadata about which protocol versions and transport modes it supports.
Fields ¶
- Socks4: true if handler supports SOCKS4/4a
- Socks5: true if handler supports SOCKS5
- TLSCompat: true if handler works over TLS connections
- Handler: The actual handler function
Handler Function ¶
The Handler function is called after: 1. Authentication succeeds 2. Command is validated 3. PreCmd hook passes 4. Address filters pass
The handler is responsible for:
- call address filters suitable for its purpose
- Sending the appropriate reply to the client
- Executing the command (dialing, listening, etc.)
- Proxying data between client and target
- Returning errors (which close the connection)
Examples ¶
// Custom CONNECT handler with logging
customHandler := CommandHandler{
Socks4: true,
Socks5: true,
TLSCompat: true,
Handler: func(ctx context.Context, server *Server,
conn net.Conn, ver string, info protocol.AuthInfo,
cmd protocol.Cmd, addr protocol.Addr) error {
log.Printf("CONNECT to %s", addr)
// Call default handler
return socksgo.DefaultConnectHandler.Handler(
ctx, server, conn, ver, info, cmd, addr)
},
}
See Also ¶
- DefaultCommandHandlers: Built-in handlers
- server_handler_*.go: Individual handler implementations
func (*CommandHandler) Allowed ¶
func (h *CommandHandler) Allowed(ver string, isTLS bool) bool
Allowed reports whether the handler supports the given version and TLS mode.
Allowed checks if the handler can handle requests for the specified SOCKS version and TLS configuration.
Parameters ¶
- ver: SOCKS version ("4", "4a", "5", "5h")
- isTLS: true if connection is encrypted
Returns ¶
- true: Handler supports this version/TLS combination
- false: Handler does not support this combination
Behavior ¶
Returns false if:
- Handler is nil
- isTLS is true but TLSCompat is false
- ver is "4" or "4a" but Socks4 is false
- ver is "5" or "5h" but Socks5 is false
func (*CommandHandler) Run ¶
func (h *CommandHandler) Run( ctx context.Context, server *Server, conn net.Conn, ver string, info protocol.AuthInfo, cmd protocol.Cmd, addr protocol.Addr, ) error
Run executes the command handler.
Run calls the Handler function if it is set, otherwise returns a NilHandlerError.
Parameters ¶
- ctx: Context for cancellation and timeouts
- server: Server instance
- conn: Client connection
- ver: SOCKS version ("4", "4a", "5")
- info: Authentication information
- cmd: Command code
- addr: Target address
Returns ¶
Error from handler, or NilHandlerError if handler is nil.
type Dialer ¶
Dialer is a function type for establishing TCP connections. It matches the signature of net.Dialer.DialContext.
type Filter ¶
Filter determines whether an address should bypass the proxy and use direct connection. Return true to use direct connection, false to route through proxy. network may be "" if unknown.
Filters are used with the Client.Filter field and server address filters. Use BuildFilter() to create filters from no_proxy-style strings.
func BuildFilter ¶
BuildFilter creates a Filter from a comma-separated string similar to the NO_PROXY environment variable format.
Each entry can be:
- host:port - matches this host and port combination
- host - matches this host on any port
- ip - matches this exact IP address
- ip/subnet - matches any IP in this CIDR subnet
- Wildcards (*, ?) are supported in host patterns using shell glob matching
Examples:
- "localhost,127.0.0.1" - bypass for localhost and IPv4 loopback
- "*.example.com" - bypass for all subdomains of example.com
- "192.168.0.0/16" - bypass for entire 192.168.x.x subnet
- "internal.corp:8080" - bypass for specific host:port
The filter is case-insensitive and handles both bracketed IPv6 addresses (e.g., [::1]:8080) and trailing dots in hostnames.
type NilHandlerError ¶
NilHandlerError is returned when a command handler is not registered for the requested command.
func (NilHandlerError) Error ¶
func (e NilHandlerError) Error() string
type PacketConn ¶
type PacketConn interface {
net.PacketConn
net.Conn
}
PacketConn is a combined interface for UDP packet connections. It embeds both net.PacketConn and net.Conn for full duplex communication.
type PacketDialer ¶
type PacketDialer = func(ctx context.Context, network, address string) (PacketConn, error)
PacketDialer is a function type for establishing UDP packet connections.
type PacketListener ¶
type PacketListener = func(ctx context.Context, network, address string) (PacketConn, error)
PacketListener is a function type for creating UDP packet listeners.
type RejectdError ¶
type RejectdError struct {
Status protocol.ReplyStatus
}
RejectdError wraps a server rejection response with the reply status code.
func (RejectdError) Error ¶
func (e RejectdError) Error() string
type Resolver ¶
type Resolver interface {
LookupIP(ctx context.Context, network, address string) ([]net.IP, error)
LookupAddr(ctx context.Context, address string) ([]string, error)
}
Resolver provides DNS lookup capabilities. It matches the interface of net.Resolver.
type Server ¶
type Server struct {
// Pool is a buffer pool for memory-efficient operations.
//
// If nil, buffers are allocated without pooling.
//
// Using a shared pool can reduce memory allocations and GC pressure.
Pool bufpool.Pool
// Auth contains server-side authentication handlers.
//
// Multiple auth methods can be registered; the server selects
// one during SOCKS5 authentication negotiation.
//
// Examples:
//
// server.Auth = (&protocol.AuthHandlers{}).
// Add(&protocol.NoAuthHandler{}).
// Add(&protocol.PassAuthHandler{Verify: verifyFunc})
Auth *protocol.AuthHandlers
// Smux configures connection multiplexing for Gost MBIND.
//
// Only used when handling CmdGostMuxBind commands.
//
// Example:
//
// server.Smux = &smux.Config{
// MaxFrameSize: 65535,
// MaxReceiveBuffer: 4194304,
// }
Smux *smux.Config
// UDPBufferSize is the buffer size for UDP packet forwarding.
//
// Default: 8192 bytes
//
// Used by UDP ASSOC and Gost UDPTun handlers.
UDPBufferSize int
// UDPTimeout is the timeout for UDP associations.
//
// Default: 2 minutes (120 seconds)
//
// UDP associations are closed after this duration of inactivity.
UDPTimeout time.Duration
// HandshakeTimeout specifies the timeout for SOCKS handshake
// (authentication and command request).
//
// Default: 0 (no timeout)
//
// If set, the connection deadline is set to time.Now() + timeout
// during handshake, then cleared after successful handshake.
HandshakeTimeout time.Duration
// DoNotPreferIP4 controls IPv4 preference for Tor resolve replies.
//
// When false (default), if both IPv4 and IPv6 addresses are returned
// from a DNS lookup, IPv4 is preferred in the reply.
//
// When true, the first returned address is used regardless of type.
DoNotPreferIP4 bool
// DefaultListenHost is the default host for BIND/MBIND/UDPAssoc commands.
//
// If set, this host is used instead of "0.0.0.0" or "::" when the
// client requests an unspecified address.
//
// Default: "" (use system default)
DefaultListenHost string
// UseIDENT determines whether IDENT lookup is performed for SOCKS4.
//
// If non-nil, called with (username, clientAddr) to determine if
// IDENT verification should be attempted.
//
// IDENT (RFC 1413) verifies the username by querying port 113 on
// the client's IP address.
//
// Default: nil (no IDENT verification)
UseIDENT func(user string, clientAddr net.Addr) bool
// LaddrFilter filters local addresses for listening commands
// (BIND, MBIND, UDPAssoc, UDPTun).
//
// Return true to allow, false to reject.
//
// If nil, all addresses are allowed.
//
// Examples:
//
// // Reject unspecified addresses
// server.LaddrFilter = func(addr *protocol.Addr) bool {
// return !addr.IsUnspecified()
// }
LaddrFilter func(laddr *protocol.Addr) bool
// RaddrFilter filters remote addresses for outgoing commands
// (CONNECT, Tor Resolve, etc.).
//
// Return true to allow, false to reject.
//
// If nil, all addresses are allowed.
//
// Examples:
//
// // Use client Filter for server-side filtering
// server.RaddrFilter = func(addr *protocol.Addr) bool {
// return socksgo.BuildFilter("localhost,192.168.0.0/16")(
// "", addr.ToHostPort())
// }
RaddrFilter func(raddr *protocol.Addr) bool
// PreCmd is a hook called before executing any command.
//
// Parameters:
// - ctx: Context for the connection
// - conn: Client connection
// - ver: SOCKS version ("4", "4a", "5")
// - info: Authentication information
// - cmd: Requested command
// - addr: Target address
//
// Returns:
// - protocol.ReplyStatus: Status to send if rejecting
// - error: Error to return (connection closed)
//
// If non-nil error or non-Ok status is returned, the request is
// rejected. For nil error with non-Ok status, Rejected(91) is used.
//
// Examples:
//
// server.PreCmd = func(ctx context.Context, conn net.Conn,
// ver string, info protocol.AuthInfo, cmd protocol.Cmd,
// addr protocol.Addr) (protocol.ReplyStatus, error) {
// log.Printf("Command %s to %s", cmd, addr)
// return 0, nil // Allow
// }
PreCmd func(
ctx context.Context,
conn net.Conn,
ver string,
info protocol.AuthInfo,
cmd protocol.Cmd,
addr protocol.Addr,
) (protocol.ReplyStatus, error)
// Handlers maps commands to their handlers.
//
// If nil, DefaultCommandHandlers is used.
//
// To customize handlers, copy DefaultCommandHandlers and modify:
//
// handlers := make(map[protocol.Cmd]CommandHandler)
// for k, v := range socksgo.DefaultCommandHandlers {
// handlers[k] = v
// }
// handlers[protocol.CmdConnect] = myCustomHandler
// server.Handlers = handlers
Handlers map[protocol.Cmd]CommandHandler
// Dialer is used to establish outgoing TCP connections for
// CONNECT and other commands requiring TCP dialing.
//
// Default: net.Dialer.DialContext
Dialer Dialer
// PacketDialer is used to establish outgoing UDP connections for
// UDP ASSOC and Gost UDPTun commands.
//
// Default: net.DialUDP
PacketDialer PacketDialer
// Listener is used to create TCP listeners for BIND and MBIND commands.
//
// Default: net.ListenConfig.Listen
Listener Listener
// PacketListener is used to create UDP listeners for UDP ASSOC
// and Gost UDPTun commands.
//
// Default: net.ListenUDP
PacketListener PacketListener
// AssocListener creates UDP listeners for UDP ASSOC commands.
//
// If nil, a UDP listener is created based on the control connection's
// local address.
//
// This allows custom UDP association handling, such as using a
// specific port range or interface.
AssocListener func(ctx context.Context, ctrl net.Conn) (assoc PacketConn, err error)
// Resolver is used for DNS lookups in Tor Resolve commands.
//
// Default: net.DefaultResolver
Resolver Resolver
// DanglingConnections disable closing of used connections after handler
// returns.
DanglingConnections bool
}
Server is a SOCKS proxy server.
Server accepts incoming SOCKS4, SOCKS4a, and SOCKS5 connections, performs authentication negotiation, and dispatches commands to appropriate handlers.
Quick Start ¶
// Create server with default handlers
server := &socksgo.Server{
Auth: authHandlers,
Handlers: socksgo.DefaultCommandHandlers,
}
// Accept connections
listener, _ := net.Listen("tcp", "127.0.0.1:1080")
for {
conn, _ := listener.Accept()
go server.Accept(ctx, conn, false)
}
Thread Safety ¶
Server is safe for concurrent use. Multiple goroutines can call Accept simultaneously, and handlers execute independently.
See Also ¶
- Accept: Main entry point for TCP connections
- AcceptWS: Entry point for WebSocket connections
- server_handlers.go: CommandHandler type and default handlers
func (*Server) Accept ¶
Accept accepts and handles a SOCKS connection.
Accept is the main entry point for handling incoming SOCKS connections. It reads the protocol version, routes to the appropriate handler (accept4 or accept5), and manages the authentication and command dispatch flow.
Parameters ¶
- ctx: Context for cancellation and timeouts
- conn: TCP connection from client
- isTLS: true if connection is encrypted (TLS)
Behavior ¶
1. Reads version byte from connection 2. Routes to accept4 (SOCKS4/4a) or accept5 (SOCKS5) 3. Connection is closed on return (deferred)
Thread Safety ¶
Accept is safe for concurrent use. Each connection is handled independently.
Examples ¶
// TCP server
listener, _ := net.Listen("tcp", "127.0.0.1:1080")
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go server.Accept(ctx, conn, false)
}
// TLS server
tlsListener := tls.Listen(listener, tlsConfig)
for {
conn, err := tlsListener.Accept()
if err != nil {
continue
}
go server.Accept(ctx, conn, true)
}
Errors ¶
Returns error if:
- Version byte cannot be read
- Unknown SOCKS version (not 4 or 5)
- Authentication fails
- Handler execution fails
See Also ¶
- AcceptWS: Accept WebSocket connections
func (*Server) AcceptWS ¶
AcceptWS accepts a SOCKS connection over WebSocket.
AcceptWS wraps the WebSocket connection and delegates to Accept. It handles the WebSocket framing layer for SOCKS over WS/WSS.
Parameters ¶
- ctx: Context for cancellation and timeouts
- conn: WebSocket connection from gorilla/websocket
- isTLS: true if connection is encrypted (WSS)
Thread Safety ¶
AcceptWS is safe for concurrent use.
Examples ¶
// WebSocket server
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
conn, _ := websocket.Upgrade(w, r, nil, 1024, 1024)
go server.AcceptWS(r.Context(), conn, r.TLS != nil)
})
See Also ¶
- Accept: Accept TCP connections
- wsConn: WebSocket connection wrapper
func (*Server) CheckBothAddr ¶
CheckBothAddr validates both local and remote addresses.
CheckBothAddr calls CheckLaddr and CheckRaddr to validate both addresses. Returns the first error encountered.
Parameters ¶
- laddr: Local address to validate
- raddr: Remote address to validate
Returns ¶
- nil: Both addresses are allowed
- AddrDisallowedError: One address was rejected
See Also ¶
- CheckLaddr: Validate local address
- CheckRaddr: Validate remote address
func (*Server) CheckLaddr ¶
CheckLaddr validates a local address against LaddrFilter.
CheckLaddr is used for listening commands (BIND, MBIND, UDPAssoc, UDPTun) to ensure the requested bind address is allowed.
Parameters ¶
- laddr: Local address to validate
Returns ¶
- nil: Address is allowed (or filter is nil)
- AddrDisallowedError: Address was rejected by filter
See Also ¶
- LaddrFilter: Server configuration field
- CheckRaddr: Validate remote address
func (*Server) CheckRaddr ¶
CheckRaddr validates a remote address against RaddrFilter.
CheckRaddr is used for outgoing commands (CONNECT, Tor Resolve) to ensure the target address is allowed.
Parameters ¶
- raddr: Remote address to validate
Returns ¶
- nil: Address is allowed (or filter is nil)
- AddrDisallowedError: Address was rejected by filter
See Also ¶
- RaddrFilter: Server configuration field
- CheckLaddr: Validate local address
func (*Server) CheckUseIDENT ¶
CheckUseIDENT reports whether IDENT verification should be performed.
CheckUseIDENT calls the UseIDENT function if set, otherwise returns false.
Parameters ¶
- user: Username from SOCKS4 request
- clientAddr: Client's network address
Returns ¶
- true: Perform IDENT verification
- false: Skip IDENT verification
See Also ¶
- UseIDENT: Server configuration field
- checkIDENT: IDENT verification implementation
func (*Server) GetAuth ¶
func (s *Server) GetAuth() *protocol.AuthHandlers
GetAuth returns the server's authentication handlers.
Returns ¶
Auth if set, otherwise nil (no authentication required).
func (*Server) GetDefaultListenHost ¶
GetDefaultListenHost returns the default host for listening commands.
Returns ¶
DefaultListenHost if set, otherwise "" (system default).
func (*Server) GetDialer ¶
GetDialer returns the TCP dialer for server operations.
Returns ¶
Dialer if set, otherwise net.Dialer.DialContext.
See Also ¶
- Dialer: Server configuration field
func (*Server) GetHandler ¶
func (s *Server) GetHandler(cmd protocol.Cmd) *CommandHandler
GetHandler returns the handler for a command.
GetHandler looks up the command handler from the Handlers map. If Handlers is nil or the command is not found, returns the corresponding handler from DefaultCommandHandlers.
Parameters ¶
- cmd: Command code to look up
Returns ¶
Pointer to CommandHandler, or nil if not found.
See Also ¶
- Handlers: Server command handler map
- DefaultCommandHandlers: Built-in handlers
func (*Server) GetHandshakeTimeout ¶
GetHandshakeTimeout returns the configured handshake timeout.
Returns ¶
HandshakeTimeout if set, otherwise 0 (no timeout).
func (*Server) GetListener ¶
GetListener returns the TCP listener for server operations.
Returns ¶
Listener if set, otherwise net.ListenConfig.Listen.
See Also ¶
- Listener: Server configuration field
func (*Server) GetPacketDialer ¶
func (s *Server) GetPacketDialer() PacketDialer
GetPacketDialer returns the UDP packet dialer for server operations.
Returns ¶
PacketDialer if set, otherwise net.DialUDP.
See Also ¶
- PacketDialer: Server configuration field
func (*Server) GetPacketListener ¶
func (s *Server) GetPacketListener() PacketListener
GetPacketListener returns the UDP packet listener for server operations.
Returns ¶
PacketListener if set, otherwise net.ListenUDP.
See Also ¶
- PacketListener: Server configuration field
func (*Server) GetPool ¶
GetPool returns the server's buffer pool.
Returns ¶
Pool if set, otherwise nil (no pooling).
func (*Server) GetResolver ¶
GetResolver returns the DNS resolver for server operations.
Returns ¶
Resolver if set, otherwise net.DefaultResolver.
See Also ¶
- Resolver: Server configuration field
func (*Server) GetSmux ¶
GetSmux returns the server's smux configuration.
Returns ¶
Smux if set, otherwise nil (default smux settings).
func (*Server) GetUDPBufferSize ¶
GetUDPBufferSize returns the configured UDP buffer size.
Returns ¶
UDPBufferSize if set, otherwise 8192 bytes.
func (*Server) GetUDPTimeout ¶
GetUDPTimeout returns the configured UDP timeout.
Returns ¶
UDPTimeout if set, otherwise 180 seconds (3 minutes).
func (*Server) IsPreferIPv4 ¶
IsPreferIPv4 reports whether IPv4 addresses are preferred for Tor resolve.
Returns true by default (including when s is nil).
Returns ¶
- true: Prefer IPv4 when both IPv4 and IPv6 are available
- false: Use first returned address regardless of type
See Also ¶
- DoNotPreferIP4: Server configuration field
func (*Server) ListenForAssoc ¶
func (s *Server) ListenForAssoc( ctx context.Context, ctrl net.Conn, ) (assoc PacketConn, err error)
ListenForAssoc creates a UDP listener for UDP ASSOC commands.
ListenForAssoc calls AssocListener if set, otherwise creates a UDP listener based on the control connection's local address.
Parameters ¶
- ctx: Context for cancellation and timeouts
- ctrl: Control TCP connection from client
Returns ¶
PacketConn for UDP association or error.
Behavior ¶
If AssocListener is nil:
- Gets local address from control connection
- Extracts host from address
- Creates UDP listener on host:0 (any port)
See Also ¶
- AssocListener: Server configuration field
- DefaultUDPAssocHandler: Handler that calls this function
type UnknownSocksVersionError ¶
type UnknownSocksVersionError struct {
Version string
}
UnknownSocksVersionError is returned when an unrecognized SOCKS version is specified.
func (UnknownSocksVersionError) Error ¶
func (e UnknownSocksVersionError) Error() string
type UnsupportedAddrError ¶
UnsupportedAddrError is returned when an address type is not supported by the specified SOCKS version (e.g., FQDN with SOCKS4).
func (UnsupportedAddrError) Error ¶
func (e UnsupportedAddrError) Error() string
type UnsupportedCommandError ¶
UnsupportedCommandError is returned when a command is not supported by the specified SOCKS version.
func (UnsupportedCommandError) Error ¶
func (e UnsupportedCommandError) Error() string
type WebSocketConfig ¶
type WebSocketConfig struct {
// ReadBufferSize is the buffer size for WebSocket reads.
//
// If zero, websocket.DefaultDialer.ReadBufferSize is used.
ReadBufferSize int
// Subprotocols is the list of WebSocket subprotocols to negotiate.
//
// If nil, websocket.DefaultDialer.Subprotocols is used.
Subprotocols []string
// EnableCompression enables per-message compression (RFC 7692).
//
// If false, compression is disabled.
//
// Default: false (websocket.DefaultDialer.EnableCompression)
EnableCompression bool
// Jar is the cookie jar for HTTP cookies during WebSocket handshake.
//
// If nil, websocket.DefaultDialer.Jar is used.
Jar http.CookieJar
// RequestHeader contains custom HTTP headers for WebSocket upgrade request.
RequestHeader http.Header
}
WebSocketConfig configures WebSocket connections for SOCKS over WS.
WebSocketConfig provides options for customizing WebSocket dialing when using SOCKS over WebSocket transport (WebSocketURL is set).
Examples ¶
client := &socksgo.Client{
SocksVersion: "5",
WebSocketURL: "wss://proxy.example.com/ws",
WebSocketConfig: &socksgo.WebSocketConfig{
ReadBufferSize: 32768,
Subprotocols: []string{"binary"},
EnableCompression: true,
RequestHeader: http.Header{
"X-Custom-Header": []string{"value"},
},
},
}
See Also ¶
- Client.WebSocketURL: Enable WebSocket transport
- github.com/gorilla/websocket: Underlying WebSocket library
type WrongNetworkError ¶
func (WrongNetworkError) Error ¶
func (e WrongNetworkError) Error() string
func (WrongNetworkError) Unwrap ¶
func (e WrongNetworkError) Unwrap() error
Source Files
¶
- client.go
- client4.go
- client5.go
- client_config.go
- client_hooks_default.go
- common.go
- errors.go
- server.go
- server_config.go
- server_handler_assoc.go
- server_handler_bind.go
- server_handler_connect.go
- server_handler_mbind.go
- server_handler_resolve.go
- server_handler_resolveptr.go
- server_handler_tun.go
- server_handlers.go
- ws.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
bind
command
nolint
|
nolint |
|
client-chaining
command
nolint
|
nolint |
|
connect
command
nolint
|
nolint |
|
custom-auth
command
nolint
|
nolint |
|
custom-cmd/client
command
nolint
|
nolint |
|
custom-cmd/server
command
nolint
|
nolint |
|
gss-auth
command
nolint
|
nolint |
|
interceptor
command
nolint
|
nolint |
|
resolve
command
nolint
|
nolint |
|
resolve-ptr
command
nolint
|
nolint |
|
server
command
nolint
|
nolint |
|
server-chaining
command
nolint
|
nolint |
|
tor-isolation
command
nolint
|
nolint |
|
udpassoc
command
nolint
|
nolint |
|
Package protocol implements low-level SOCKS protocol encoding and decoding.
|
Package protocol implements low-level SOCKS protocol encoding and decoding. |