add tests for forward tunnel
This commit is contained in:
parent
5e5bb3035d
commit
49f2fcc9f3
30
client.go
30
client.go
@ -62,10 +62,10 @@ type Transporter interface {
|
|||||||
Multiplex() bool
|
Multiplex() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type tcpTransporter struct {
|
// tcpTransporter is a raw TCP transporter.
|
||||||
}
|
type tcpTransporter struct{}
|
||||||
|
|
||||||
// TCPTransporter creates a transporter for TCP proxy client.
|
// TCPTransporter creates a raw TCP client.
|
||||||
func TCPTransporter() Transporter {
|
func TCPTransporter() Transporter {
|
||||||
return &tcpTransporter{}
|
return &tcpTransporter{}
|
||||||
}
|
}
|
||||||
@ -90,6 +90,30 @@ func (tr *tcpTransporter) Multiplex() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// udpTransporter is a raw UDP transporter.
|
||||||
|
type udpTransporter struct{}
|
||||||
|
|
||||||
|
// UDPTransporter creates a raw UDP client.
|
||||||
|
func UDPTransporter() Transporter {
|
||||||
|
return &udpTransporter{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *udpTransporter) Dial(addr string, options ...DialOption) (net.Conn, error) {
|
||||||
|
opts := &DialOptions{}
|
||||||
|
for _, option := range options {
|
||||||
|
option(opts)
|
||||||
|
}
|
||||||
|
return net.DialTimeout("udp", addr, opts.Timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *udpTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *udpTransporter) Multiplex() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// DialOptions describes the options for Transporter.Dial.
|
// DialOptions describes the options for Transporter.Dial.
|
||||||
type DialOptions struct {
|
type DialOptions struct {
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
|
121
common_test.go
Normal file
121
common_test.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package gost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
|
||||||
|
udpTestHandler = udpHandlerFunc(func(w io.Writer, r *udpRequest) {
|
||||||
|
io.Copy(w, r.Body)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
type udpRequest struct {
|
||||||
|
Body io.Reader
|
||||||
|
RemoteAddr string
|
||||||
|
}
|
||||||
|
|
||||||
|
type udpResponseWriter struct {
|
||||||
|
conn net.PacketConn
|
||||||
|
addr net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *udpResponseWriter) Write(p []byte) (int, error) {
|
||||||
|
return w.conn.WriteTo(p, w.addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type udpHandlerFunc func(w io.Writer, r *udpRequest)
|
||||||
|
|
||||||
|
// udpTestServer is a UDP server for test.
|
||||||
|
type udpTestServer struct {
|
||||||
|
ln net.PacketConn
|
||||||
|
handler udpHandlerFunc
|
||||||
|
wg sync.WaitGroup
|
||||||
|
mu sync.Mutex // guards closed and conns
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUDPTestServer(handler udpHandlerFunc) *udpTestServer {
|
||||||
|
laddr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:0")
|
||||||
|
ln, err := net.ListenUDP("udp", laddr)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("udptest: failed to listen on a port: %v", err))
|
||||||
|
}
|
||||||
|
return &udpTestServer{
|
||||||
|
ln: ln,
|
||||||
|
handler: handler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *udpTestServer) Start() {
|
||||||
|
go s.serve()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *udpTestServer) serve() {
|
||||||
|
for {
|
||||||
|
data := make([]byte, 1024)
|
||||||
|
n, raddr, err := s.ln.ReadFrom(data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.handler != nil {
|
||||||
|
s.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer s.wg.Done()
|
||||||
|
w := &udpResponseWriter{
|
||||||
|
conn: s.ln,
|
||||||
|
addr: raddr,
|
||||||
|
}
|
||||||
|
r := &udpRequest{
|
||||||
|
Body: bytes.NewReader(data[:n]),
|
||||||
|
RemoteAddr: raddr.String(),
|
||||||
|
}
|
||||||
|
s.handler(w, r)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *udpTestServer) Addr() string {
|
||||||
|
return s.ln.LocalAddr().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *udpTestServer) Close() error {
|
||||||
|
s.mu.Lock()
|
||||||
|
|
||||||
|
if s.closed {
|
||||||
|
s.mu.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := s.ln.Close()
|
||||||
|
s.closed = true
|
||||||
|
s.mu.Unlock()
|
||||||
|
|
||||||
|
s.wg.Wait()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
159
forward.go
159
forward.go
@ -272,9 +272,6 @@ func (h *tcpRemoteForwardHandler) Handle(conn net.Conn) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
retries := 1
|
retries := 1
|
||||||
if h.options.Chain != nil && h.options.Chain.Retries > 0 {
|
|
||||||
retries = h.options.Chain.Retries
|
|
||||||
}
|
|
||||||
if h.options.Retries > 0 {
|
if h.options.Retries > 0 {
|
||||||
retries = h.options.Retries
|
retries = h.options.Retries
|
||||||
}
|
}
|
||||||
@ -422,7 +419,7 @@ func (l *udpDirectForwardListener) listenLoop() {
|
|||||||
n, raddr, err := l.ln.ReadFrom(b)
|
n, raddr, err := l.ln.ReadFrom(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Logf("[udp] peer -> %s : %s", l.Addr(), err)
|
log.Logf("[udp] peer -> %s : %s", l.Addr(), err)
|
||||||
l.ln.Close()
|
l.Close()
|
||||||
l.errChan <- err
|
l.errChan <- err
|
||||||
close(l.errChan)
|
close(l.errChan)
|
||||||
return
|
return
|
||||||
@ -593,10 +590,14 @@ func (c *udpServerConn) ttlWait() {
|
|||||||
ttl = defaultTTL
|
ttl = defaultTTL
|
||||||
}
|
}
|
||||||
timer := time.NewTimer(ttl)
|
timer := time.NewTimer(ttl)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-c.nopChan:
|
case <-c.nopChan:
|
||||||
|
if !timer.Stop() {
|
||||||
|
<-timer.C
|
||||||
|
}
|
||||||
timer.Reset(ttl)
|
timer.Reset(ttl)
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
close(c.brokenChan)
|
close(c.brokenChan)
|
||||||
@ -630,10 +631,13 @@ func (c *udpServerConn) SetWriteDeadline(t time.Time) error {
|
|||||||
type tcpRemoteForwardListener struct {
|
type tcpRemoteForwardListener struct {
|
||||||
addr net.Addr
|
addr net.Addr
|
||||||
chain *Chain
|
chain *Chain
|
||||||
|
connChan chan net.Conn
|
||||||
ln net.Listener
|
ln net.Listener
|
||||||
session *muxSession
|
session *muxSession
|
||||||
mutex sync.Mutex
|
sessionMux sync.Mutex
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
|
closeMux sync.Mutex
|
||||||
|
errChan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// TCPRemoteForwardListener creates a Listener for TCP remote port forwarding server.
|
// TCPRemoteForwardListener creates a Listener for TCP remote port forwarding server.
|
||||||
@ -643,23 +647,56 @@ func TCPRemoteForwardListener(addr string, chain *Chain) (Listener, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tcpRemoteForwardListener{
|
ln := &tcpRemoteForwardListener{
|
||||||
addr: laddr,
|
addr: laddr,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
|
connChan: make(chan net.Conn, 1024),
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}, nil
|
errChan: make(chan error),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ln.isChainValid() {
|
||||||
|
ln.ln, err = net.Listen("tcp", ln.addr.String())
|
||||||
|
return ln, err
|
||||||
|
}
|
||||||
|
|
||||||
|
go ln.listenLoop()
|
||||||
|
|
||||||
|
if err = <-ln.errChan; err != nil {
|
||||||
|
ln.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ln, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *tcpRemoteForwardListener) Accept() (net.Conn, error) {
|
func (l *tcpRemoteForwardListener) isChainValid() bool {
|
||||||
|
lastNode := l.chain.LastNode()
|
||||||
|
if (lastNode.Protocol == "forward" && lastNode.Transport == "ssh") ||
|
||||||
|
lastNode.Protocol == "socks5" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tcpRemoteForwardListener) listenLoop() {
|
||||||
|
var tempDelay time.Duration
|
||||||
|
var once sync.Once
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := l.accept()
|
||||||
|
|
||||||
|
once.Do(func() {
|
||||||
|
l.errChan <- err
|
||||||
|
close(l.errChan)
|
||||||
|
})
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-l.closed:
|
case <-l.closed:
|
||||||
return nil, errors.New("closed")
|
conn.Close()
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempDelay time.Duration
|
|
||||||
for {
|
|
||||||
conn, err := l.accept()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tempDelay == 0 {
|
if tempDelay == 0 {
|
||||||
tempDelay = 1000 * time.Millisecond
|
tempDelay = 1000 * time.Millisecond
|
||||||
@ -673,15 +710,37 @@ func (l *tcpRemoteForwardListener) Accept() (net.Conn, error) {
|
|||||||
time.Sleep(tempDelay)
|
time.Sleep(tempDelay)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return conn, nil
|
|
||||||
|
select {
|
||||||
|
case l.connChan <- conn:
|
||||||
|
default:
|
||||||
|
conn.Close()
|
||||||
|
log.Logf("[rtcp] %s - %s: connection queue is full", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tcpRemoteForwardListener) Accept() (conn net.Conn, err error) {
|
||||||
|
if l.ln != nil {
|
||||||
|
return l.ln.Accept()
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case conn = <-l.connChan:
|
||||||
|
case <-l.closed:
|
||||||
|
err = errors.New("closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *tcpRemoteForwardListener) accept() (conn net.Conn, err error) {
|
func (l *tcpRemoteForwardListener) accept() (conn net.Conn, err error) {
|
||||||
lastNode := l.chain.LastNode()
|
lastNode := l.chain.LastNode()
|
||||||
if lastNode.Protocol == "forward" && lastNode.Transport == "ssh" {
|
if lastNode.Protocol == "forward" && lastNode.Transport == "ssh" {
|
||||||
conn, err = l.chain.Dial(l.addr.String())
|
return l.chain.Dial(l.addr.String())
|
||||||
} else if lastNode.Protocol == "socks5" {
|
}
|
||||||
|
|
||||||
|
if lastNode.Protocol == "socks5" {
|
||||||
if lastNode.GetBool("mbind") {
|
if lastNode.GetBool("mbind") {
|
||||||
return l.muxAccept() // multiplexing support for binding.
|
return l.muxAccept() // multiplexing support for binding.
|
||||||
}
|
}
|
||||||
@ -694,14 +753,6 @@ func (l *tcpRemoteForwardListener) accept() (conn net.Conn, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
cc.Close()
|
cc.Close()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if l.ln == nil {
|
|
||||||
l.ln, err = net.Listen("tcp", l.addr.String())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn, err = l.ln.Accept()
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -721,8 +772,8 @@ func (l *tcpRemoteForwardListener) muxAccept() (conn net.Conn, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *tcpRemoteForwardListener) getSession() (*muxSession, error) {
|
func (l *tcpRemoteForwardListener) getSession() (*muxSession, error) {
|
||||||
l.mutex.Lock()
|
l.sessionMux.Lock()
|
||||||
defer l.mutex.Unlock()
|
defer l.sessionMux.Unlock()
|
||||||
|
|
||||||
if l.session != nil && !l.session.IsClosed() {
|
if l.session != nil && !l.session.IsClosed() {
|
||||||
return l.session, nil
|
return l.session, nil
|
||||||
@ -810,22 +861,40 @@ func (l *tcpRemoteForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *tcpRemoteForwardListener) Addr() net.Addr {
|
func (l *tcpRemoteForwardListener) Addr() net.Addr {
|
||||||
|
if l.ln != nil {
|
||||||
|
return l.ln.Addr()
|
||||||
|
}
|
||||||
return l.addr
|
return l.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *tcpRemoteForwardListener) Close() error {
|
func (l *tcpRemoteForwardListener) Close() error {
|
||||||
|
if l.ln != nil {
|
||||||
|
return l.ln.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
l.closeMux.Lock()
|
||||||
|
defer l.closeMux.Unlock()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-l.closed:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
close(l.closed)
|
close(l.closed)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpRemoteForwardListener struct {
|
type udpRemoteForwardListener struct {
|
||||||
addr *net.UDPAddr
|
addr net.Addr
|
||||||
chain *Chain
|
chain *Chain
|
||||||
conns map[string]*udpServerConn
|
conns map[string]*udpServerConn
|
||||||
connChan chan net.Conn
|
connChan chan net.Conn
|
||||||
|
ln *net.UDPConn
|
||||||
errChan chan error
|
errChan chan error
|
||||||
ttl time.Duration
|
ttl time.Duration
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
|
closeMux sync.Mutex
|
||||||
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
|
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
|
||||||
@ -844,8 +913,17 @@ func UDPRemoteForwardListener(addr string, chain *Chain, ttl time.Duration) (Lis
|
|||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
go ln.listenLoop()
|
go ln.listenLoop()
|
||||||
return ln, nil
|
|
||||||
|
err = <-ln.errChan
|
||||||
|
|
||||||
|
return ln, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *udpRemoteForwardListener) isChainValid() bool {
|
||||||
|
lastNode := l.chain.LastNode()
|
||||||
|
return lastNode.Protocol == "socks5"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpRemoteForwardListener) listenLoop() {
|
func (l *udpRemoteForwardListener) listenLoop() {
|
||||||
@ -855,7 +933,6 @@ func (l *udpRemoteForwardListener) listenLoop() {
|
|||||||
log.Logf("[rudp] %s : %s", l.Addr(), err)
|
log.Logf("[rudp] %s : %s", l.Addr(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -911,8 +988,18 @@ func (l *udpRemoteForwardListener) connect() (conn net.PacketConn, err error) {
|
|||||||
conn = &udpTunnelConn{Conn: cc}
|
conn = &udpTunnelConn{Conn: cc}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conn, err = net.ListenUDP("udp", l.addr)
|
var uc *net.UDPConn
|
||||||
|
uc, err = net.ListenUDP("udp", l.addr.(*net.UDPAddr))
|
||||||
|
if err == nil {
|
||||||
|
l.addr = uc.LocalAddr()
|
||||||
|
conn = uc
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l.once.Do(func() {
|
||||||
|
l.errChan <- err
|
||||||
|
close(l.errChan)
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tempDelay == 0 {
|
if tempDelay == 0 {
|
||||||
@ -932,14 +1019,11 @@ func (l *udpRemoteForwardListener) connect() (conn net.PacketConn, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpRemoteForwardListener) Accept() (conn net.Conn, err error) {
|
func (l *udpRemoteForwardListener) Accept() (conn net.Conn, err error) {
|
||||||
var ok bool
|
|
||||||
select {
|
select {
|
||||||
case conn = <-l.connChan:
|
case conn = <-l.connChan:
|
||||||
case err, ok = <-l.errChan:
|
case <-l.closed:
|
||||||
if !ok {
|
|
||||||
err = errors.New("accpet on closed listener")
|
err = errors.New("accpet on closed listener")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,6 +1032,15 @@ func (l *udpRemoteForwardListener) Addr() net.Addr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *udpRemoteForwardListener) Close() error {
|
func (l *udpRemoteForwardListener) Close() error {
|
||||||
|
l.closeMux.Lock()
|
||||||
|
defer l.closeMux.Unlock()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-l.closed:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
close(l.closed)
|
close(l.closed)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
333
forward_test.go
Normal file
333
forward_test.go
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
package gost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tcpDirectForwardRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: TCPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTCPDirectForward(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := tcpDirectForwardRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTCPDirectForward(b *testing.B) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: TCPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(httpSrv.URL)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
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 BenchmarkTCPDirectForwardParallel(b *testing.B) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: TCPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(httpSrv.URL)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
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 udpRoundtrip(client *Client, server *Server, host string, data []byte) (err error) {
|
||||||
|
conn, err := proxyConn(client, server)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
conn.SetDeadline(time.Now().Add(1 * time.Second))
|
||||||
|
defer conn.SetDeadline(time.Time{})
|
||||||
|
|
||||||
|
conn, err = client.Connect(conn, host)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = conn.Write(data); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
recv := make([]byte, len(data))
|
||||||
|
if _, err = conn.Read(recv); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(data, recv) {
|
||||||
|
return fmt.Errorf("data not equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func udpDirectForwardRoundtrip(host string, data []byte) error {
|
||||||
|
ln, err := UDPDirectForwardListener("localhost:0", 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: UDPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: UDPDirectForwardHandler(host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return udpRoundtrip(client, server, host, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUDPDirectForward(t *testing.T) {
|
||||||
|
udpSrv := newUDPTestServer(udpTestHandler)
|
||||||
|
udpSrv.Start()
|
||||||
|
defer udpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
err := udpDirectForwardRoundtrip(udpSrv.Addr(), sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUDPDirectForward(b *testing.B) {
|
||||||
|
udpSrv := newUDPTestServer(udpTestHandler)
|
||||||
|
udpSrv.Start()
|
||||||
|
defer udpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := UDPDirectForwardListener("localhost:0", 0)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: UDPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: UDPDirectForwardHandler(udpSrv.Addr()),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if err := udpRoundtrip(client, server, udpSrv.Addr(), sendData); err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkUDPDirectForwardParallel(b *testing.B) {
|
||||||
|
udpSrv := newUDPTestServer(udpTestHandler)
|
||||||
|
udpSrv.Start()
|
||||||
|
defer udpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := UDPDirectForwardListener("localhost:0", 0)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: UDPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: UDPDirectForwardHandler(udpSrv.Addr()),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
if err := udpRoundtrip(client, server, udpSrv.Addr(), sendData); err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcpRemoteForwardRoundtrip(t *testing.T, targetURL string, data []byte) error {
|
||||||
|
ln, err := TCPRemoteForwardListener("localhost:0", nil) // listening on localhost
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: TCPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPRemoteForwardHandler(u.Host), // forward to u.Host
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTCPRemoteForward(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := tcpRemoteForwardRoundtrip(t, httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func udpRemoteForwardRoundtrip(t *testing.T, host string, data []byte) error {
|
||||||
|
ln, err := UDPRemoteForwardListener("localhost:0", nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: UDPTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: UDPRemoteForwardHandler(host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return udpRoundtrip(client, server, host, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUDPRemoteForward(t *testing.T) {
|
||||||
|
udpSrv := newUDPTestServer(udpTestHandler)
|
||||||
|
udpSrv.Start()
|
||||||
|
defer udpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := udpRemoteForwardRoundtrip(t, udpSrv.Addr(), sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
@ -484,6 +484,46 @@ func TestSNIOverH2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func h2ForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := H2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: H2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestH2ForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := h2ForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(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 {
|
||||||
|
|
||||||
@ -840,3 +880,43 @@ func TestSNIOverH2C(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func h2cForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := H2CListener("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: H2CTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestH2CForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := h2cForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
19
http_test.go
19
http_test.go
@ -4,10 +4,8 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -17,23 +15,6 @@ import (
|
|||||||
"time"
|
"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)
|
|
||||||
})
|
|
||||||
|
|
||||||
// proxyConn obtains a connection to the proxy server.
|
// proxyConn obtains a connection to the proxy server.
|
||||||
func proxyConn(client *Client, server *Server) (net.Conn, error) {
|
func proxyConn(client *Client, server *Server) (net.Conn, error) {
|
||||||
conn, err := client.Dial(server.Addr().String())
|
conn, err := client.Dial(server.Addr().String())
|
||||||
|
40
kcp_test.go
40
kcp_test.go
@ -365,3 +365,43 @@ func TestSNIOverKCP(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func kcpForwardTunnelRoundtrip(targetURL string, data []byte) 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: ForwardConnector(),
|
||||||
|
Transporter: KCPTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKCPForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := kcpForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
40
quic_test.go
40
quic_test.go
@ -365,3 +365,43 @@ func TestSNIOverQUIC(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func quicForwardTunnelRoundtrip(targetURL string, data []byte) 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: ForwardConnector(),
|
||||||
|
Transporter: QUICTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQUICForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := quicForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
10
selector.go
10
selector.go
@ -22,9 +22,7 @@ type defaultSelector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *defaultSelector) Select(nodes []Node, opts ...SelectOption) (Node, error) {
|
func (s *defaultSelector) Select(nodes []Node, opts ...SelectOption) (Node, error) {
|
||||||
sopts := SelectOptions{
|
sopts := SelectOptions{}
|
||||||
Strategy: &RoundStrategy{},
|
|
||||||
}
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt(&sopts)
|
opt(&sopts)
|
||||||
}
|
}
|
||||||
@ -35,7 +33,11 @@ func (s *defaultSelector) Select(nodes []Node, opts ...SelectOption) (Node, erro
|
|||||||
if len(nodes) == 0 {
|
if len(nodes) == 0 {
|
||||||
return Node{}, ErrNoneAvailable
|
return Node{}, ErrNoneAvailable
|
||||||
}
|
}
|
||||||
return sopts.Strategy.Apply(nodes), nil
|
strategy := sopts.Strategy
|
||||||
|
if strategy == nil {
|
||||||
|
strategy = &RoundStrategy{}
|
||||||
|
}
|
||||||
|
return strategy.Apply(nodes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectOption is the option used when making a select call.
|
// SelectOption is the option used when making a select call.
|
||||||
|
2
socks.go
2
socks.go
@ -172,7 +172,7 @@ func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Con
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if Debug {
|
if Debug {
|
||||||
log.Log("[socks5] %s - %s: %s", conn.RemoteAddr(), conn.LocalAddr(), resp)
|
log.Logf("[socks5] %s - %s: %s", conn.RemoteAddr(), conn.LocalAddr(), resp)
|
||||||
}
|
}
|
||||||
log.Logf("[socks5] %s - %s: proxy authentication required", conn.RemoteAddr(), conn.LocalAddr())
|
log.Logf("[socks5] %s - %s: proxy authentication required", conn.RemoteAddr(), conn.LocalAddr())
|
||||||
return nil, gosocks5.ErrAuthFailure
|
return nil, gosocks5.ErrAuthFailure
|
||||||
|
40
ssh_test.go
40
ssh_test.go
@ -367,3 +367,43 @@ func TestSNIOverSSHTunnel(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sshForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := SSHTunnelListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: SSHTunnelTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSSHForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := sshForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
80
tls_test.go
80
tls_test.go
@ -368,6 +368,46 @@ func TestSNIOverTLS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tlsForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := TLSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: TLSTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTLSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := tlsForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(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 {
|
||||||
|
|
||||||
@ -726,3 +766,43 @@ func TestSNIOverMTLS(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mtlsForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := MTLSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: MTLSTransporter(),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMTLSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := mtlsForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
80
ws_test.go
80
ws_test.go
@ -366,6 +366,46 @@ func TestSNIOverWS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wsForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := WSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: WSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := wsForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(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 {
|
||||||
|
|
||||||
@ -724,3 +764,43 @@ func TestSNIOverMWS(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mwsForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := MWSListener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: MWSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMWSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := mwsForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
80
wss_test.go
80
wss_test.go
@ -367,6 +367,46 @@ func TestSNIOverWSS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wssForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := WSSListener("", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: WSSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWSSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := wssForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(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 {
|
||||||
|
|
||||||
@ -725,3 +765,43 @@ func TestSNIOverMWSS(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mwssForwardTunnelRoundtrip(targetURL string, data []byte) error {
|
||||||
|
ln, err := MWSSListener("", nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(targetURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: ForwardConnector(),
|
||||||
|
Transporter: MWSSTransporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: TCPDirectForwardHandler(u.Host),
|
||||||
|
}
|
||||||
|
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
return proxyRoundtrip(client, server, targetURL, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMWSSForwardTunnel(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
err := mwssForwardTunnelRoundtrip(httpSrv.URL, sendData)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user