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.Addr) 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
var DialTCP func(network string, laddr, raddr string) (net.Conn, error) = func(network string, laddr, raddr string) (net.Conn, error) { var la, ra *net.TCPAddr if laddr != "" { var err error la, err = net.ResolveTCPAddr(network, laddr) if err != nil { return nil, err } } a, err := Resolve(network, raddr) if err != nil { return nil, err } ra = a.(*net.TCPAddr) return net.DialTCP(network, la, ra) }
var DialUDP func(network string, laddr, raddr string) (net.Conn, error) = func(network string, laddr, raddr string) (net.Conn, error) { var la, ra *net.UDPAddr if laddr != "" { var err error la, err = net.ResolveUDPAddr(network, laddr) if err != nil { return nil, err } } a, err := Resolve(network, raddr) if err != nil { return nil, err } ra = a.(*net.UDPAddr) return net.DialUDP(network, la, ra) }
var ( // ErrBadReply is the error when read reply ErrBadReply = errors.New("Bad Reply") )
var Resolve func(network string, addr string) (net.Addr, error) = func(network string, addr string) (net.Addr, error) { if network == "tcp" { return net.ResolveTCPAddr("tcp", addr) } return net.ResolveUDPAddr("udp", addr) }
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.Conn UDPConn net.Conn RemoteAddress net.Addr TCPTimeout int UDPTimeout int Dst string }
Client is socks5 client wrapper
Example (Tcp) ¶
go ExampleServer() c, err := socks5.NewClient("127.0.0.1:1080", "", "", 0, 60) if err != nil { log.Println(err) return } 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 { log.Println(err) return } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { log.Println(err) return } log.Println("tcp", string(b))
Output:
Example (Udp) ¶
go ExampleServer() c, err := socks5.NewClient("127.0.0.1:1080", "", "", 0, 60) if err != nil { log.Println(err) return } conn, err := c.Dial("udp", "8.8.8.8:53") if err != nil { log.Println(err) return } b, err := hex.DecodeString("0001010000010000000000000a74787468696e6b696e6703636f6d0000010001") if err != nil { log.Println(err) return } if _, err := conn.Write(b); err != nil { log.Println(err) return } b = make([]byte, 2048) n, err := conn.Read(b) if err != nil { log.Println(err) return } m := &dns.Msg{} if err := m.Unpack(b[0:n]); err != nil { log.Println(err) return } log.Println(m.String())
Output:
func (*Client) DialWithLocalAddr ¶
If you want to send address that expects to use to send UDP, just assign it to src, otherwise it will send zero address. Recommend specifying the src address in a non-NAT environment, and leave it blank in other cases.
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 Addr string ServerAddr net.Addr 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 ¶
s, err := socks5.NewClassicServer("127.0.0.1:1080", "127.0.0.1", "", "", 0, 60) if err != nil { log.Println(err) return } // 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