add more SNI tests
This commit is contained in:
parent
75f71daa99
commit
5e94eb642e
@ -7,3 +7,6 @@ install: true
|
|||||||
script:
|
script:
|
||||||
- env GO111MODULE=on go test -race -v
|
- env GO111MODULE=on go test -race -v
|
||||||
- cd cmd/gost && env GO111MODULE=on go build
|
- cd cmd/gost && env GO111MODULE=on go build
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
|
@ -34,6 +34,7 @@ type HandlerOptions struct {
|
|||||||
Hosts *Hosts
|
Hosts *Hosts
|
||||||
ProbeResist string
|
ProbeResist string
|
||||||
Node Node
|
Node Node
|
||||||
|
Host string
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerOption allows a common way to set handler options.
|
// HandlerOption allows a common way to set handler options.
|
||||||
@ -137,6 +138,13 @@ func NodeHandlerOption(node Node) HandlerOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HostHandlerOption sets the target host for SNI proxy.
|
||||||
|
func HostHandlerOption(host string) HandlerOption {
|
||||||
|
return func(opts *HandlerOptions) {
|
||||||
|
opts.Host = host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type autoHandler struct {
|
type autoHandler struct {
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
}
|
}
|
||||||
|
131
http2_test.go
131
http2_test.go
@ -3,6 +3,7 @@ package gost
|
|||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -418,6 +419,71 @@ func TestSSOverH2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverH2Roundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := H2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: H2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverH2(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverH2Roundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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,
|
func httpOverH2CRoundtrip(targetURL string, data []byte,
|
||||||
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
||||||
|
|
||||||
@ -709,3 +775,68 @@ func TestSSOverH2C(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverH2CRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := H2CListener("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: H2CTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverH2C(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverH2CRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
// SetLogger(&LogLogger{})
|
// SetLogger(&LogLogger{})
|
||||||
// Debug = true
|
// Debug = true
|
||||||
|
|
||||||
cert, err := GenCertificate()
|
cert, err := GenCertificate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
66
kcp_test.go
66
kcp_test.go
@ -2,6 +2,7 @@ package gost
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -299,3 +300,68 @@ func TestSSOverKCP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverKCPRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := KCPListener("localhost:0", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: KCPTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverKCP(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverKCPRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
quic.go
2
quic.go
@ -137,7 +137,7 @@ func (tr *quicTransporter) initSession(addr string, conn net.Conn, config *QUICC
|
|||||||
}
|
}
|
||||||
session, err := quic.Dial(udpConn, udpAddr, addr, config.TLSConfig, quicConfig)
|
session, err := quic.Dial(udpConn, udpAddr, addr, config.TLSConfig, quicConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Log("quic dial:", err)
|
log.Logf("quic dial %s: %v", addr, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &quicSession{conn: conn, session: session}, nil
|
return &quicSession{conn: conn, session: session}, nil
|
||||||
|
66
quic_test.go
66
quic_test.go
@ -2,6 +2,7 @@ package gost
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -299,3 +300,68 @@ func TestSSOverQUIC(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverQUICRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := QUICListener("localhost:0", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: QUICTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverQUIC(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverQUICRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
sni.go
6
sni.go
@ -91,7 +91,11 @@ func (h *sniHandler) Handle(conn net.Conn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
host = net.JoinHostPort(host, "443")
|
_, sport, _ := net.SplitHostPort(h.options.Host)
|
||||||
|
if sport == "" {
|
||||||
|
sport = "443"
|
||||||
|
}
|
||||||
|
host = net.JoinHostPort(host, sport)
|
||||||
|
|
||||||
log.Logf("[sni] %s -> %s -> %s",
|
log.Logf("[sni] %s -> %s -> %s",
|
||||||
conn.RemoteAddr(), h.options.Node.String(), host)
|
conn.RemoteAddr(), h.options.Node.String(), host)
|
||||||
|
68
sni_test.go
68
sni_test.go
@ -6,6 +6,8 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -18,18 +20,21 @@ func sniRoundtrip(client *Client, server *Server, targetURL string, data []byte)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
conn.SetDeadline(time.Now().Add(3 * time.Second))
|
conn, err = client.Handshake(conn, AddrHandshakeOption(server.Addr().String()))
|
||||||
|
|
||||||
conn, err = client.Handshake(conn)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
u, err := url.Parse(targetURL)
|
u, err := url.Parse(targetURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn.SetDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
defer conn.SetDeadline(time.Time{})
|
||||||
|
|
||||||
conn, err = client.Connect(conn, u.Host)
|
conn, err = client.Connect(conn, u.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -38,8 +43,8 @@ func sniRoundtrip(client *Client, server *Server, targetURL string, data []byte)
|
|||||||
if u.Scheme == "https" {
|
if u.Scheme == "https" {
|
||||||
conn = tls.Client(conn,
|
conn = tls.Client(conn,
|
||||||
&tls.Config{
|
&tls.Config{
|
||||||
InsecureSkipVerify: false,
|
InsecureSkipVerify: true,
|
||||||
ServerName: u.Hostname(),
|
// ServerName: u.Hostname(),
|
||||||
})
|
})
|
||||||
u.Scheme = "http"
|
u.Scheme = "http"
|
||||||
}
|
}
|
||||||
@ -64,6 +69,15 @@ func sniRoundtrip(client *Client, server *Server, targetURL string, data []byte)
|
|||||||
return errors.New(resp.Status)
|
return errors.New(resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recv, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(data, recv) {
|
||||||
|
return fmt.Errorf("data not equal")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +87,11 @@ func sniProxyRoundtrip(targetURL string, data []byte, host string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
client := &Client{
|
client := &Client{
|
||||||
Connector: SNIConnector(host),
|
Connector: SNIConnector(host),
|
||||||
Transporter: TCPTransporter(),
|
Transporter: TCPTransporter(),
|
||||||
@ -80,7 +99,7 @@ func sniProxyRoundtrip(targetURL string, data []byte, host string) error {
|
|||||||
|
|
||||||
server := &Server{
|
server := &Server{
|
||||||
Listener: ln,
|
Listener: ln,
|
||||||
Handler: SNIHandler(),
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
}
|
}
|
||||||
|
|
||||||
go server.Run()
|
go server.Run()
|
||||||
@ -90,19 +109,40 @@ func sniProxyRoundtrip(targetURL string, data []byte, host string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSNIProxy(t *testing.T) {
|
func TestSNIProxy(t *testing.T) {
|
||||||
httpSrv := httptest.NewTLSServer(httpTestHandler)
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
defer httpSrv.Close()
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
sendData := make([]byte, 128)
|
sendData := make([]byte, 128)
|
||||||
rand.Read(sendData)
|
rand.Read(sendData)
|
||||||
|
|
||||||
err := sniProxyRoundtrip("https://github.com", sendData, "")
|
var sniProxyTests = []struct {
|
||||||
if err != nil {
|
targetURL string
|
||||||
t.Errorf("got error: %v", err)
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sniProxyRoundtrip("https://github.com", sendData, "google.com")
|
for i, tc := range sniProxyTests {
|
||||||
if err != nil {
|
tc := tc
|
||||||
t.Errorf("got error: %v", err)
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniProxyRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
66
ssh_test.go
66
ssh_test.go
@ -3,6 +3,7 @@ package gost
|
|||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -301,3 +302,68 @@ func TestSSOverSSHTunnel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverSSHTunnelRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := SSHTunnelListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: SSHTunnelTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverSSHTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverSSHTunnelRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
131
tls_test.go
131
tls_test.go
@ -3,6 +3,7 @@ package gost
|
|||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -302,6 +303,71 @@ func TestSSOverTLS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverTLSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := TLSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: TLSTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverTLS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverTLSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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,
|
func httpOverMTLSRoundtrip(targetURL string, data []byte, tlsConfig *tls.Config,
|
||||||
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
||||||
|
|
||||||
@ -595,3 +661,68 @@ func TestSSOverMTLS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverMTLSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := MTLSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: MTLSTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverMTLS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverMTLSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
131
ws_test.go
131
ws_test.go
@ -2,6 +2,7 @@ package gost
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -300,6 +301,71 @@ func TestSSOverWS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverWSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := WSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: WSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverWS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverWSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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,
|
func httpOverMWSRoundtrip(targetURL string, data []byte,
|
||||||
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
||||||
|
|
||||||
@ -593,3 +659,68 @@ func TestSSOverMWS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverMWSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := MWSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: MWSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverMWS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverMWSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
131
wss_test.go
131
wss_test.go
@ -3,6 +3,7 @@ package gost
|
|||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -301,6 +302,71 @@ func TestSSOverWSS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverWSSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := WSSListener("", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: WSSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverWSS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverWSSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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,
|
func httpOverMWSSRoundtrip(targetURL string, data []byte,
|
||||||
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
clientInfo *url.Userinfo, serverInfo []*url.Userinfo) error {
|
||||||
|
|
||||||
@ -594,3 +660,68 @@ func TestSSOverMWSS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sniOverMWSSRoundtrip(targetURL string, data []byte, host string) error {
|
||||||
|
ln, err := MWSSListener("", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: SNIConnector(host),
|
||||||
|
Transporter: MWSSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: SNIHandler(HostHandlerOption(u.Host)),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return sniRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSNIOverMWSS(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
httpsSrv := httptest.NewTLSServer(httpTestHandler)
|
||||||
|
defer httpsSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
var sniProxyTests = []struct {
|
||||||
|
targetURL string
|
||||||
|
host string
|
||||||
|
pass bool
|
||||||
|
}{
|
||||||
|
{httpSrv.URL, "", true},
|
||||||
|
{httpSrv.URL, "example.com", true},
|
||||||
|
{httpsSrv.URL, "", true},
|
||||||
|
{httpsSrv.URL, "example.com", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range sniProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
|
err := sniOverMWSSRoundtrip(tc.targetURL, sendData, tc.host)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user