Sfoglia il codice sorgente

integrate tls settings in ws

Darien Raymond 9 anni fa
parent
commit
5ec948f690

+ 10 - 0
transport/config.proto

@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package v2ray.core.transport;
+option go_package = "transport";
+option java_package = "com.v2ray.core.transport";
+option java_outer_classname = "ConfigProto";
+
+message Config {
+  
+}

+ 4 - 1
transport/internet/connection.go

@@ -39,10 +39,13 @@ type TLSSettings struct {
 
 func (this *TLSSettings) GetTLSConfig() *tls.Config {
 	config := &tls.Config{
-		InsecureSkipVerify: this.AllowInsecure,
 		ClientSessionCache: globalSessionCache,
 	}
+	if this == nil {
+		return config
+	}
 
+	config.InsecureSkipVerify = this.AllowInsecure
 	config.Certificates = this.Certs
 	config.BuildNameToCertificate()
 

+ 14 - 18
transport/internet/dialer.go

@@ -1,19 +1,21 @@
 package internet
 
 import (
-	"crypto/tls"
 	"errors"
 	"net"
 
 	v2net "v2ray.com/core/common/net"
-	v2tls "v2ray.com/core/transport/internet/tls"
 )
 
 var (
 	ErrUnsupportedStreamType = errors.New("Unsupported stream type.")
 )
 
-type Dialer func(src v2net.Address, dest v2net.Destination) (Connection, error)
+type DialerOptions struct {
+	Stream *StreamSettings
+}
+
+type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
 
 var (
 	TCPDialer    Dialer
@@ -27,18 +29,21 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
 
 	var connection Connection
 	var err error
+	dialerOptions := DialerOptions{
+		Stream: settings,
+	}
 	if dest.Network == v2net.Network_TCP {
 		switch {
 		case settings.IsCapableOf(StreamConnectionTypeTCP):
-			connection, err = TCPDialer(src, dest)
+			connection, err = TCPDialer(src, dest, dialerOptions)
 		case settings.IsCapableOf(StreamConnectionTypeKCP):
-			connection, err = KCPDialer(src, dest)
+			connection, err = KCPDialer(src, dest, dialerOptions)
 		case settings.IsCapableOf(StreamConnectionTypeWebSocket):
-			connection, err = WSDialer(src, dest)
+			connection, err = WSDialer(src, dest, dialerOptions)
 
 			// This check has to be the last one.
 		case settings.IsCapableOf(StreamConnectionTypeRawTCP):
-			connection, err = RawTCPDialer(src, dest)
+			connection, err = RawTCPDialer(src, dest, dialerOptions)
 		default:
 			return nil, ErrUnsupportedStreamType
 		}
@@ -46,19 +51,10 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (
 			return nil, err
 		}
 
-		if settings.Security == StreamSecurityTypeNone {
-			return connection, nil
-		}
-
-		config := settings.TLSSettings.GetTLSConfig()
-		if dest.Address.Family().IsDomain() {
-			config.ServerName = dest.Address.Domain()
-		}
-		tlsConn := tls.Client(connection, config)
-		return v2tls.NewConnection(tlsConn), nil
+		return connection, nil
 	}
 
-	return UDPDialer(src, dest)
+	return UDPDialer(src, dest, dialerOptions)
 }
 
 func DialToDest(src v2net.Address, dest v2net.Destination) (net.Conn, error) {

+ 16 - 2
transport/internet/kcp/dialer.go

@@ -1,6 +1,7 @@
 package kcp
 
 import (
+	"crypto/tls"
 	"net"
 	"sync/atomic"
 
@@ -8,13 +9,14 @@ import (
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
+	v2tls "v2ray.com/core/transport/internet/tls"
 )
 
 var (
 	globalConv = uint32(dice.Roll(65536))
 )
 
-func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
+func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
 	dest.Network = v2net.Network_UDP
 	log.Info("KCP|Dialer: Dialing KCP to ", dest)
 	conn, err := internet.DialToDest(src, dest)
@@ -32,7 +34,19 @@ func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, er
 	session := NewConnection(conv, conn, conn.LocalAddr().(*net.UDPAddr), conn.RemoteAddr().(*net.UDPAddr), cpip)
 	session.FetchInputFrom(conn)
 
-	return session, nil
+	var iConn internet.Connection
+	iConn = session
+
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		config := options.Stream.TLSSettings.GetTLSConfig()
+		if dest.Address.Family().IsDomain() {
+			config.ServerName = dest.Address.Domain()
+		}
+		tlsConn := tls.Client(conn, config)
+		iConn = v2tls.NewConnection(tlsConn)
+	}
+
+	return iConn, nil
 }
 
 func init() {

+ 3 - 2
transport/internet/kcp/kcp_test.go

@@ -10,13 +10,14 @@ import (
 
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/testing/assert"
+	"v2ray.com/core/transport/internet"
 	. "v2ray.com/core/transport/internet/kcp"
 )
 
 func TestDialAndListen(t *testing.T) {
 	assert := assert.On(t)
 
-	listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0))
+	listerner, err := NewListener(v2net.LocalHostIP, v2net.Port(0), internet.ListenOptions{})
 	assert.Error(err).IsNil()
 	port := v2net.Port(listerner.Addr().(*net.UDPAddr).Port)
 
@@ -45,7 +46,7 @@ func TestDialAndListen(t *testing.T) {
 
 	wg := new(sync.WaitGroup)
 	for i := 0; i < 10; i++ {
-		clientConn, err := DialKCP(v2net.LocalHostIP, v2net.UDPDestination(v2net.LocalHostIP, port))
+		clientConn, err := DialKCP(v2net.LocalHostIP, v2net.UDPDestination(v2net.LocalHostIP, port), internet.DialerOptions{})
 		assert.Error(err).IsNil()
 		wg.Add(1)
 

+ 13 - 3
transport/internet/kcp/listener.go

@@ -1,6 +1,7 @@
 package kcp
 
 import (
+	"crypto/tls"
 	"net"
 	"sync"
 	"time"
@@ -11,6 +12,7 @@ import (
 	"v2ray.com/core/common/serial"
 	"v2ray.com/core/proxy"
 	"v2ray.com/core/transport/internet"
+	v2tls "v2ray.com/core/transport/internet/tls"
 	"v2ray.com/core/transport/internet/udp"
 )
 
@@ -22,9 +24,10 @@ type Listener struct {
 	sessions      map[string]*Connection
 	awaitingConns chan *Connection
 	hub           *udp.UDPHub
+	tlsConfig     *tls.Config
 }
 
-func NewListener(address v2net.Address, port v2net.Port) (*Listener, error) {
+func NewListener(address v2net.Address, port v2net.Port, options internet.ListenOptions) (*Listener, error) {
 	auth, err := effectiveConfig.GetAuthenticator()
 	if err != nil {
 		return nil, err
@@ -35,6 +38,9 @@ func NewListener(address v2net.Address, port v2net.Port) (*Listener, error) {
 		awaitingConns: make(chan *Connection, 64),
 		running:       true,
 	}
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
+	}
 	hub, err := udp.ListenUDP(address, port, udp.ListenOption{Callback: l.OnReceive})
 	if err != nil {
 		return nil, err
@@ -120,6 +126,10 @@ func (this *Listener) Accept() (internet.Connection, error) {
 		}
 		select {
 		case conn := <-this.awaitingConns:
+			if this.tlsConfig != nil {
+				tlsConn := tls.Server(conn, this.tlsConfig)
+				return v2tls.NewConnection(tlsConn), nil
+			}
 			return conn, nil
 		case <-time.After(time.Second):
 
@@ -173,8 +183,8 @@ func (this *Writer) Close() error {
 	return nil
 }
 
-func ListenKCP(address v2net.Address, port v2net.Port) (internet.Listener, error) {
-	return NewListener(address, port)
+func ListenKCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
+	return NewListener(address, port, options)
 }
 
 func init() {

+ 11 - 2
transport/internet/tcp/dialer.go

@@ -3,6 +3,7 @@ package tcp
 import (
 	"net"
 
+	"crypto/tls"
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/transport/internet"
@@ -12,7 +13,7 @@ var (
 	globalCache = NewConnectionCache()
 )
 
-func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
+func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
 	log.Info("Dailing TCP to ", dest)
 	if src == nil {
 		src = v2net.AnyIP
@@ -29,15 +30,23 @@ func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error
 			return nil, err
 		}
 	}
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		config := options.Stream.TLSSettings.GetTLSConfig()
+		if dest.Address.Family().IsDomain() {
+			config.ServerName = dest.Address.Domain()
+		}
+		conn = tls.Client(conn, config)
+	}
 	return NewConnection(id, conn, globalCache), nil
 }
 
-func DialRaw(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
+func DialRaw(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
 	log.Info("Dailing Raw TCP to ", dest)
 	conn, err := internet.DialToDest(src, dest)
 	if err != nil {
 		return nil, err
 	}
+	// TODO: handle dialer options
 	return &RawConnection{
 		TCPConn: *conn.(*net.TCPConn),
 	}, nil

+ 13 - 3
transport/internet/tcp/hub.go

@@ -1,6 +1,7 @@
 package tcp
 
 import (
+	"crypto/tls"
 	"errors"
 	"net"
 	"sync"
@@ -24,9 +25,10 @@ type TCPListener struct {
 	acccepting    bool
 	listener      *net.TCPListener
 	awaitingConns chan *ConnectionWithError
+	tlsConfig     *tls.Config
 }
 
-func ListenTCP(address v2net.Address, port v2net.Port) (internet.Listener, error) {
+func ListenTCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
 	listener, err := net.ListenTCP("tcp", &net.TCPAddr{
 		IP:   address.IP(),
 		Port: int(port),
@@ -39,6 +41,9 @@ func ListenTCP(address v2net.Address, port v2net.Port) (internet.Listener, error
 		listener:      listener,
 		awaitingConns: make(chan *ConnectionWithError, 32),
 	}
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
+	}
 	go l.KeepAccepting()
 	return l, nil
 }
@@ -53,7 +58,11 @@ func (this *TCPListener) Accept() (internet.Connection, error) {
 			if connErr.err != nil {
 				return nil, connErr.err
 			}
-			return NewConnection("", connErr.conn, this), nil
+			conn := connErr.conn
+			if this.tlsConfig != nil {
+				conn = tls.Server(conn, this.tlsConfig)
+			}
+			return NewConnection("", conn, this), nil
 		case <-time.After(time.Second * 2):
 		}
 	}
@@ -139,7 +148,7 @@ func (this *RawTCPListener) Close() error {
 	return nil
 }
 
-func ListenRawTCP(address v2net.Address, port v2net.Port) (internet.Listener, error) {
+func ListenRawTCP(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
 	listener, err := net.ListenTCP("tcp", &net.TCPAddr{
 		IP:   address.IP(),
 		Port: int(port),
@@ -147,6 +156,7 @@ func ListenRawTCP(address v2net.Address, port v2net.Port) (internet.Listener, er
 	if err != nil {
 		return nil, err
 	}
+	// TODO: handle listen options
 	return &RawTCPListener{
 		accepting: true,
 		listener:  listener,

+ 12 - 18
transport/internet/tcp_hub.go

@@ -1,14 +1,12 @@
 package internet
 
 import (
-	"crypto/tls"
 	"errors"
 	"net"
 	"sync"
 
 	"v2ray.com/core/common/log"
 	v2net "v2ray.com/core/common/net"
-	v2tls "v2ray.com/core/transport/internet/tls"
 )
 
 var (
@@ -20,7 +18,11 @@ var (
 	WSListenFunc     ListenFunc
 )
 
-type ListenFunc func(address v2net.Address, port v2net.Port) (Listener, error)
+type ListenFunc func(address v2net.Address, port v2net.Port, options ListenOptions) (Listener, error)
+type ListenOptions struct {
+	Stream *StreamSettings
+}
+
 type Listener interface {
 	Accept() (Connection, error)
 	Close() error
@@ -32,21 +34,23 @@ type TCPHub struct {
 	listener     Listener
 	connCallback ConnectionHandler
 	accepting    bool
-	tlsConfig    *tls.Config
 }
 
 func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamSettings) (*TCPHub, error) {
 	var listener Listener
 	var err error
+	options := ListenOptions{
+		Stream: settings,
+	}
 	switch {
 	case settings.IsCapableOf(StreamConnectionTypeTCP):
-		listener, err = TCPListenFunc(address, port)
+		listener, err = TCPListenFunc(address, port, options)
 	case settings.IsCapableOf(StreamConnectionTypeKCP):
-		listener, err = KCPListenFunc(address, port)
+		listener, err = KCPListenFunc(address, port, options)
 	case settings.IsCapableOf(StreamConnectionTypeWebSocket):
-		listener, err = WSListenFunc(address, port)
+		listener, err = WSListenFunc(address, port, options)
 	case settings.IsCapableOf(StreamConnectionTypeRawTCP):
-		listener, err = RawTCPListenFunc(address, port)
+		listener, err = RawTCPListenFunc(address, port, options)
 	default:
 		log.Error("Internet|Listener: Unknown stream type: ", settings.Type)
 		err = ErrUnsupportedStreamType
@@ -57,15 +61,9 @@ func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandle
 		return nil, err
 	}
 
-	var tlsConfig *tls.Config
-	if settings.Security == StreamSecurityTypeTLS {
-		tlsConfig = settings.TLSSettings.GetTLSConfig()
-	}
-
 	hub := &TCPHub{
 		listener:     listener,
 		connCallback: callback,
-		tlsConfig:    tlsConfig,
 	}
 
 	go hub.start()
@@ -88,10 +86,6 @@ func (this *TCPHub) start() {
 			}
 			continue
 		}
-		if this.tlsConfig != nil {
-			tlsConn := tls.Server(conn, this.tlsConfig)
-			conn = v2tls.NewConnection(tlsConn)
-		}
 		go this.connCallback(conn)
 	}
 }

+ 2 - 1
transport/internet/udp/connection.go

@@ -18,11 +18,12 @@ func (this *Connection) Reusable() bool {
 func (this *Connection) SetReusable(b bool) {}
 
 func init() {
-	internet.UDPDialer = func(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
+	internet.UDPDialer = func(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
 		conn, err := internet.DialToDest(src, dest)
 		if err != nil {
 			return nil, err
 		}
+		// TODO: handle dialer options
 		return &Connection{
 			UDPConn: *(conn.(*net.UDPConn)),
 		}, nil

+ 2 - 7
transport/internet/ws/config.go

@@ -1,12 +1,8 @@
 package ws
 
 type Config struct {
-	ConnectionReuse             bool
-	Path                        string
-	Pto                         string
-	Cert                        string
-	PrivKey                     string
-	DeveloperInsecureSkipVerify bool
+	ConnectionReuse bool
+	Path            string
 }
 
 func (this *Config) Apply() {
@@ -17,6 +13,5 @@ var (
 	effectiveConfig = &Config{
 		ConnectionReuse: true,
 		Path:            "",
-		Pto:             "",
 	}
 )

+ 0 - 8
transport/internet/ws/config_json.go

@@ -8,23 +8,15 @@ func (this *Config) UnmarshalJSON(data []byte) error {
 	type JsonConfig struct {
 		ConnectionReuse bool   `json:"connectionReuse"`
 		Path            string `json:"Path"`
-		Pto             string `json:"Pto"`
-		Cert            string `json:"Cert"`
-		PrivKey         string `json:"PrivKey"`
 	}
 	jsonConfig := &JsonConfig{
 		ConnectionReuse: true,
 		Path:            "",
-		Pto:             "",
 	}
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
 		return err
 	}
 	this.ConnectionReuse = jsonConfig.ConnectionReuse
 	this.Path = jsonConfig.Path
-	this.Pto = jsonConfig.Pto
-	this.PrivKey = jsonConfig.PrivKey
-	this.Cert = jsonConfig.Cert
-	this.DeveloperInsecureSkipVerify = false
 	return nil
 }

+ 17 - 50
transport/internet/ws/dialer.go

@@ -1,7 +1,6 @@
 package ws
 
 import (
-	"crypto/tls"
 	"fmt"
 	"io/ioutil"
 	"net"
@@ -16,7 +15,7 @@ var (
 	globalCache = NewConnectionCache()
 )
 
-func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
+func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
 	log.Info("WebSocket|Dailer: Creating connection to ", dest)
 	if src == nil {
 		src = v2net.AnyIP
@@ -31,7 +30,7 @@ func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error
 	}
 	if conn == nil {
 		var err error
-		conn, err = wsDial(src, dest)
+		conn, err = wsDial(src, dest, options)
 		if err != nil {
 			log.Warning("WebSocket|Dialer: Dial failed: ", err)
 			return nil, err
@@ -44,20 +43,30 @@ func init() {
 	internet.WSDialer = Dial
 }
 
-func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
+func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) {
 	commonDial := func(network, addr string) (net.Conn, error) {
 		return internet.DialToDest(src, dest)
 	}
 
-	tlsconf := &tls.Config{ServerName: dest.Address.Domain(), InsecureSkipVerify: effectiveConfig.DeveloperInsecureSkipVerify}
+	dialer := websocket.Dialer{
+		NetDial:         commonDial,
+		ReadBufferSize:  65536,
+		WriteBufferSize: 65536,
+	}
 
-	dialer := websocket.Dialer{NetDial: commonDial, ReadBufferSize: 65536, WriteBufferSize: 65536, TLSClientConfig: tlsconf}
+	protocol := "ws"
 
-	effpto := calcPto(dest)
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		protocol = "wss"
+		dialer.TLSClientConfig = options.Stream.TLSSettings.GetTLSConfig()
+		if dest.Address.Family().IsDomain() {
+			dialer.TLSClientConfig.ServerName = dest.Address.Domain()
+		}
+	}
 
 	uri := func(dst v2net.Destination, pto string, path string) string {
 		return fmt.Sprintf("%v://%v/%v", pto, dst.NetAddr(), path)
-	}(dest, effpto, effectiveConfig.Path)
+	}(dest, protocol, effectiveConfig.Path)
 
 	conn, resp, err := dialer.Dial(uri, nil)
 	if err != nil {
@@ -73,45 +82,3 @@ func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
 		return connv2ray
 	}().(*wsconn), nil
 }
-
-func calcPto(dst v2net.Destination) string {
-
-	if effectiveConfig.Pto != "" {
-		return effectiveConfig.Pto
-	}
-
-	switch dst.Port.Value() {
-	/*
-		Since the value is not given explicitly,
-		We are guessing it now.
-
-		HTTP Port:
-				80
-				8080
-				8880
-				2052
-				2082
-				2086
-				2095
-
-		HTTPS Port:
-				443
-				2053
-				2083
-				2087
-				2096
-				8443
-
-		if the port you are using is not well-known,
-		specify it to avoid this process.
-
-		We will	return "CRASH"turn "unknown" if we can't guess it, cause Dial to fail.
-	*/
-	case 80, 8080, 8880, 2052, 2082, 2086, 2095:
-		return "ws"
-	case 443, 2053, 2083, 2087, 2096, 8443:
-		return "wss"
-	default:
-		return "unknown"
-	}
-}

+ 8 - 3
transport/internet/ws/hub.go

@@ -1,6 +1,7 @@
 package ws
 
 import (
+	"crypto/tls"
 	"errors"
 	"net"
 	"net/http"
@@ -28,14 +29,18 @@ type WSListener struct {
 	acccepting    bool
 	awaitingConns chan *ConnectionWithError
 	listener      *StoppableListener
+	tlsConfig     *tls.Config
 }
 
-func ListenWS(address v2net.Address, port v2net.Port) (internet.Listener, error) {
+func ListenWS(address v2net.Address, port v2net.Port, options internet.ListenOptions) (internet.Listener, error) {
 
 	l := &WSListener{
 		acccepting:    true,
 		awaitingConns: make(chan *ConnectionWithError, 32),
 	}
+	if options.Stream != nil && options.Stream.Security == internet.StreamSecurityTypeTLS {
+		l.tlsConfig = options.Stream.TLSSettings.GetTLSConfig()
+	}
 
 	err := l.listenws(address, port)
 
@@ -77,10 +82,10 @@ func (wsl *WSListener) listenws(address v2net.Address, port v2net.Port) error {
 		return http.Serve(wsl.listener, nil)
 	}
 
-	if effectiveConfig.Pto == "wss" {
+	if wsl.tlsConfig != nil {
 		listenerfunc = func() error {
 			var err error
-			wsl.listener, err = getstopableTLSlistener(effectiveConfig.Cert, effectiveConfig.PrivKey, address.String()+":"+strconv.Itoa(int(port.Value())))
+			wsl.listener, err = getstopableTLSlistener(wsl.tlsConfig, address.String()+":"+strconv.Itoa(int(port.Value())))
 			if err != nil {
 				return err
 			}

+ 2 - 8
transport/internet/ws/stopabletlslistener.go

@@ -2,14 +2,8 @@ package ws
 
 import "crypto/tls"
 
-func getstopableTLSlistener(cert, key, listenaddr string) (*StoppableListener, error) {
-	cer, err := tls.LoadX509KeyPair(cert, key)
-	if err != nil {
-		return nil, err
-	}
-
-	config := &tls.Config{Certificates: []tls.Certificate{cer}}
-	ln, err := tls.Listen("tcp", listenaddr, config)
+func getstopableTLSlistener(tlsConfig *tls.Config, listenaddr string) (*StoppableListener, error) {
+	ln, err := tls.Listen("tcp", listenaddr, tlsConfig)
 	if err != nil {
 		return nil, err
 	}

+ 67 - 29
transport/internet/ws/ws_test.go

@@ -1,18 +1,20 @@
 package ws_test
 
 import (
+	"crypto/tls"
 	"testing"
 	"time"
 
 	v2net "v2ray.com/core/common/net"
 	"v2ray.com/core/testing/assert"
+	"v2ray.com/core/transport/internet"
 	. "v2ray.com/core/transport/internet/ws"
 )
 
 func Test_Connect_ws(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "ws", Path: ""}).Apply()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80))
+	(&Config{Path: ""}).Apply()
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{})
 	assert.Error(err).IsNil()
 	conn.Write([]byte("echo"))
 	s := make(chan int)
@@ -31,8 +33,12 @@ func Test_Connect_ws(t *testing.T) {
 
 func Test_Connect_wss(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "wss", Path: ""}).Apply()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443))
+	(&Config{Path: ""}).Apply()
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+		},
+	})
 	assert.Error(err).IsNil()
 	conn.Write([]byte("echo"))
 	s := make(chan int)
@@ -51,8 +57,12 @@ func Test_Connect_wss(t *testing.T) {
 
 func Test_Connect_wss_1_nil(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "wss", Path: ""}).Apply()
-	conn, err := Dial(nil, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443))
+	(&Config{Path: ""}).Apply()
+	conn, err := Dial(nil, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+		},
+	})
 	assert.Error(err).IsNil()
 	conn.Write([]byte("echo"))
 	s := make(chan int)
@@ -71,8 +81,8 @@ func Test_Connect_wss_1_nil(t *testing.T) {
 
 func Test_Connect_ws_guess(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "", Path: ""}).Apply()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80))
+	(&Config{Path: ""}).Apply()
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 80), internet.DialerOptions{})
 	assert.Error(err).IsNil()
 	conn.Write([]byte("echo"))
 	s := make(chan int)
@@ -91,8 +101,12 @@ func Test_Connect_ws_guess(t *testing.T) {
 
 func Test_Connect_wss_guess(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "", Path: ""}).Apply()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443))
+	(&Config{Path: ""}).Apply()
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+		},
+	})
 	assert.Error(err).IsNil()
 	conn.Write([]byte("echo"))
 	s := make(chan int)
@@ -111,24 +125,25 @@ func Test_Connect_wss_guess(t *testing.T) {
 
 func Test_Connect_wss_guess_fail(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "", Path: ""}).Apply()
-	_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 443))
-	assert.Error(err).IsNotNil()
-}
-
-func Test_Connect_wss_guess_fail_port(t *testing.T) {
-	assert := assert.On(t)
-	(&Config{Pto: "", Path: ""}).Apply()
-	_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 179))
+	(&Config{Path: ""}).Apply()
+	_, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("static.kkdev.org"), 443), internet.DialerOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+		},
+	})
 	assert.Error(err).IsNotNil()
 }
 
 func Test_Connect_wss_guess_reuse(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "", Path: "", ConnectionReuse: true}).Apply()
