add more examples

This commit is contained in:
zhengrui
2018-12-06 20:46:39 +08:00
parent afb424193e
commit 5baaf4207e
6 changed files with 138 additions and 15 deletions
+36 -6
View File
@@ -7,18 +7,48 @@ import (
"github.com/ginuerzh/gosocks5"
)
type Client struct {
selector gosocks5.Selector
}
// Dial connects to the SOCKS5 server.
func Dial(addr string, options ...DialOption) (net.Conn, error) {
opts := &DialOptions{}
for _, o := range options {
o(opts)
}
func (c *Client) Dial(addr string, options ...DialOption) (net.Conn, error) {
return nil, nil
conn, err := net.DialTimeout("tcp", addr, opts.Timeout)
if err != nil {
return nil, err
}
selector := opts.Selector
if selector == nil {
selector = DefaultSelector
}
cc := gosocks5.ClientConn(conn, selector)
if err := cc.Handleshake(); err != nil {
conn.Close()
return nil, err
}
return cc, nil
}
// DialOptions describes the options for Transporter.Dial.
type DialOptions struct {
Timeout time.Duration
Selector gosocks5.Selector
Timeout time.Duration
}
// DialOption allows a common way to set dial options.
type DialOption func(opts *DialOptions)
func SelectorDialOption(selector gosocks5.Selector) DialOption {
return func(opts *DialOptions) {
opts.Selector = selector
}
}
func TimeoutDialOption(timeout time.Duration) DialOption {
return func(opts *DialOptions) {
opts.Timeout = timeout
}
}
+16 -4
View File
@@ -7,9 +7,21 @@ import (
"github.com/ginuerzh/gosocks5"
)
var (
// DefaultSelector is the default client selector.
DefaultSelector gosocks5.Selector = &clientSelector{}
)
type clientSelector struct {
methods []uint8
User *url.Userinfo
user *url.Userinfo
}
func NewClientSelector(user *url.Userinfo, methods ...uint8) gosocks5.Selector {
return &clientSelector{
methods: methods,
user: user,
}
}
func (selector *clientSelector) Methods() []uint8 {
@@ -28,9 +40,9 @@ func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Con
switch method {
case gosocks5.MethodUserPass:
var username, password string
if selector.User != nil {
username = selector.User.Username()
password, _ = selector.User.Password()
if selector.user != nil {
username = selector.user.Username()
password, _ = selector.user.Password()
}
req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password)
+41
View File
@@ -0,0 +1,41 @@
package main
import (
"flag"
"log"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5/client"
)
var (
server string
)
func init() {
flag.StringVar(&server, "p", "", "SOCKS5 server address")
flag.Parse()
}
func main() {
addr, err := gosocks5.NewAddr(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
conn, err := client.Dial(server)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
if err := gosocks5.NewRequest(gosocks5.CmdConnect, addr).Write(conn); err != nil {
log.Fatal(err)
}
reply, err := gosocks5.ReadReply(conn)
if err != nil {
log.Fatal(err)
}
log.Println("reply:", reply)
}
+1 -1
View File
@@ -17,7 +17,7 @@ var (
func init() {
DefaultHandler = &serverHandler{
selector: &serverSelector{},
selector: DefaultSelector,
}
}
+17 -4
View File
@@ -7,9 +7,22 @@ import (
"github.com/ginuerzh/gosocks5"
)
var (
// DefaultSelector is the default server selector.
// It only supports No-Auth Method.
DefaultSelector gosocks5.Selector = &serverSelector{}
)
type serverSelector struct {
methods []uint8
Users []*url.Userinfo
users []*url.Userinfo
}
func NewServerSelector(users []*url.Userinfo, methods ...uint8) gosocks5.Selector {
return &serverSelector{
methods: methods,
users: users,
}
}
func (selector *serverSelector) Methods() []uint8 {
@@ -24,7 +37,7 @@ func (selector *serverSelector) Select(methods ...uint8) (method uint8) {
method = gosocks5.MethodNoAuth
// when user/pass is set, auth is mandatory
if len(selector.Users) > 0 {
if len(selector.users) > 0 {
method = gosocks5.MethodUserPass
}
@@ -40,7 +53,7 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
}
valid := false
for _, user := range selector.Users {
for _, user := range selector.users {
username := user.Username()
password, _ := user.Password()
if (req.Username == username && req.Password == password) ||
@@ -50,7 +63,7 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
break
}
}
if len(selector.Users) > 0 && !valid {
if len(selector.users) > 0 && !valid {
resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
if err := resp.Write(conn); err != nil {
return nil, err
+27
View File
@@ -273,6 +273,33 @@ type Addr struct {
Port uint16
}
func NewAddr(sa string) (addr *Addr, err error) {
host, sport, err := net.SplitHostPort(sa)
if err != nil {
return nil, err
}
port, err := strconv.Atoi(sport)
if err != nil {
return nil, err
}
addr = &Addr{
Type: AddrDomain,
Host: host,
Port: uint16(port),
}
if ip := net.ParseIP(host); ip != nil {
if ip.To4() != nil {
addr.Type = AddrIPv4
} else {
addr.Type = AddrIPv6
}
}
return
}
func (addr *Addr) Decode(b []byte) error {
addr.Type = b[0]
pos := 1