v2ray 9 tahun lalu
induk
melakukan
754e8b6e78

+ 0 - 35
proxy/http/config.go

@@ -1,42 +1,7 @@
 package http
 
-import "crypto/tls"
-
-// CertificateConfig is the config for TLS certificates used in HTTP proxy.
-type CertificateConfig struct {
-	Domain      string
-	Certificate tls.Certificate
-}
-
-// TlsConfig is the config for TLS connections.
-type TLSConfig struct {
-	Enabled bool
-	Certs   []*CertificateConfig
-}
-
-// GetConfig returns corresponding tls.Config.
-func (this *TLSConfig) GetConfig() *tls.Config {
-	if !this.Enabled {
-		return nil
-	}
-
-	config := &tls.Config{
-		InsecureSkipVerify: false,
-	}
-
-	config.Certificates = make([]tls.Certificate, len(this.Certs))
-	for index, cert := range this.Certs {
-		config.Certificates[index] = cert.Certificate
-	}
-
-	config.BuildNameToCertificate()
-
-	return config
-}
-
 // Config for HTTP proxy server.
 type Config struct {
-	TLSConfig *TLSConfig
 }
 
 // ClientConfig for HTTP proxy client.

+ 0 - 41
proxy/http/config_json.go

@@ -3,7 +3,6 @@
 package http
 
 import (
-	"crypto/tls"
 	"encoding/json"
 	"errors"
 
@@ -11,54 +10,14 @@ import (
 )
 
 // UnmarshalJSON implements json.Unmarshaler
-func (this *CertificateConfig) UnmarshalJSON(data []byte) error {
-	type JsonConfig struct {
-		Domain   string `json:"domain"`
-		CertFile string `json:"cert"`
-		KeyFile  string `json:"key"`
-	}
-	jsonConfig := new(JsonConfig)
-	if err := json.Unmarshal(data, jsonConfig); err != nil {
-		return errors.New("HTTP: Failed to parse certificate config: " + err.Error())
-	}
-
-	cert, err := tls.LoadX509KeyPair(jsonConfig.CertFile, jsonConfig.KeyFile)
-	if err != nil {
-		return err
-	}
-	this.Domain = jsonConfig.Domain
-	this.Certificate = cert
-	return nil
-}
-
-// UnmarshalJSON implements json.Unmarshaler
-func (this *TLSConfig) UnmarshalJSON(data []byte) error {
-	type JsonConfig struct {
-		Enabled bool                 `json:"enable"`
-		Certs   []*CertificateConfig `json:"certs"`
-	}
-	jsonConfig := new(JsonConfig)
-	if err := json.Unmarshal(data, jsonConfig); err != nil {
-		return errors.New("HTTP: Failed to parse TLS config: " + err.Error())
-	}
-
-	this.Enabled = jsonConfig.Enabled
-	this.Certs = jsonConfig.Certs
-	return nil
-}
-
-// UnmarshalJSON implements json.Unmarshaler
 func (this *Config) UnmarshalJSON(data []byte) error {
 	type JsonConfig struct {
-		Tls *TLSConfig `json:"tls"`
 	}
 	jsonConfig := new(JsonConfig)
 	if err := json.Unmarshal(data, jsonConfig); err != nil {
 		return errors.New("HTTP: Failed to parse config: " + err.Error())
 	}
 
-	this.TLSConfig = jsonConfig.Tls
-
 	return nil
 }
 

+ 27 - 2
transport/internet/connection.go

@@ -1,6 +1,7 @@
 package internet
 
 import (
+	"crypto/tls"
 	"net"
 )
 
@@ -13,14 +14,38 @@ type Reusable interface {
 
 type StreamConnectionType int
 
-var (
+const (
 	StreamConnectionTypeRawTCP StreamConnectionType = 1
 	StreamConnectionTypeTCP    StreamConnectionType = 2
 	StreamConnectionTypeKCP    StreamConnectionType = 4
 )
 
+type StreamSecurityType int
+
+const (
+	StreamSecurityTypeNone StreamSecurityType = 0
+	StreamSecurityTypeTLS  StreamSecurityType = 1
+)
+
+type TLSSettings struct {
+	Certs []tls.Certificate
+}
+
+func (this *TLSSettings) GetTLSConfig() *tls.Config {
+	config := &tls.Config{
+		InsecureSkipVerify: true,
+	}
+
+	config.Certificates = this.Certs
+	config.BuildNameToCertificate()
+
+	return config
+}
+
 type StreamSettings struct {
-	Type StreamConnectionType
+	Type        StreamConnectionType
+	Security    StreamSecurityType
+	TLSSettings *TLSSettings
 }
 
 func (this *StreamSettings) IsCapableOf(streamType StreamConnectionType) bool {

+ 36 - 1
transport/internet/connection_json.go

@@ -3,14 +3,42 @@
 package internet
 
 import (
+	"crypto/tls"
 	"encoding/json"
+	"errors"
+	"strings"
 
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
+func (this *TLSSettings) UnmarshalJSON(data []byte) error {
+	type JSONCertConfig struct {
+		CertFile string `json:"certFile"`
+		KeyFile  string `json:"keyFile"`
+	}
+	type JSONConfig struct {
+		Certs []*JSONCertConfig `json:"certs"`
+	}
+	jsonConfig := new(JSONConfig)
+	if err := json.Unmarshal(data, jsonConfig); err != nil {
+		return err
+	}
+	this.Certs = make([]tls.Certificate, len(jsonConfig.Certs))
+	for idx, certConf := range jsonConfig.Certs {
+		cert, err := tls.LoadX509KeyPair(certConf.CertFile, certConf.KeyFile)
+		if err != nil {
+			return errors.New("Internet|TLS: Failed to load certificate file: " + err.Error())
+		}
+		this.Certs[idx] = cert
+	}
+	return nil
+}
+
 func (this *StreamSettings) UnmarshalJSON(data []byte) error {
 	type JSONConfig struct {
-		Network v2net.NetworkList `json:"network"`
+		Network     v2net.NetworkList `json:"network"`
+		Security    string            `json:"security"`
+		TLSSettings *TLSSettings      `json:"tlsSettings"`
 	}
 	this.Type = StreamConnectionTypeRawTCP
 	jsonConfig := new(JSONConfig)
@@ -23,5 +51,12 @@ func (this *StreamSettings) UnmarshalJSON(data []byte) error {
 	if jsonConfig.Network.HasNetwork(v2net.TCPNetwork) {
 		this.Type |= StreamConnectionTypeTCP
 	}
+	this.Security = StreamSecurityTypeNone
+	if strings.ToLower(jsonConfig.Security) == "tls" {
+		this.Security = StreamSecurityTypeTLS
+	}
+	if jsonConfig.TLSSettings != nil {
+		this.TLSSettings = jsonConfig.TLSSettings
+	}
 	return nil
 }

+ 22 - 4
transport/internet/dialer.go

@@ -1,11 +1,13 @@
 package internet
 
 import (
+	"crypto/tls"
 	"errors"
 	"net"
 	"time"
 
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	v2tls "github.com/v2ray/v2ray-core/transport/internet/tls"
 )
 
 var (
@@ -22,16 +24,32 @@ var (
 )
 
 func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (Connection, error) {
+	var connection Connection
+	var err error
 	if dest.IsTCP() {
 		switch {
 		case settings.IsCapableOf(StreamConnectionTypeTCP):
-			return TCPDialer(src, dest)
+			connection, err = TCPDialer(src, dest)
 		case settings.IsCapableOf(StreamConnectionTypeKCP):
-			return KCPDialer(src, dest)
+			connection, err = KCPDialer(src, dest)
 		case settings.IsCapableOf(StreamConnectionTypeRawTCP):
-			return RawTCPDialer(src, dest)
+			connection, err = RawTCPDialer(src, dest)
+		default:
+			return nil, ErrUnsupportedStreamType
 		}
-		return nil, ErrUnsupportedStreamType
+		if err != nil {
+			return nil, err
+		}
+		if settings.Security == StreamSecurityTypeNone {
+			return connection, nil
+		}
+
+		config := settings.TLSSettings.GetTLSConfig()
+		if dest.Address().IsDomain() {
+			config.ServerName = dest.Address().Domain()
+		}
+		tlsConn := tls.Client(connection, config)
+		return v2tls.NewConnection(tlsConn), nil
 	}
 
 	return UDPDialer(src, dest)

+ 13 - 0
transport/internet/tcp_hub.go

@@ -1,12 +1,14 @@
 package internet
 
 import (
+	"crypto/tls"
 	"errors"
 	"net"
 	"sync"
 
 	"github.com/v2ray/v2ray-core/common/log"
 	v2net "github.com/v2ray/v2ray-core/common/net"
+	v2tls "github.com/v2ray/v2ray-core/transport/internet/tls"
 )
 
 var (
@@ -29,6 +31,7 @@ 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) {
@@ -51,9 +54,15 @@ 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()
@@ -76,6 +85,10 @@ func (this *TCPHub) start() {
 			}
 			continue
 		}
+		if this.tlsConfig != nil {
+			tlsConn := tls.Server(conn, this.tlsConfig)
+			conn = v2tls.NewConnection(tlsConn)
+		}
 		go this.connCallback(conn)
 	}
 }

+ 21 - 0
transport/internet/tls/connection.go

@@ -0,0 +1,21 @@
+package tls
+
+import (
+	"crypto/tls"
+)
+
+type Connection struct {
+	*tls.Conn
+}
+
+func (this *Connection) Reusable() bool {
+	return false
+}
+
+func (this *Connection) SetReusable(bool) {}
+
+func NewConnection(conn *tls.Conn) *Connection {
+	return &Connection{
+		Conn: conn,
+	}
+}