+	(&Config{Path: "", ConnectionReuse: true}).Apply()
 	i := 3
 	for i != 0 {
-		conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443))
+		conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("echo.websocket.org"), 443), internet.DialerOptions{
+			Stream: &internet.StreamSettings{
+				Security: internet.StreamSecurityTypeTLS,
+			},
+		})
 		assert.Error(err).IsNil()
 		conn.Write([]byte("echo"))
 		s := make(chan int)
@@ -155,8 +170,8 @@ func Test_Connect_wss_guess_reuse(t *testing.T) {
 
 func Test_listenWSAndDial(t *testing.T) {
 	assert := assert.On(t)
-	(&Config{Pto: "ws", Path: "ws"}).Apply()
-	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13142)
+	(&Config{Path: "ws"}).Apply()
+	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13142, internet.ListenOptions{})
 	assert.Error(err).IsNil()
 	go func() {
 		conn, err := listen.Accept()
@@ -170,15 +185,15 @@ func Test_listenWSAndDial(t *testing.T) {
 		conn.Close()
 		listen.Close()
 	}()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142))
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
 	assert.Error(err).IsNil()
 	conn.Close()
 	<-time.After(time.Second * 5)
-	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142))
+	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
 	assert.Error(err).IsNil()
 	conn.Close()
 	<-time.After(time.Second * 15)
