add more tests

This commit is contained in:
ginuerzh 2018-12-09 12:32:23 +08:00
parent 52a8626d4a
commit e41c11d943
14 changed files with 3374 additions and 135 deletions

6
go.mod
View File

@ -12,6 +12,8 @@ require (
github.com/ginuerzh/tls-dissector v0.0.1
github.com/go-log/log v0.1.0
github.com/gobwas/glob v0.2.3
github.com/golang/mock v1.2.0 // indirect
github.com/gorilla/websocket v1.4.0 // indirect
github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/klauspost/compress v1.4.1
github.com/klauspost/cpuid v1.2.0 // indirect
@ -20,6 +22,8 @@ require (
github.com/lucas-clemente/quic-go v0.10.0
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced // indirect
github.com/miekg/dns v1.1.1
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/pkg/errors v0.8.0 // indirect
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735
github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba
@ -28,8 +32,8 @@ require (
github.com/tjfoc/gmsm v1.0.1 // indirect
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f // indirect
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e // indirect
golang.org/x/text v0.3.0 // indirect
gopkg.in/gorilla/websocket.v1 v1.4.0
gopkg.in/xtaci/kcp-go.v4 v4.3.2
gopkg.in/xtaci/smux.v1 v1.0.7

28
go.sum
View File

@ -14,6 +14,8 @@ github.com/dchest/siphash v1.2.0 h1:YWOShuhvg0GqbQpMa60QlCGtEyf7O7HC1Jf0VjdQ60M=
github.com/dchest/siphash v1.2.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ginuerzh/gosocks4 v0.0.1 h1:ojDKUyz+uaEeRm2usY1cyQiXTqJqrKxfeE6SVBXq4m0=
github.com/ginuerzh/gosocks4 v0.0.1/go.mod h1:8SdwBMKjfJ9+BfP2vDJM1jcrgWUbWV6qxBPHHVrwptY=
github.com/ginuerzh/gosocks5 v0.2.0 h1:K0Ua23U9LU3BZrf3XpGDcs0mP8DiEpa6PJE4TA/MU3s=
@ -24,8 +26,16 @@ github.com/go-log/log v0.1.0 h1:wudGTNsiGzrD5ZjgIkVZ517ugi2XRe9Q/xRCzwEO4/U=
github.com/go-log/log v0.1.0/go.mod h1:4mBwpdRMFLiuXZDCwU2lKQFsoSCo72j3HqBK9d81N2M=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
@ -40,6 +50,11 @@ github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cce
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
github.com/miekg/dns v1.1.1 h1:DVkblRdiScEnEr0LR9nTnEQqHYycjkXW9bOjd+2EL2o=
github.com/miekg/dns v1.1.1/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
@ -55,16 +70,29 @@ github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e h1:njOxP/wVblhCLIUhjHXf6X+dzTt5OQ3vMQo9mkOIKIo=
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gorilla/websocket.v1 v1.4.0 h1:lREme3ezAGPCpxSHwjGkHhAJX+ed2B6vzAJ+kaqBEIM=
gopkg.in/gorilla/websocket.v1 v1.4.0/go.mod h1:Ons1i8d00TjvJPdla7bJyeXFsdOacUyrTYbg9IetsIE=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/xtaci/kcp-go.v4 v4.3.2 h1:S9IF+L55Ugzl/hVA6wvuL3SuAtTUzH2cBBC88MXQxnE=
gopkg.in/xtaci/kcp-go.v4 v4.3.2/go.mod h1:fFYTlSOHNOHDNTKfoqarZMQsu7g7oXKwJ9wq0i9lODc=
gopkg.in/xtaci/smux.v1 v1.0.7 h1:qootIZs4ZPSx5blhvgaFpx2epdFSWkyw99xT+q0mRXI=
gopkg.in/xtaci/smux.v1 v1.0.7/go.mod h1:NbrPjLp8lNAYN8KqTplnFr2JjIBbr7CdHBkHtHsXtWA=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

766
http2_test.go Normal file
View File

@ -0,0 +1,766 @@
package gost
import (
"crypto/rand"
"crypto/tls"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func http2ProxyRoundtrip(targetURL string, data []byte, clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := HTTP2Listener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTP2Connector(clientInfo),
Transporter: HTTP2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTP2Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTP2Proxy(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := http2ProxyRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTP2Proxy(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := HTTP2Listener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTP2Connector(url.UserPassword("admin", "123456")),
Transporter: HTTP2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTP2Handler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTP2ProxyParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := HTTP2Listener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTP2Connector(url.UserPassword("admin", "123456")),
Transporter: HTTP2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTP2Handler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 httpOverH2Roundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := H2Listener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverH2(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverH2Roundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverH2(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := H2Listener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverH2Parallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := H2Listener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverH2Roundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := H2Listener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverH2(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverH2Roundtrip(httpSrv.URL, sendData,
nil,
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 socks4OverH2Roundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := H2Listener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverH2(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverH2Roundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverH2Roundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := H2Listener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverH2(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverH2Roundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverH2Roundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := H2Listener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: H2Transporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverH2(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
var ssProxyTests = []struct {
clientCipher *url.Userinfo
serverCipher *url.Userinfo
pass bool
}{
{nil, nil, false},
{&url.Userinfo{}, &url.Userinfo{}, false},
{url.User("abc"), url.User("abc"), false},
{url.UserPassword("abc", "def"), url.UserPassword("abc", "def"), false},
{url.User("aes-128-cfb"), url.User("aes-128-cfb"), false},
{url.User("aes-128-cfb"), url.UserPassword("aes-128-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.User("aes-128-cfb"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "abc"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), true},
}
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverH2Roundtrip(httpSrv.URL, sendData,
nil,
tc.clientCipher,
tc.serverCipher,
)
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 httpOverH2CRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := H2CListener("")
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverH2C(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverH2CRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverH2C(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := H2CListener("")
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverH2CParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := H2CListener("")
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverH2CRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := H2CListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverH2C(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverH2CRoundtrip(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 socks4OverH2CRoundtrip(targetURL string, data []byte) error {
ln, err := H2CListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverH2C(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverH2CRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverH2CRoundtrip(targetURL string, data []byte) error {
ln, err := H2CListener("")
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverH2C(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverH2CRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverH2CRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := H2CListener("")
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: H2CTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverH2C(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
var ssProxyTests = []struct {
clientCipher *url.Userinfo
serverCipher *url.Userinfo
pass bool
}{
{nil, nil, false},
{&url.Userinfo{}, &url.Userinfo{}, false},
{url.User("abc"), url.User("abc"), false},
{url.UserPassword("abc", "def"), url.UserPassword("abc", "def"), false},
{url.User("aes-128-cfb"), url.User("aes-128-cfb"), false},
{url.User("aes-128-cfb"), url.UserPassword("aes-128-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.User("aes-128-cfb"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "abc"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), true},
}
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverH2CRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}

View File

@ -9,6 +9,7 @@ import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
"net/url"
@ -16,42 +17,43 @@ import (
"time"
)
func init() {
// SetLogger(&LogLogger{})
// Debug = true
cert, err := GenCertificate()
if err != nil {
panic(err)
}
DefaultTLSConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
}
}
var httpTestHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(w, r.Body)
})
func proxyRoundtrip(client *Client, server *Server, targetURL string, data []byte) (err error) {
// proxyConn obtains a connection to the proxy server.
func proxyConn(client *Client, server *Server) (net.Conn, error) {
conn, err := client.Dial(server.Addr().String())
if err != nil {
return
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(1 * time.Second))
conn, err = client.Handshake(conn)
if err != nil {
return
}
u, err := url.Parse(targetURL)
if err != nil {
return
}
conn, err = client.Connect(conn, u.Host)
if err != nil {
return
return nil, err
}
if u.Scheme == "https" {
conn = tls.Client(conn,
&tls.Config{
InsecureSkipVerify: true,
})
u.Scheme = "http"
cc, err := client.Handshake(conn, AddrHandshakeOption(server.Addr().String()))
if err != nil {
conn.Close()
return nil, err
}
return cc, nil
}
// httpRoundtrip does a HTTP request-response roundtrip, and checks the data received.
func httpRoundtrip(conn net.Conn, targetURL string, data []byte) (err error) {
req, err := http.NewRequest(
http.MethodGet,
u.String(),
targetURL,
bytes.NewReader(data),
)
if err != nil {
@ -78,10 +80,32 @@ func proxyRoundtrip(client *Client, server *Server, targetURL string, data []byt
if !bytes.Equal(data, recv) {
return fmt.Errorf("data not equal")
}
return
}
func proxyRoundtrip(client *Client, server *Server, targetURL string, data []byte) (err error) {
conn, err := proxyConn(client, server)
if err != nil {
return err
}
defer conn.Close()
u, err := url.Parse(targetURL)
if err != nil {
return
}
conn.SetDeadline(time.Now().Add(1 * time.Second))
defer conn.SetDeadline(time.Time{})
conn, err = client.Connect(conn, u.Host)
if err != nil {
return
}
return httpRoundtrip(conn, targetURL, data)
}
var httpProxyTests = []struct {
cliUser *url.Userinfo
srvUsers []*url.Userinfo

311
kcp_test.go Normal file
View File

@ -0,0 +1,311 @@
package gost
import (
"crypto/rand"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverKCPRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := KCPListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverKCP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverKCPRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverKCP(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := KCPListener("", nil)
if err != nil {
b.Error(err)
}
b.Log(ln.Addr())
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverKCPParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := KCPListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverKCPRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := KCPListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverKCP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverKCPRoundtrip(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 socks4OverKCPRoundtrip(targetURL string, data []byte) error {
ln, err := KCPListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverKCP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverKCPRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverKCPRoundtrip(targetURL string, data []byte) error {
ln, err := KCPListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverKCP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverKCPRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverKCPRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := KCPListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: KCPTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverKCP(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverKCPRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}

View File

@ -21,7 +21,7 @@ type quicSession struct {
}
func (session *quicSession) GetConn() (*quicConn, error) {
stream, err := session.session.OpenStream()
stream, err := session.session.OpenStreamSync()
if err != nil {
return nil, err
}
@ -130,6 +130,10 @@ func (tr *quicTransporter) initSession(addr string, conn net.Conn, config *QUICC
HandshakeTimeout: config.Timeout,
KeepAlive: config.KeepAlive,
IdleTimeout: config.IdleTimeout,
Versions: []quic.VersionNumber{
quic.VersionGQUIC43,
quic.VersionGQUIC39,
},
}
session, err := quic.Dial(udpConn, udpAddr, addr, config.TLSConfig, quicConfig)
if err != nil {

311
quic_test.go Normal file
View File

@ -0,0 +1,311 @@
package gost
import (
"crypto/rand"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverQUICRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := QUICListener("localhost:0", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverQUIC(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverQUICRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverQUIC(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := QUICListener("localhost:0", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: QUICTransporter(&QUICConfig{KeepAlive: true}),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverQUICParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := QUICListener("localhost:0", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverQUICRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := QUICListener("localhost:0", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverQUIC(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverQUICRoundtrip(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 socks4OverQUICRoundtrip(targetURL string, data []byte) error {
ln, err := QUICListener("localhost:0", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverQUIC(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverQUICRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverQUICRoundtrip(targetURL string, data []byte) error {
ln, err := QUICListener("localhost:0", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverQUIC(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverQUICRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverQUICRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := QUICListener("localhost:0", nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: QUICTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverQUIC(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverQUICRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}

View File

@ -90,15 +90,18 @@ func sniProxyRoundtrip(targetURL string, data []byte, host string) error {
}
func TestSNIProxy(t *testing.T) {
// SetLogger(&LogLogger{})
// Debug = true
httpSrv := httptest.NewTLSServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := sniProxyRoundtrip("https://github.com", sendData, "google.com")
err := sniProxyRoundtrip("https://github.com", sendData, "")
if err != nil {
t.Errorf("got error: %v", err)
}
err = sniProxyRoundtrip("https://github.com", sendData, "google.com")
if err != nil {
t.Errorf("got error: %v", err)
}

View File

@ -23,54 +23,54 @@ var ssProxyTests = []struct {
{url.UserPassword("aes-128-cfb", "123456"), url.User("aes-128-cfb"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "abc"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), true},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
{url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
// {url.UserPassword("aes-128-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
{url.User("aes-192-cfb"), url.User("aes-192-cfb"), false},
{url.User("aes-192-cfb"), url.UserPassword("aes-192-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.User("aes-192-cfb"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-cfb", "abc"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), true},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
{url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
// {url.UserPassword("aes-192-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
{url.User("aes-256-cfb"), url.User("aes-256-cfb"), false},
{url.User("aes-256-cfb"), url.UserPassword("aes-256-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.User("aes-256-cfb"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-cfb", "abc"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-cfb", "123456"), true},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
{url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-cfb", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-cfb", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-128-ctr", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-192-ctr", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("aes-256-ctr", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("des-cfb", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("bf-cfb", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("cast5-cfb", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("rc4-md5", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("chacha20-ietf", "123456"), false},
// {url.UserPassword("aes-256-cfb", "123456"), url.UserPassword("salsa20", "123456"), false},
{url.User("aes-128-ctr"), url.User("aes-128-ctr"), false},
{url.User("aes-128-ctr"), url.UserPassword("aes-128-ctr", "123456"), false},

7
ssh.go
View File

@ -252,6 +252,7 @@ func (tr *sshTunnelTransporter) Handshake(conn net.Conn, options ...HandshakeOpt
Timeout: opts.Timeout,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// TODO: support pubkey auth.
if opts.User != nil {
config.User = opts.User.Username()
password, _ := opts.User.Password()
@ -847,13 +848,13 @@ func (c *sshConn) RemoteAddr() net.Addr {
}
func (c *sshConn) SetDeadline(t time.Time) error {
return nil
return c.conn.SetDeadline(t)
}
func (c *sshConn) SetReadDeadline(t time.Time) error {
return nil
return c.conn.SetReadDeadline(t)
}
func (c *sshConn) SetWriteDeadline(t time.Time) error {
return nil
return c.conn.SetWriteDeadline(t)
}

313
ssh_test.go Normal file
View File

@ -0,0 +1,313 @@
package gost
import (
"crypto/rand"
"crypto/tls"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := SSHTunnelListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverSSHTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverSSHTunnelRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverSSHTunnel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := SSHTunnelListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverSSHTunnelParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := SSHTunnelListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := SSHTunnelListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverSSHTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverSSHTunnelRoundtrip(httpSrv.URL, sendData,
nil,
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 socks4OverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := SSHTunnelListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverSSHTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverSSHTunnelRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := SSHTunnelListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverSSHTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverSSHTunnelRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverSSHTunnelRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := SSHTunnelListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: SSHTunnelTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverSSHTunnel(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverSSHTunnelRoundtrip(httpSrv.URL, sendData,
nil,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}

View File

@ -36,14 +36,6 @@ func httpOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
}
func TestHTTPOverTLS(t *testing.T) {
cert, err := GenCertificate()
if err != nil {
t.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
@ -53,7 +45,7 @@ func TestHTTPOverTLS(t *testing.T) {
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig, tc.cliUser, tc.srvUsers)
err := httpOverTLSRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
@ -77,15 +69,7 @@ func BenchmarkHTTPOverTLS(b *testing.B) {
sendData := make([]byte, 128)
rand.Read(sendData)
cert, err := GenCertificate()
if err != nil {
b.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
ln, err := TLSListener("", tlsConfig)
ln, err := TLSListener("", nil)
if err != nil {
b.Error(err)
}
@ -118,15 +102,7 @@ func BenchmarkHTTPOverTLSParallel(b *testing.B) {
sendData := make([]byte, 128)
rand.Read(sendData)
cert, err := GenCertificate()
if err != nil {
b.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
ln, err := TLSListener("", tlsConfig)
ln, err := TLSListener("", nil)
if err != nil {
b.Error(err)
}
@ -181,15 +157,6 @@ func socks5OverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config
}
func TestSOCKS5OverTLS(t *testing.T) {
cert, err := GenCertificate()
if err != nil {
t.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
DefaultTLSConfig = tlsConfig
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
@ -200,7 +167,7 @@ func TestSOCKS5OverTLS(t *testing.T) {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverTLSRoundtrip(httpSrv.URL, sendData,
tlsConfig,
nil,
tc.cliUser,
tc.srvUsers,
)
@ -241,21 +208,13 @@ func socks4OverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config
}
func TestSOCKS4OverTLS(t *testing.T) {
cert, err := GenCertificate()
if err != nil {
t.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err = socks4OverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig)
err := socks4OverTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
@ -285,21 +244,13 @@ func socks4aOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Confi
}
func TestSOCKS4AOverTLS(t *testing.T) {
cert, err := GenCertificate()
if err != nil {
t.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err = socks4aOverTLSRoundtrip(httpSrv.URL, sendData, tlsConfig)
err := socks4aOverTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
@ -333,15 +284,6 @@ func ssOverTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
}
func TestSSOverTLS(t *testing.T) {
cert, err := GenCertificate()
if err != nil {
t.Error(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
DefaultTLSConfig = tlsConfig
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
@ -352,7 +294,310 @@ func TestSSOverTLS(t *testing.T) {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverTLSRoundtrip(httpSrv.URL, sendData,
tlsConfig,
nil,
tc.clientCipher,
tc.serverCipher,
)
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 httpOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverMTLSRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverMTLS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MTLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverMTLSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MTLSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverMTLSRoundtrip(httpSrv.URL, sendData,
nil,
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 socks4OverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverMTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverMTLSRoundtrip(httpSrv.URL, sendData, nil)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := MTLSListener("", tlsConfig)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: MTLSTransporter(),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverMTLS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverMTLSRoundtrip(httpSrv.URL, sendData,
nil,
tc.clientCipher,
tc.serverCipher,
)

614
ws_test.go Normal file
View File

@ -0,0 +1,614 @@
package gost
import (
"crypto/rand"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverWSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := WSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverWSRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverWS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := WSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverWSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := WSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverWSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := WSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverWSRoundtrip(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 socks4OverWSRoundtrip(targetURL string, data []byte) error {
ln, err := WSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverWSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverWSRoundtrip(targetURL string, data []byte) error {
ln, err := WSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverWSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverWSRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := WSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: WSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverWSRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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 httpOverMWSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MWSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverMWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverMWSRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverMWS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MWSListener("", nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverMWSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MWSListener("", nil)
if err != nil {
b.Error(err)
}
b.Log(ln.Addr())
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverMWSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MWSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverMWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverMWSRoundtrip(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 socks4OverMWSRoundtrip(targetURL string, data []byte) error {
ln, err := MWSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverMWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverMWSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverMWSRoundtrip(targetURL string, data []byte) error {
ln, err := MWSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverMWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverMWSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverMWSRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := MWSListener("", nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: MWSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverMWS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverMWSRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}

615
wss_test.go Normal file
View File

@ -0,0 +1,615 @@
package gost
import (
"crypto/rand"
"crypto/tls"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func httpOverWSSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := WSSListener("", tlsConfig, nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverWSSRoundtrip(httpSrv.URL, sendData, nil, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverWSS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := WSSListener("", nil, nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverWSSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := WSSListener("", nil, nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverWSSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := WSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverWSSRoundtrip(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 socks4OverWSSRoundtrip(targetURL string, data []byte) error {
ln, err := WSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverWSSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverWSSRoundtrip(targetURL string, data []byte) error {
ln, err := WSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverWSSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverWSSRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := WSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: WSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverWSSRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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 httpOverMWSSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MWSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: HTTPConnector(clientInfo),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestHTTPOverMWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range httpProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := httpOverMWSSRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
if err == nil {
if tc.errStr != "" {
t.Errorf("#%d should failed with error %s", i, tc.errStr)
}
} else {
if tc.errStr == "" {
t.Errorf("#%d got error %v", i, err)
}
if err.Error() != tc.errStr {
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
}
}
})
}
}
func BenchmarkHTTPOverMWSS(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MWSSListener("", nil, nil)
if err != nil {
b.Error(err)
}
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 BenchmarkHTTPOverMWSSParallel(b *testing.B) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
ln, err := MWSSListener("", nil, nil)
if err != nil {
b.Error(err)
}
b.Log(ln.Addr())
client := &Client{
Connector: HTTPConnector(url.UserPassword("admin", "123456")),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: HTTPHandler(
UsersHandlerOption(url.UserPassword("admin", "123456")),
),
}
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 socks5OverMWSSRoundtrip(targetURL string, data []byte,
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
ln, err := MWSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS5Connector(clientInfo),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS5Handler(
UsersHandlerOption(serverInfo...),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS5OverMWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range socks5ProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := socks5OverMWSSRoundtrip(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 socks4OverMWSSRoundtrip(targetURL string, data []byte) error {
ln, err := MWSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4Connector(),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4OverMWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4OverMWSSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func socks4aOverMWSSRoundtrip(targetURL string, data []byte) error {
ln, err := MWSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: SOCKS4AConnector(),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: SOCKS4Handler(),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSOCKS4AOverMWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
err := socks4aOverMWSSRoundtrip(httpSrv.URL, sendData)
// t.Logf("#%d %v", i, err)
if err != nil {
t.Errorf("got error: %v", err)
}
}
func ssOverMWSSRoundtrip(targetURL string, data []byte,
clientInfo, serverInfo *url.Userinfo) error {
ln, err := MWSSListener("", nil, nil)
if err != nil {
return err
}
client := &Client{
Connector: ShadowConnector(clientInfo),
Transporter: MWSSTransporter(nil),
}
server := &Server{
Listener: ln,
Handler: ShadowHandler(
UsersHandlerOption(serverInfo),
),
}
go server.Run()
defer server.Close()
return proxyRoundtrip(client, server, targetURL, data)
}
func TestSSOverMWSS(t *testing.T) {
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
sendData := make([]byte, 128)
rand.Read(sendData)
for i, tc := range ssProxyTests {
tc := tc
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
err := ssOverMWSSRoundtrip(httpSrv.URL, sendData,
tc.clientCipher,
tc.serverCipher,
)
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)
}
}
})
}
}