diff --git a/go.mod b/go.mod index 9caf0c8..03694ae 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/thinkgos/socks5 go 1.14 + +require golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e diff --git a/go.sum b/go.sum index e69de29..9541a65 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,6 @@ +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/socks5_test.go b/socks5_test.go index 5939514..945032d 100644 --- a/socks5_test.go +++ b/socks5_test.go @@ -8,6 +8,8 @@ import ( "os" "testing" "time" + + "golang.org/x/net/proxy" ) func TestSOCKS5_Connect(t *testing.T) { @@ -232,3 +234,72 @@ func TestSOCKS5_Associate(t *testing.T) { } time.Sleep(time.Second * 1) } + +func Test_SocksWithProxy(t *testing.T) { + // Create a local listener + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("err: %v", err) + } + go func() { + conn, err := l.Accept() + if err != nil { + t.Fatalf("err: %v", err) + } + defer conn.Close() + + buf := make([]byte, 4) + if _, err := io.ReadAtLeast(conn, buf, 4); err != nil { + t.Fatalf("err: %v", err) + } + + if !bytes.Equal(buf, []byte("ping")) { + t.Fatalf("bad: %v", buf) + } + conn.Write([]byte("pong")) + }() + lAddr := l.Addr().(*net.TCPAddr) + + // Create a socks server + cator := UserPassAuthenticator{Credentials: StaticCredentials{"foo": "bar"}} + conf := &Config{ + AuthMethods: []Authenticator{cator}, + Logger: NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags)), + } + serv, err := New(conf) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Start listening + go func() { + if err := serv.ListenAndServe("tcp", "127.0.0.1:12395"); err != nil { + t.Fatalf("err: %v", err) + } + }() + time.Sleep(10 * time.Millisecond) + + dial, err := proxy.SOCKS5("tcp", "127.0.0.1:12395", &proxy.Auth{"foo", "bar"}, proxy.Direct) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Connect, auth and connect to local + conn, err := dial.Dial("tcp", lAddr.String()) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Send a ping + conn.Write([]byte("ping")) + + out := make([]byte, 4) + conn.SetDeadline(time.Now().Add(time.Second)) + if _, err := io.ReadFull(conn, out); err != nil { + t.Fatalf("err: %v", err) + } + + if !bytes.Equal(out, []byte("pong")) { + t.Fatalf("bad: %v", out) + } +}