-	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142))
+	conn, err = Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13142), internet.DialerOptions{})
 	assert.Error(err).IsNil()
 	conn.Close()
 }
@@ -189,8 +204,17 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
 		<-time.After(time.Second * 5)
 		assert.Fail("Too slow")
 	}()
-	(&Config{Pto: "wss", Path: "wss", ConnectionReuse: true, DeveloperInsecureSkipVerify: true, PrivKey: "./../../../testing/tls/key.pem", Cert: "./../../../testing/tls/cert.pem"}).Apply()
-	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143)
+	(&Config{Path: "wss", ConnectionReuse: true}).Apply()
+
+	listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143, internet.ListenOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+			TLSSettings: &internet.TLSSettings{
+				AllowInsecure: true,
+				Certs:         LoadTestCert(assert),
+			},
+		},
+	})
 	assert.Error(err).IsNil()
 	go func() {
 		conn, err := listen.Accept()
@@ -198,7 +222,21 @@ func Test_listenWSAndDial_TLS(t *testing.T) {
 		conn.Close()
 		listen.Close()
 	}()
-	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143))
+	conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{
+		Stream: &internet.StreamSettings{
+			Security: internet.StreamSecurityTypeTLS,
+			TLSSettings: &internet.TLSSettings{
+				AllowInsecure: true,
+				Certs:         LoadTestCert(assert),
+			},
+		},
+	})
 	assert.Error(err).IsNil()
 	conn.Close()
 }
+
+func LoadTestCert(assert *assert.Assert) []tls.Certificate {
+	cert, err := tls.LoadX509KeyPair("./../../../testing/tls/cert.pem", "./../../../testing/tls/key.pem")
+	assert.Error(err).IsNil()
+	return []tls.Certificate{cert}
+}