Merge remote-tracking branch 'Pro-Plus/with-tun' into Alpha

# Conflicts:
#	README.md
#	adapter/outbound/trojan.go
#	adapter/outbound/vless.go
#	transport/trojan/trojan.go
This commit is contained in:
MetaCubeX
2022-03-30 13:15:45 +08:00
33 changed files with 569 additions and 327 deletions

View File

@ -7,7 +7,7 @@ import (
"encoding/binary"
"encoding/hex"
"errors"
xtls "github.com/xtls/go"
"fmt"
"io"
"net"
"net/http"
@ -16,15 +16,15 @@ import (
"github.com/Dreamacro/clash/common/pool"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/transport/socks5"
"github.com/Dreamacro/clash/transport/vless"
"github.com/Dreamacro/clash/transport/vmess"
xtls "github.com/xtls/go"
)
const (
// max packet length
maxLength = 8192
XRD = "xtls-rprx-direct"
XRO = "xtls-rprx-origin"
)
var (
@ -36,21 +36,22 @@ var (
type Command = byte
var (
const (
CommandTCP byte = 1
CommandUDP byte = 3
CommandXRD byte = 0xf0
CommandXRO byte = 0xf1
// for XTLS
commandXRD byte = 0xf0 // XTLS direct mode
commandXRO byte = 0xf1 // XTLS origin mode
)
type Option struct {
Password string
Flow string
ALPN []string
ServerName string
SkipCertVerify bool
ClientSessionCache tls.ClientSessionCache
ClientXSessionCache xtls.ClientSessionCache
Password string
ALPN []string
ServerName string
SkipCertVerify bool
Flow string
FlowShow bool
}
type WebsocketOption struct {
@ -65,28 +66,22 @@ type Trojan struct {
hexPassword []byte
}
func (t *Trojan) GetFlow() string {
return t.option.Flow
}
func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
alpn := defaultALPN
if len(t.option.ALPN) != 0 {
alpn = t.option.ALPN
}
switch t.option.Flow {
case XRD, XRO:
case vless.XRO, vless.XRD, vless.XRS:
xtlsConfig := &xtls.Config{
NextProtos: alpn,
MinVersion: xtls.VersionTLS12,
InsecureSkipVerify: t.option.SkipCertVerify,
ServerName: t.option.ServerName,
ClientSessionCache: t.option.ClientXSessionCache,
}
xtlsConn := xtls.Client(conn, xtlsConfig)
if err := xtlsConn.Handshake(); err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
defer cancel()
if err := xtlsConn.HandshakeContext(ctx); err != nil {
@ -99,7 +94,6 @@ func (t *Trojan) StreamConn(conn net.Conn) (net.Conn, error) {
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: t.option.SkipCertVerify,
ServerName: t.option.ServerName,
ClientSessionCache: t.option.ClientSessionCache,
}
tlsConn := tls.Client(conn, tlsConfig)
if err := tlsConn.Handshake(); err != nil {
@ -139,7 +133,37 @@ func (t *Trojan) StreamWebsocketConn(conn net.Conn, wsOptions *WebsocketOption)
})
}
func (t *Trojan) PresetXTLSConn(conn net.Conn) (net.Conn, error) {
switch t.option.Flow {
case vless.XRO, vless.XRD, vless.XRS:
if xtlsConn, ok := conn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = t.option.FlowShow
xtlsConn.MARK = "XTLS"
if t.option.Flow == vless.XRS {
t.option.Flow = vless.XRD
}
if t.option.Flow == vless.XRD {
xtlsConn.DirectMode = true
}
} else {
return nil, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", t.option.Flow)
}
}
return conn, nil
}
func (t *Trojan) WriteHeader(w io.Writer, command Command, socks5Addr []byte) error {
if command == CommandTCP {
if t.option.Flow == vless.XRD {
command = commandXRD
} else if t.option.Flow == vless.XRO {
command = commandXRO
}
}
buf := pool.GetBuffer()
defer pool.PutBuffer(buf)

View File

@ -35,15 +35,6 @@ type DstAddr struct {
Port uint
}
// Config of vless
type Config struct {
UUID string
AlterID uint16
Security string
Port string
HostName string
}
// Client is vless connection generator
type Client struct {
uuid *uuid.UUID