add all testing
This commit is contained in:
parent
372b42cd09
commit
10f96879ba
26
README.md
26
README.md
@ -9,7 +9,7 @@ go-socks5
|
||||
[![License](https://img.shields.io/github/license/thinkgos/go-socks5)](https://github.com/thinkgos/go-socks5/raw/master/LICENSE)
|
||||
[![Tag](https://img.shields.io/github/v/tag/thinkgos/go-socks5)](https://github.com/thinkgos/go-socks5/tags)
|
||||
|
||||
Provides the `socks5` package that implements a [SOCKS5 server](http://en.wikipedia.org/wiki/SOCKS).
|
||||
Provides the `socks5` package that implements a [SOCKS5](http://en.wikipedia.org/wiki/SOCKS).
|
||||
SOCKS (Secure Sockets) is used to route traffic between a client and server through
|
||||
an intermediate proxy layer. This can be used to bypass firewalls or NATs.
|
||||
|
||||
@ -17,22 +17,24 @@ Feature
|
||||
=======
|
||||
|
||||
The package has the following features:
|
||||
* Unit tests
|
||||
* "No Auth" mode
|
||||
* User/Password authentication optional user addr limit
|
||||
* Support for the CONNECT command
|
||||
* Support for the ASSOCIATE command
|
||||
* Rules to do granular filtering of commands
|
||||
* Custom DNS resolution
|
||||
* Custom goroutine pool
|
||||
* buffer pool design and optional custom buffer pool
|
||||
* Custom logger
|
||||
- Support client(**under ccsocks5 directory**) and server(**under root directory**)
|
||||
- Support TCP/UDP and IPv4/IPv6
|
||||
- Unit tests
|
||||
- "No Auth" mode
|
||||
- User/Password authentication optional user addr limit
|
||||
- Support for the CONNECT command
|
||||
- Support for the ASSOCIATE command
|
||||
- Rules to do granular filtering of commands
|
||||
- Custom DNS resolution
|
||||
- Custom goroutine pool
|
||||
- buffer pool design and optional custom buffer pool
|
||||
- Custom logger
|
||||
|
||||
TODO
|
||||
====
|
||||
|
||||
The package still needs the following:
|
||||
* Support for the BIND command
|
||||
- Support for the BIND command
|
||||
|
||||
Example
|
||||
=======
|
||||
|
@ -22,7 +22,8 @@ type Client struct {
|
||||
bufferPool bufferpool.BufPool
|
||||
}
|
||||
|
||||
// NewClient This is just create a client, you need to use Dial to create conn.
|
||||
// NewClient This is just create a client.
|
||||
// you need to use Dial to create conn.
|
||||
func NewClient(proxyAddr string, opts ...Option) (*Client, error) {
|
||||
c := &Client{
|
||||
proxyAddr: proxyAddr,
|
||||
@ -37,7 +38,9 @@ func NewClient(proxyAddr string, opts ...Option) (*Client, error) {
|
||||
|
||||
// Close closes the connection.
|
||||
func (sf *Client) Close() (err error) {
|
||||
err = sf.tcpConn.Close()
|
||||
if sf.tcpConn != nil {
|
||||
err = sf.tcpConn.Close()
|
||||
}
|
||||
if sf.Conn != nil {
|
||||
err = sf.Conn.Close()
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ func (sf *Server) Serve(l net.Listener) error {
|
||||
}
|
||||
sf.submit(func() {
|
||||
if err := sf.ServeConn(conn); err != nil {
|
||||
sf.logger.Errorf("server conn %v", err)
|
||||
sf.logger.Errorf("server: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
128
testing/socks5_test.go
Normal file
128
testing/socks5_test.go
Normal file
@ -0,0 +1,128 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/net/proxy"
|
||||
|
||||
"github.com/thinkgos/go-socks5"
|
||||
"github.com/thinkgos/go-socks5/bufferpool"
|
||||
"github.com/thinkgos/go-socks5/ccsocks5"
|
||||
)
|
||||
|
||||
func Test_Socks5_Connect(t *testing.T) {
|
||||
// Create a local listener
|
||||
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
|
||||
go func() {
|
||||
conn, err := l.Accept()
|
||||
require.NoError(t, err)
|
||||
defer conn.Close()
|
||||
|
||||
buf := make([]byte, 4)
|
||||
_, err = io.ReadAtLeast(conn, buf, 4)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("ping"), buf)
|
||||
|
||||
conn.Write([]byte("pong")) // nolint: errcheck
|
||||
}()
|
||||
|
||||
// Create a socks server with UserPass auth.
|
||||
cator := socks5.UserPassAuthenticator{Credentials: socks5.StaticCredentials{"user": "pass"}}
|
||||
srv := socks5.NewServer(
|
||||
socks5.WithAuthMethods([]socks5.Authenticator{cator}),
|
||||
socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))),
|
||||
)
|
||||
|
||||
// Start listening
|
||||
go func() {
|
||||
err := srv.ListenAndServe("tcp", "127.0.0.1:12389")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
// Get a local conn
|
||||
client, err := ccsocks5.NewClient("127.0.0.1:12389",
|
||||
ccsocks5.WithAuth(&proxy.Auth{User: "user", Password: "pass"}),
|
||||
ccsocks5.WithBufferPool(bufferpool.NewPool(32*1024)),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
conn, err := client.Dial("tcp", l.Addr().String())
|
||||
require.NoError(t, err)
|
||||
defer conn.Close()
|
||||
// Send all the bytes
|
||||
conn.Write([]byte("ping")) // nolint: errcheck
|
||||
|
||||
out := make([]byte, 4)
|
||||
conn.SetDeadline(time.Now().Add(time.Second)) // nolint: errcheck
|
||||
_, err = io.ReadFull(conn, out)
|
||||
conn.SetDeadline(time.Time{}) // nolint: errcheck
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []byte("pong"), out)
|
||||
}
|
||||
|
||||
func Test_socks5_Associate(t *testing.T) {
|
||||
locIP := net.ParseIP("127.0.0.1")
|
||||
// Create a local listener
|
||||
lAddr := &net.UDPAddr{IP: locIP, Port: 12312}
|
||||
l, err := net.ListenUDP("udp", lAddr)
|
||||
require.NoError(t, err)
|
||||
defer l.Close()
|
||||
|
||||
go func() {
|
||||
buf := make([]byte, 2048)
|
||||
for {
|
||||
n, remote, err := l.ReadFrom(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
require.Equal(t, []byte("ping"), buf[:n])
|
||||
|
||||
l.WriteTo([]byte("pong"), remote) // nolint: errcheck
|
||||
}
|
||||
}()
|
||||
|
||||
// Create a socks server
|
||||
cator := socks5.UserPassAuthenticator{Credentials: socks5.StaticCredentials{"user": "pass"}}
|
||||
proxySrv := socks5.NewServer(
|
||||
socks5.WithAuthMethods([]socks5.Authenticator{cator}),
|
||||
socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))),
|
||||
)
|
||||
// Start listening
|
||||
go func() {
|
||||
err := proxySrv.ListenAndServe("tcp", "127.0.0.1:12385")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
// Get a local conn
|
||||
client, err := ccsocks5.NewClient(
|
||||
"127.0.0.1:12385",
|
||||
ccsocks5.WithAuth(&proxy.Auth{User: "user", Password: "pass"}),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
conn, err := client.Dial("udp", lAddr.String())
|
||||
require.NoError(t, err)
|
||||
|
||||
// send ping
|
||||
conn.Write([]byte("ping")) // nolint: errcheck
|
||||
|
||||
// read response
|
||||
out := make([]byte, 4)
|
||||
conn.SetDeadline(time.Now().Add(time.Second)) // nolint: errcheck
|
||||
_, err = io.ReadFull(conn, out)
|
||||
conn.SetDeadline(time.Time{}) // nolint: errcheck
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []byte("pong"), out)
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
Loading…
Reference in New Issue
Block a user