feat: VLESS support packet encodings (#334)

* adjust: Do not use XTLS on H2 connections

* feat: VLESS support XUDP fullcone NAT

* fix: VLESS with PacketAddr does not work

* fix: VLESS XUDP crash
This commit is contained in:
Hellojack
2023-01-11 22:01:15 +08:00
committed by GitHub
parent 0069513780
commit be6142aa43
6 changed files with 87 additions and 109 deletions

View File

@@ -1,60 +0,0 @@
// Modified from: https://github.com/Qv2ray/gun-lite
// License: MIT
package gun
import (
"crypto/tls"
"fmt"
"net"
xtls "github.com/xtls/go"
"golang.org/x/net/http2"
)
func NewHTTP2XTLSClient(dialFn DialFn, tlsConfig *tls.Config) *TransportWrap {
wrap := TransportWrap{}
dialFunc := func(network, addr string, cfg *tls.Config) (net.Conn, error) {
pconn, err := dialFn(network, addr)
if err != nil {
return nil, err
}
wrap.remoteAddr = pconn.RemoteAddr()
xtlsConfig := &xtls.Config{
InsecureSkipVerify: cfg.InsecureSkipVerify,
ServerName: cfg.ServerName,
}
cn := xtls.Client(pconn, xtlsConfig)
if err := cn.Handshake(); err != nil {
pconn.Close()
return nil, err
}
state := cn.ConnectionState()
if p := state.NegotiatedProtocol; p != http2.NextProtoTLS {
cn.Close()
return nil, fmt.Errorf("http2: unexpected ALPN protocol %s, want %s", p, http2.NextProtoTLS)
}
return cn, nil
}
wrap.Transport = &http2.Transport{
DialTLS: dialFunc,
TLSClientConfig: tlsConfig,
AllowHTTP: false,
DisableCompression: true,
PingTimeout: 0,
}
return &wrap
}
func StreamGunWithXTLSConn(conn net.Conn, tlsConfig *tls.Config, cfg *Config) (net.Conn, error) {
dialFn := func(network, addr string) (net.Conn, error) {
return conn, nil
}
transport := NewHTTP2XTLSClient(dialFn, tlsConfig)
return StreamGunWithTransport(transport, cfg)
}

View File

@@ -51,17 +51,20 @@ func (vc *Conn) sendRequest() error {
buf.WriteByte(0) // addon data length. 0 means no addon data
}
// command
if vc.dst.UDP {
buf.WriteByte(CommandUDP)
if vc.dst.Mux {
buf.WriteByte(CommandMux)
} else {
buf.WriteByte(CommandTCP)
}
if vc.dst.UDP {
buf.WriteByte(CommandUDP)
} else {
buf.WriteByte(CommandTCP)
}
// Port AddrType Addr
binary.Write(buf, binary.BigEndian, uint16(vc.dst.Port))
buf.WriteByte(vc.dst.AddrType)
buf.Write(vc.dst.Addr)
// Port AddrType Addr
binary.Write(buf, binary.BigEndian, vc.dst.Port)
buf.WriteByte(vc.dst.AddrType)
buf.Write(vc.dst.Addr)
}
_, err := vc.Conn.Write(buf.Bytes())
return err

View File

@@ -1,9 +1,10 @@
package vless
import (
"github.com/Dreamacro/clash/common/utils"
"net"
"github.com/Dreamacro/clash/common/utils"
"github.com/gofrs/uuid"
)
@@ -19,6 +20,7 @@ const (
const (
CommandTCP byte = 1
CommandUDP byte = 2
CommandMux byte = 3
)
// Addr types
@@ -33,7 +35,8 @@ type DstAddr struct {
UDP bool
AddrType byte
Addr []byte
Port uint
Port uint16
Mux bool // currently used for XUDP only
}
// Client is vless connection generator

View File

@@ -12,7 +12,7 @@ import (
type XTLSConfig struct {
Host string
SkipCertVerify bool
FingerPrint string
Fingerprint string
NextProtos []string
}
@@ -22,11 +22,11 @@ func StreamXTLSConn(conn net.Conn, cfg *XTLSConfig) (net.Conn, error) {
InsecureSkipVerify: cfg.SkipCertVerify,
NextProtos: cfg.NextProtos,
}
if len(cfg.FingerPrint) == 0 {
if len(cfg.Fingerprint) == 0 {
xtlsConfig = tlsC.GetGlobalFingerprintXTLCConfig(xtlsConfig)
} else {
var err error
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, cfg.FingerPrint); err != nil {
if xtlsConfig, err = tlsC.GetSpecifiedFingerprintXTLSConfig(xtlsConfig, cfg.Fingerprint); err != nil {
return nil, err
}
}