Fix: Vless UDP

This commit is contained in:
yaling888 2022-03-29 07:18:09 +08:00
parent 56e2c172e1
commit 131e9d38b6
3 changed files with 23 additions and 13 deletions

View file

@ -140,6 +140,7 @@ proxies:
network: tcp network: tcp
servername: example.com servername: example.com
# flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS # flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS
# udp: true
# skip-cert-verify: true # skip-cert-verify: true
``` ```

View file

@ -3,6 +3,7 @@ package outbound
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"net" "net"
@ -128,8 +129,9 @@ func (v *Vless) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig) c, err = gun.StreamGunWithConn(c, v.gunTLSConfig, v.gunConfig)
} }
default: default:
// default tcp network
// handle TLS And XTLS // handle TLS And XTLS
c, err = v.streamTLSOrXTLSConn(c, true) c, err = v.streamTLSOrXTLSConn(c, false)
} }
if err != nil { if err != nil {
@ -213,7 +215,7 @@ func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d
// ListenPacketContext implements C.ProxyAdapter // ListenPacketContext implements C.ProxyAdapter
func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.PacketConn, err error) { func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.PacketConn, err error) {
// vmess use stream-oriented udp with a special address, so we needs a net.UDPAddr // vless use stream-oriented udp with a special address, so we needs a net.UDPAddr
if !metadata.Resolved() { if !metadata.Resolved() {
ip, err := resolver.ResolveIP(metadata.Host) ip, err := resolver.ResolveIP(metadata.Host)
if err != nil { if err != nil {
@ -269,7 +271,7 @@ func parseVlessAddr(metadata *C.Metadata) *vless.DstAddr {
copy(addr[1:], []byte(metadata.Host)) copy(addr[1:], []byte(metadata.Host))
} }
port, _ := strconv.Atoi(metadata.DstPort) port, _ := strconv.ParseUint(metadata.DstPort, 10, 16)
return &vless.DstAddr{ return &vless.DstAddr{
UDP: metadata.NetWork == C.UDP, UDP: metadata.NetWork == C.UDP,
AddrType: addrType, AddrType: addrType,
@ -281,14 +283,21 @@ func parseVlessAddr(metadata *C.Metadata) *vless.DstAddr {
type vlessPacketConn struct { type vlessPacketConn struct {
net.Conn net.Conn
rAddr net.Addr rAddr net.Addr
cache [2]byte
} }
func (uc *vlessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { func (uc *vlessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
binary.BigEndian.PutUint16(uc.cache[:], uint16(len(b)))
_, _ = uc.Conn.Write(uc.cache[:])
return uc.Conn.Write(b) return uc.Conn.Write(b)
} }
func (uc *vlessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { func (uc *vlessPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
n, err := uc.Conn.Read(b) n, err := uc.Conn.Read(uc.cache[:])
if err != nil {
return n, uc.rAddr, err
}
n, err = uc.Conn.Read(b)
return n, uc.rAddr, err return n, uc.rAddr, err
} }

View file

@ -40,7 +40,7 @@ func TestClash_VlessTLS(t *testing.T) {
TLS: true, TLS: true,
SkipCertVerify: true, SkipCertVerify: true,
ServerName: "example.org", ServerName: "example.org",
UDP: false, UDP: true,
}) })
if err != nil { if err != nil {
assert.FailNow(t, err.Error()) assert.FailNow(t, err.Error())
@ -76,11 +76,11 @@ func TestClash_VlessXTLS(t *testing.T) {
Port: 10002, Port: 10002,
UUID: "b831381d-6324-4d53-ad4f-8cda48b30811", UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
TLS: true, TLS: true,
Flow: "xtls-rprx-direct",
//FlowShow: true,
SkipCertVerify: true, SkipCertVerify: true,
ServerName: "example.org", ServerName: "example.org",
UDP: false, UDP: true,
Flow: "xtls-rprx-direct",
FlowShow: true,
}) })
if err != nil { if err != nil {
assert.FailNow(t, err.Error()) assert.FailNow(t, err.Error())