diff --git a/README.md b/README.md index 2da68e00..56a7c0be 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ proxies: network: tcp servername: example.com # flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS + # udp: true # skip-cert-verify: true ``` diff --git a/adapter/outbound/vless.go b/adapter/outbound/vless.go index df7ce4a1..876613b2 100644 --- a/adapter/outbound/vless.go +++ b/adapter/outbound/vless.go @@ -3,6 +3,7 @@ package outbound import ( "context" "crypto/tls" + "encoding/binary" "errors" "fmt" "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) } default: + // default tcp network // handle TLS And XTLS - c, err = v.streamTLSOrXTLSConn(c, true) + c, err = v.streamTLSOrXTLSConn(c, false) } if err != nil { @@ -213,7 +215,7 @@ func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata, opts ...d // ListenPacketContext implements C.ProxyAdapter 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() { ip, err := resolver.ResolveIP(metadata.Host) if err != nil { @@ -269,7 +271,7 @@ func parseVlessAddr(metadata *C.Metadata) *vless.DstAddr { copy(addr[1:], []byte(metadata.Host)) } - port, _ := strconv.Atoi(metadata.DstPort) + port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) return &vless.DstAddr{ UDP: metadata.NetWork == C.UDP, AddrType: addrType, @@ -281,14 +283,21 @@ func parseVlessAddr(metadata *C.Metadata) *vless.DstAddr { type vlessPacketConn struct { net.Conn rAddr net.Addr + cache [2]byte } 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) } 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 } diff --git a/listener/redir/tcp_linux.go b/listener/redir/tcp_linux.go index e802319c..c4a47d8e 100644 --- a/listener/redir/tcp_linux.go +++ b/listener/redir/tcp_linux.go @@ -37,7 +37,7 @@ func parserPacket(conn net.Conn) (socks5.Addr, error) { // Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c func getorigdst(fd uintptr) (socks5.Addr, error) { raw := syscall.RawSockaddrInet4{} - siz := unsafe.Sizeof(raw) + siz := uint32(unsafe.Sizeof(raw)) if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil { return nil, err } diff --git a/listener/tun/device/tun/tun_wireguard.go b/listener/tun/device/tun/tun_wireguard.go index 30398b55..6e0ad15f 100644 --- a/listener/tun/device/tun/tun_wireguard.go +++ b/listener/tun/device/tun/tun_wireguard.go @@ -8,7 +8,6 @@ import ( "os" "runtime" - "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/listener/tun/device" "github.com/Dreamacro/clash/listener/tun/device/iobased" @@ -22,6 +21,8 @@ type TUN struct { mtu uint32 name string offset int + + cache []byte } func Open(name string, mtu uint32) (_ device.Device, err error) { @@ -70,6 +71,10 @@ func Open(name string, mtu uint32) (_ device.Device, err error) { } t.mtu = uint32(tunMTU) + if t.offset > 0 { + t.cache = make([]byte, 65535) + } + return t, nil } @@ -78,19 +83,9 @@ func (t *TUN) Read(packet []byte) (int, error) { return t.nt.Read(packet, t.offset) } - buff := pool.Get(t.offset + cap(packet)) - defer func() { - _ = pool.Put(buff) - }() + n, err := t.nt.Read(t.cache, t.offset) - n, err := t.nt.Read(buff, t.offset) - if err != nil { - return 0, err - } - - _ = buff[:t.offset] - - copy(packet, buff[t.offset:t.offset+n]) + copy(packet, t.cache[t.offset:t.offset+n]) return n, err } @@ -100,7 +95,8 @@ func (t *TUN) Write(packet []byte) (int, error) { return t.nt.Write(packet, t.offset) } - packet = append(make([]byte, t.offset), packet...) + _ = t.cache[:t.offset] + packet = append(t.cache[:t.offset], packet...) return t.nt.Write(packet, t.offset) } diff --git a/test/vless_test.go b/test/vless_test.go index 8bce51d6..b5fbec86 100644 --- a/test/vless_test.go +++ b/test/vless_test.go @@ -40,7 +40,7 @@ func TestClash_VlessTLS(t *testing.T) { TLS: true, SkipCertVerify: true, ServerName: "example.org", - UDP: false, + UDP: true, }) if err != nil { assert.FailNow(t, err.Error()) @@ -71,16 +71,16 @@ func TestClash_VlessXTLS(t *testing.T) { defer cleanContainer(id) proxy, err := outbound.NewVless(outbound.VlessOption{ - Name: "vless", - Server: localIP.String(), - Port: 10002, - UUID: "b831381d-6324-4d53-ad4f-8cda48b30811", - TLS: true, - Flow: "xtls-rprx-direct", - //FlowShow: true, + Name: "vless", + Server: localIP.String(), + Port: 10002, + UUID: "b831381d-6324-4d53-ad4f-8cda48b30811", + TLS: true, SkipCertVerify: true, ServerName: "example.org", - UDP: false, + UDP: true, + Flow: "xtls-rprx-direct", + FlowShow: true, }) if err != nil { assert.FailNow(t, err.Error())