791 lines
16 KiB
Go
791 lines
16 KiB
Go
package gost
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"net"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
var socks5ProxyTests = []struct {
|
|
cliUser *url.Userinfo
|
|
srvUsers []*url.Userinfo
|
|
pass bool
|
|
}{
|
|
{nil, nil, true},
|
|
{nil, []*url.Userinfo{url.User("admin")}, false},
|
|
{nil, []*url.Userinfo{url.UserPassword("", "123456")}, false},
|
|
{url.User("admin"), []*url.Userinfo{url.User("test")}, false},
|
|
{url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "123456")}, false},
|
|
{url.User("admin"), []*url.Userinfo{url.User("admin")}, true},
|
|
{url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "")}, true},
|
|
{url.UserPassword("admin", "123456"), nil, true},
|
|
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.User("admin")}, true},
|
|
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, false},
|
|
{url.UserPassword("", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, true},
|
|
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("admin", "123456")}, true},
|
|
{url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("user", "pass"), url.UserPassword("admin", "123456")}, true},
|
|
}
|
|
|
|
func socks5ProxyRoundtrip(targetURL string, data []byte, clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5Connector(clientInfo),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(serverInfo...)),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return proxyRoundtrip(client, server, targetURL, data)
|
|
}
|
|
|
|
func TestSOCKS5Proxy(t *testing.T) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
for i, tc := range socks5ProxyTests {
|
|
err := socks5ProxyRoundtrip(httpSrv.URL, sendData,
|
|
tc.cliUser,
|
|
tc.srvUsers,
|
|
)
|
|
if err == nil {
|
|
if !tc.pass {
|
|
t.Errorf("#%d should failed", i)
|
|
}
|
|
} else {
|
|
// t.Logf("#%d %v", i, err)
|
|
if tc.pass {
|
|
t.Errorf("#%d got error: %v", i, err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5Proxy(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5Connector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5ProxyParallel(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5Connector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func socks4ProxyRoundtrip(targetURL string, data []byte) error {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4Connector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return proxyRoundtrip(client, server, targetURL, data)
|
|
}
|
|
|
|
func TestSOCKS4Proxy(t *testing.T) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
err := socks4ProxyRoundtrip(httpSrv.URL, sendData)
|
|
// t.Logf("#%d %v", i, err)
|
|
if err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS4Proxy(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4Connector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS4ProxyParallel(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4Connector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func socks4aProxyRoundtrip(targetURL string, data []byte) error {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4AConnector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return proxyRoundtrip(client, server, targetURL, data)
|
|
}
|
|
|
|
func TestSOCKS4AProxy(t *testing.T) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
err := socks4aProxyRoundtrip(httpSrv.URL, sendData)
|
|
// t.Logf("#%d %v", i, err)
|
|
if err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS4AProxy(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4AConnector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS4AProxyParallel(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS4AConnector(),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Listener: ln,
|
|
Handler: SOCKS4Handler(),
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
if err := proxyRoundtrip(client, server, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func socks5BindRoundtrip(t *testing.T, targetURL string, data []byte) (err error) {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5BindConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
conn, err := proxyConn(client, server)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer conn.Close()
|
|
|
|
conn, err = client.Connect(conn, "")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
cc, err := net.Dial("tcp", conn.LocalAddr().String())
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer cc.Close()
|
|
|
|
if err = conn.(*socks5BindConn).Handshake(); err != nil {
|
|
return
|
|
}
|
|
|
|
u, err := url.Parse(targetURL)
|
|
if err != nil {
|
|
return
|
|
}
|
|
hc, err := net.Dial("tcp", u.Host)
|
|
if err != nil {
|
|
return
|
|
}
|
|
go transport(hc, conn)
|
|
|
|
return httpRoundtrip(cc, targetURL, data)
|
|
}
|
|
|
|
func TestSOCKS5Bind(t *testing.T) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
if err := socks5BindRoundtrip(t, httpSrv.URL, sendData); err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
func socks5MuxBindRoundtrip(t *testing.T, targetURL string, data []byte) (err error) {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
l, err := net.Listen("tcp", "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
bindAddr := l.Addr().String()
|
|
l.Close()
|
|
|
|
client := &Client{
|
|
Connector: Socks5MuxBindConnector(),
|
|
Transporter: SOCKS5MuxBindTransporter(bindAddr),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return muxBindRoundtrip(client, server, bindAddr, targetURL, data)
|
|
}
|
|
|
|
func muxBindRoundtrip(client *Client, server *Server, bindAddr, targetURL string, data []byte) (err error) {
|
|
cn, err := client.Dial(server.Addr().String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
conn, err := client.Handshake(cn,
|
|
AddrHandshakeOption(server.Addr().String()),
|
|
UserHandshakeOption(url.UserPassword("admin", "123456")),
|
|
)
|
|
if err != nil {
|
|
cn.Close()
|
|
return err
|
|
}
|
|
defer conn.Close()
|
|
|
|
cc, err := net.Dial("tcp", bindAddr)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer cc.Close()
|
|
|
|
conn, err = client.Connect(conn, "")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
u, err := url.Parse(targetURL)
|
|
if err != nil {
|
|
return
|
|
}
|
|
hc, err := net.Dial("tcp", u.Host)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer hc.Close()
|
|
|
|
go transport(hc, conn)
|
|
|
|
return httpRoundtrip(cc, targetURL, data)
|
|
}
|
|
|
|
func TestSOCKS5MuxBind(t *testing.T) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
if err := socks5MuxBindRoundtrip(t, httpSrv.URL, sendData); err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5MuxBind(b *testing.B) {
|
|
httpSrv := httptest.NewServer(httpTestHandler)
|
|
defer httpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
l, err := net.Listen("tcp", "")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
bindAddr := l.Addr().String()
|
|
l.Close()
|
|
|
|
client := &Client{
|
|
Connector: Socks5MuxBindConnector(),
|
|
Transporter: SOCKS5MuxBindTransporter(bindAddr),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := muxBindRoundtrip(client, server, bindAddr, httpSrv.URL, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func socks5UDPRoundtrip(t *testing.T, host string, data []byte) (err error) {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return udpRoundtrip(t, client, server, host, data)
|
|
}
|
|
|
|
func TestSOCKS5UDP(t *testing.T) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
if err := socks5UDPRoundtrip(t, udpSrv.Addr(), sendData); err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
// TODO: fix a probability of timeout.
|
|
func BenchmarkSOCKS5UDP(b *testing.B) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := udpRoundtrip(b, client, server, udpSrv.Addr(), sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5UDPSingleConn(b *testing.B) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
conn, err := proxyConn(client, server)
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
defer conn.Close()
|
|
|
|
conn, err = client.Connect(conn, udpSrv.Addr())
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
roundtrip := func(conn net.Conn, data []byte) error {
|
|
conn.SetDeadline(time.Now().Add(1 * time.Second))
|
|
defer conn.SetDeadline(time.Time{})
|
|
|
|
if _, err = conn.Write(data); err != nil {
|
|
return err
|
|
}
|
|
|
|
recv := make([]byte, len(data))
|
|
if _, err = conn.Read(recv); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !bytes.Equal(data, recv) {
|
|
return fmt.Errorf("data not equal")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := roundtrip(conn, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func socks5UDPTunRoundtrip(t *testing.T, host string, data []byte) (err error) {
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPTunConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
return udpRoundtrip(t, client, server, host, data)
|
|
}
|
|
|
|
func TestSOCKS5UDPTun(t *testing.T) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
if err := socks5UDPTunRoundtrip(t, udpSrv.Addr(), sendData); err != nil {
|
|
t.Errorf("got error: %v", err)
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5UDPTun(b *testing.B) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPTunConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := udpRoundtrip(b, client, server, udpSrv.Addr(), sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSOCKS5UDPTunSingleConn(b *testing.B) {
|
|
udpSrv := newUDPTestServer(udpTestHandler)
|
|
udpSrv.Start()
|
|
defer udpSrv.Close()
|
|
|
|
sendData := make([]byte, 128)
|
|
rand.Read(sendData)
|
|
|
|
ln, err := TCPListener("")
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
client := &Client{
|
|
Connector: SOCKS5UDPTunConnector(url.UserPassword("admin", "123456")),
|
|
Transporter: TCPTransporter(),
|
|
}
|
|
|
|
server := &Server{
|
|
Handler: SOCKS5Handler(UsersHandlerOption(url.UserPassword("admin", "123456"))),
|
|
Listener: ln,
|
|
}
|
|
go server.Run()
|
|
defer server.Close()
|
|
|
|
conn, err := proxyConn(client, server)
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
defer conn.Close()
|
|
|
|
conn, err = client.Connect(conn, udpSrv.Addr())
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
|
|
roundtrip := func(conn net.Conn, data []byte) error {
|
|
conn.SetDeadline(time.Now().Add(1 * time.Second))
|
|
defer conn.SetDeadline(time.Time{})
|
|
|
|
if _, err = conn.Write(data); err != nil {
|
|
return err
|
|
}
|
|
|
|
recv := make([]byte, len(data))
|
|
if _, err = conn.Read(recv); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !bytes.Equal(data, recv) {
|
|
return fmt.Errorf("data not equal")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
if err := roundtrip(conn, sendData); err != nil {
|
|
b.Error(err)
|
|
}
|
|
}
|
|
}
|