Documentation
¶
Index ¶
- Constants
- Variables
- func ParseAddress(address string) (a byte, addr []byte, port []byte, err error)
- func ParseBytesAddress(b []byte) (a byte, addr []byte, port []byte, err error)
- func ToAddress(a byte, addr []byte, port []byte) string
- type Client
- func (c *Client) Close() error
- func (c *Client) Dial(network, addr string) (net.Conn, error)
- func (c *Client) DialWithLocalAddr(network, src, dst string, remoteAddr net.Addr) (net.Conn, error)
- func (c *Client) LocalAddr() net.Addr
- func (c *Client) Negotiate(laddr *net.TCPAddr) error
- func (c *Client) Read(b []byte) (int, error)
- func (c *Client) RemoteAddr() net.Addr
- func (c *Client) Request(r *Request) (*Reply, error)
- func (c *Client) SetDeadline(t time.Time) error
- func (c *Client) SetReadDeadline(t time.Time) error
- func (c *Client) SetWriteDeadline(t time.Time) error
- func (c *Client) Write(b []byte) (int, error)
- type Datagram
- type DefaultHandle
- type Handler
- type NegotiationReply
- type NegotiationRequest
- type Reply
- type Request
- type Server
- type UDPExchange
- type UserPassNegotiationReply
- type UserPassNegotiationRequest
Examples ¶
Constants ¶
const ( // Ver is socks protocol version Ver byte = 0x05 // MethodNone is none method MethodNone byte = 0x00 // MethodGSSAPI is gssapi method MethodGSSAPI byte = 0x01 // MUST support // todo // MethodUsernamePassword is username/assword auth method MethodUsernamePassword byte = 0x02 // SHOULD support // MethodUnsupportAll means unsupport all given methods MethodUnsupportAll byte = 0xFF // UserPassVer is username/password auth protocol version UserPassVer byte = 0x01 // UserPassStatusSuccess is success status of username/password auth UserPassStatusSuccess byte = 0x00 // UserPassStatusFailure is failure status of username/password auth UserPassStatusFailure byte = 0x01 // just other than 0x00 // CmdConnect is connect command CmdConnect byte = 0x01 // CmdBind is bind command CmdBind byte = 0x02 // CmdUDP is UDP command CmdUDP byte = 0x03 // ATYPIPv4 is ipv4 address type ATYPIPv4 byte = 0x01 // 4 octets // ATYPDomain is domain address type ATYPDomain byte = 0x03 // The first octet of the address field contains the number of octets of name that follow, there is no terminating NUL octet. // ATYPIPv6 is ipv6 address type ATYPIPv6 byte = 0x04 // 16 octets // RepSuccess means that success for repling RepSuccess byte = 0x00 // RepServerFailure means the server failure RepServerFailure byte = 0x01 // RepNotAllowed means the request not allowed RepNotAllowed byte = 0x02 // RepNetworkUnreachable means the network unreachable RepNetworkUnreachable byte = 0x03 // RepHostUnreachable means the host unreachable RepHostUnreachable byte = 0x04 // RepConnectionRefused means the connection refused RepConnectionRefused byte = 0x05 // RepTTLExpired means the TTL expired RepTTLExpired byte = 0x06 // RepCommandNotSupported means the request command not supported RepCommandNotSupported byte = 0x07 // RepAddressNotSupported means the request address not supported RepAddressNotSupported byte = 0x08 )
Variables ¶
var ( // ErrUnsupportCmd is the error when got unsupport command ErrUnsupportCmd = errors.New("Unsupport Command") // ErrUserPassAuth is the error when got invalid username or password ErrUserPassAuth = errors.New("Invalid Username or Password for Auth") )
var ( // ErrVersion is version error ErrVersion = errors.New("Invalid Version") // ErrUserPassVersion is username/password auth version error ErrUserPassVersion = errors.New("Invalid Version of Username Password Auth") // ErrBadRequest is bad request error ErrBadRequest = errors.New("Bad Request") )
var Debug bool
Debug enable debug log
var Dial x.Dialer = x.DefaultDial
var ( // ErrBadReply is the error when read reply ErrBadReply = errors.New("Bad Reply") )
Functions ¶
func ParseAddress ¶
ParseAddress format address x.x.x.x:xx to raw address. addr contains domain length
func ParseBytesAddress ¶
bytes to address addr contains domain length
Types ¶
type Client ¶
type Client struct { Server string UserName string Password string // On cmd UDP, let server control the tcp and udp connection relationship TCPConn *net.TCPConn UDPConn *net.UDPConn RemoteAddress net.Addr TCPTimeout int UDPTimeout int // HijackServerUDPAddr can let client control which server UDP address to connect to after sending request, // In most cases, you should ignore this, according to the standard server will return the address in reply, // More: https://github.com/leeshung/socks5/pull/8. HijackServerUDPAddr func(*Reply) (*net.UDPAddr, error) }
Client is socks5 client wrapper
Example (Tcp) ¶
package main import ( "io/ioutil" "log" "net" "net/http" "github.com/leeshung/socks5" ) func main() { c, err := socks5.NewClient("127.0.0.1:1080", "", "", 0, 60) if err != nil { panic(err) } client := &http.Client{ Transport: &http.Transport{ Dial: func(network, addr string) (net.Conn, error) { return c.Dial(network, addr) }, }, } res, err := client.Get("https://ifconfig.co") if err != nil { panic(err) } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { panic(err) } log.Println(string(b)) }
Output:
Example (Udp) ¶
package main import ( "encoding/hex" "log" "net" "github.com/leeshung/socks5" ) func main() { c, err := socks5.NewClient("127.0.0.1:1080", "", "", 0, 60) if err != nil { panic(err) } conn, err := c.Dial("udp", "180.76.76.76:53") if err != nil { panic(err) } b, err := hex.DecodeString("0001010000010000000000000a74787468696e6b696e6703636f6d0000010001") if err != nil { panic(err) } if _, err := conn.Write(b); err != nil { panic(err) } b = make([]byte, 2048) n, err := conn.Read(b) if err != nil { panic(err) } b = b[:n] b = b[len(b)-4:] log.Println(net.IPv4(b[0], b[1], b[2], b[3])) }
Output:
func (*Client) DialWithLocalAddr ¶
func (*Client) RemoteAddr ¶
type Datagram ¶
type Datagram struct { Rsv []byte // 0x00 0x00 Frag byte Atyp byte DstAddr []byte DstPort []byte // 2 bytes Data []byte }
Datagram is the UDP packet
func NewDatagram ¶
NewDatagram return datagram packet can be writed into client, dstaddr should not have domain length
func NewDatagramFromBytes ¶
type DefaultHandle ¶
type DefaultHandle struct { }
DefaultHandle implements Handler interface
type Handler ¶
type Handler interface { // Request has not been replied yet TCPHandle(*Server, *net.TCPConn, *Request) error UDPHandle(*Server, *net.UDPAddr, *Datagram) error }
Handler handle tcp, udp request
type NegotiationReply ¶
NegotiationReply is the negotiation reply packet
func NewNegotiationReply ¶
func NewNegotiationReply(method byte) *NegotiationReply
NewNegotiationReply return negotiation reply packet can be writed into client
func NewNegotiationReplyFrom ¶
func NewNegotiationReplyFrom(r io.Reader) (*NegotiationReply, error)
NewNegotiationReplyFrom read negotiation reply packet from server
type NegotiationRequest ¶
NegotiationRequest is the negotiation reqeust packet
func NewNegotiationRequest ¶
func NewNegotiationRequest(methods []byte) *NegotiationRequest
NewNegotiationRequest return negotiation request packet can be writed into server
func NewNegotiationRequestFrom ¶
func NewNegotiationRequestFrom(r io.Reader) (*NegotiationRequest, error)
NewNegotiationRequestFrom read negotiation requst packet from client
type Reply ¶
type Reply struct { Ver byte Rep byte Rsv byte // 0x00 Atyp byte // CONNECT socks server's address which used to connect to dst addr // BIND ... // UDP socks server's address which used to connect to dst addr BndAddr []byte // CONNECT socks server's port which used to connect to dst addr // BIND ... // UDP socks server's port which used to connect to dst addr BndPort []byte // 2 bytes }
Reply is the reply packet
func NewReply ¶
NewReply return reply packet can be writed into client, bndaddr should not have domain length
func NewReplyFrom ¶
NewReplyFrom read reply packet from server
type Request ¶
type Request struct { Ver byte Cmd byte Rsv byte // 0x00 Atyp byte DstAddr []byte DstPort []byte // 2 bytes }
Request is the request packet
func NewRequest ¶
NewRequest return request packet can be writed into server, dstaddr should not have domain length
func NewRequestFrom ¶
NewRequestFrom read requst packet from client
func (*Request) Connect ¶
Connect remote conn which u want to connect with your dialer Error or OK both replied.
type Server ¶
type Server struct { UserName string Password string Method byte SupportedCommands []byte TCPAddr *net.TCPAddr UDPAddr *net.UDPAddr ServerAddr *net.UDPAddr TCPListen *net.TCPListener UDPConn *net.UDPConn UDPExchanges *cache.Cache TCPTimeout int UDPTimeout int Handle Handler AssociatedUDP *cache.Cache UDPSrc *cache.Cache RunnerGroup *runnergroup.RunnerGroup // RFC: [UDP ASSOCIATE] The server MAY use this information to limit access to the association. Default false, no limit. LimitUDP bool }
Server is socks5 server wrapper
Example ¶
package main import ( "github.com/leeshung/socks5" ) func main() { s, err := socks5.NewClassicServer("127.0.0.1:1080", "127.0.0.1", "", "", 0, 60) if err != nil { panic(err) } // You can pass in custom Handler s.ListenAndServe(nil) // #Output: }
Output:
func NewClassicServer ¶
func NewClassicServer(addr, ip, username, password string, tcpTimeout, udpTimeout int) (*Server, error)
NewClassicServer return a server which allow none method
func (*Server) GetRequest ¶
func (s *Server) GetRequest(rw io.ReadWriter) (*Request, error)
GetRequest get request packet from client, and check command according to SupportedCommands Error replied.
type UDPExchange ¶
UDPExchange used to store client address and remote connection
type UserPassNegotiationReply ¶
UserPassNegotiationReply is the negotiation username/password reply packet
func NewUserPassNegotiationReply ¶
func NewUserPassNegotiationReply(status byte) *UserPassNegotiationReply
NewUserPassNegotiationReply return negotiation username password reply packet can be writed into client
func NewUserPassNegotiationReplyFrom ¶
func NewUserPassNegotiationReplyFrom(r io.Reader) (*UserPassNegotiationReply, error)
NewUserPassNegotiationReplyFrom read user password negotiation reply packet from server
type UserPassNegotiationRequest ¶
type UserPassNegotiationRequest struct { Ver byte Ulen byte Uname []byte // 1-255 bytes Plen byte Passwd []byte // 1-255 bytes }
UserPassNegotiationRequest is the negotiation username/password reqeust packet
func NewUserPassNegotiationRequest ¶
func NewUserPassNegotiationRequest(username []byte, password []byte) *UserPassNegotiationRequest
NewUserPassNegotiationRequest return user password negotiation request packet can be writed into server
func NewUserPassNegotiationRequestFrom ¶
func NewUserPassNegotiationRequestFrom(r io.Reader) (*UserPassNegotiationRequest, error)
NewUserPassNegotiationRequestFrom read user password negotiation request packet from client