feat: Add XUDP migration support

This commit is contained in:
H1JK 2023-06-07 23:03:36 +08:00
parent 093453582f
commit c3ef05b257
6 changed files with 55 additions and 25 deletions

View file

@ -14,6 +14,7 @@ import (
"github.com/Dreamacro/clash/common/convert"
N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/proxydialer"
"github.com/Dreamacro/clash/component/resolver"
@ -374,7 +375,9 @@ func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metada
if v.option.XUDP {
return newPacketConn(N.NewThreadSafePacketConn(
vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
vmessSing.NewXUDPConn(c,
utils.GlobalID(metadata.SourceAddress()),
M.SocksaddrFromNet(metadata.UDPAddr())),
), v), nil
} else if v.option.PacketAddr {
return newPacketConn(N.NewThreadSafePacketConn(

View file

@ -12,6 +12,7 @@ import (
"sync"
N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/proxydialer"
"github.com/Dreamacro/clash/component/resolver"
@ -224,29 +225,39 @@ func (v *Vmess) streamConn(c net.Conn, metadata *C.Metadata) (conn net.Conn, err
if metadata.NetWork == C.UDP {
if v.option.XUDP {
if N.NeedHandshake(c) {
conn = v.client.DialEarlyXUDPPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
conn = v.client.DialEarlyXUDPPacketConn(c,
utils.GlobalID(metadata.SourceAddress()),
M.SocksaddrFromNet(metadata.UDPAddr()))
} else {
conn, err = v.client.DialXUDPPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
conn, err = v.client.DialXUDPPacketConn(c,
utils.GlobalID(metadata.SourceAddress()),
M.SocksaddrFromNet(metadata.UDPAddr()))
}
} else if v.option.PacketAddr {
if N.NeedHandshake(c) {
conn = v.client.DialEarlyPacketConn(c, M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
conn = v.client.DialEarlyPacketConn(c,
M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
} else {
conn, err = v.client.DialPacketConn(c, M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
conn, err = v.client.DialPacketConn(c,
M.ParseSocksaddrHostPort(packetaddr.SeqPacketMagicAddress, 443))
}
conn = packetaddr.NewBindConn(conn)
} else {
if N.NeedHandshake(c) {
conn = v.client.DialEarlyPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
conn = v.client.DialEarlyPacketConn(c,
M.SocksaddrFromNet(metadata.UDPAddr()))
} else {
conn, err = v.client.DialPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
conn, err = v.client.DialPacketConn(c,
M.SocksaddrFromNet(metadata.UDPAddr()))
}
}
} else {
if N.NeedHandshake(c) {
conn = v.client.DialEarlyConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
conn = v.client.DialEarlyConn(c,
M.ParseSocksaddr(metadata.RemoteAddress()))
} else {
conn, err = v.client.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
conn, err = v.client.DialConn(c,
M.ParseSocksaddr(metadata.RemoteAddress()))
}
}
if err != nil {

13
common/utils/global_id.go Normal file
View file

@ -0,0 +1,13 @@
package utils
import (
"hash/maphash"
"unsafe"
)
var globalSeed = maphash.MakeSeed()
func GlobalID(material string) (id [8]byte) {
*(*uint64)(unsafe.Pointer(&id[0])) = maphash.String(globalSeed, material)
return
}

2
go.mod
View file

@ -108,4 +108,4 @@ require (
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20230530121223-b768faae5c6b
replace github.com/sagernet/sing-vmess => github.com/metacubex/sing-vmess v0.1.5-0.20230520082358-78b126617899
replace github.com/sagernet/sing-vmess => github.com/metacubex/sing-vmess v0.1.5-0.20230607134851-17f84aec22a1

4
go.sum
View file

@ -103,8 +103,8 @@ github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca h1:10q
github.com/metacubex/sing-shadowsocks2 v0.0.0-20230529235701-a238874242ca/go.mod h1:jVDD4N22bDPPKA73NvB7aqdlLWiAwv8D+jx7HwhcWak=
github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e h1:7QlJQl4S3F3YXn48fYxjymMw8HkXg9bl++hLi4ZRyCY=
github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e/go.mod h1:u9onX49LZPYuIPQ7SdM64Gnins8y5wg4Cn6ZYRSxWHU=
github.com/metacubex/sing-vmess v0.1.5-0.20230520082358-78b126617899 h1:iRfcuztp7REfmOyasSlCL/pqNWfUDMTJ2CwbGpxpeks=
github.com/metacubex/sing-vmess v0.1.5-0.20230520082358-78b126617899/go.mod h1:RSt9rxGHllLdc5JUebkQwaqyWLx09Lqya37DlBe8CP8=
github.com/metacubex/sing-vmess v0.1.5-0.20230607134851-17f84aec22a1 h1:ARhfmDKWzOsDEX5oUiC8bnz7FxQFukLV6fBiNM73r/M=
github.com/metacubex/sing-vmess v0.1.5-0.20230607134851-17f84aec22a1/go.mod h1:RSt9rxGHllLdc5JUebkQwaqyWLx09Lqya37DlBe8CP8=
github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a h1:cWKym33Qvl6HA3hj4/YuYD8hHyqQPb47wT5cJRAPgco=
github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a/go.mod h1:Bsw2BvKMMMY0FhZPseDI50ZOalvoUPMKYyGpyqvIIqY=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=

View file

@ -203,24 +203,27 @@ func newConn(conn net.Conn, client *Client, dst *DstAddr) (net.Conn, error) {
needHandshake: true,
}
if !dst.UDP && client.Addons != nil {
if client.Addons != nil {
switch client.Addons.Flow {
case XRO, XRD, XRS:
if xtlsConn, ok := conn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = client.XTLSShow
xtlsConn.MARK = "XTLS"
if client.Addons.Flow == XRS {
client.Addons.Flow = XRD
}
if !dst.UDP {
if xtlsConn, ok := conn.(*xtls.Conn); ok {
xtlsConn.RPRX = true
xtlsConn.SHOW = client.XTLSShow
xtlsConn.MARK = "XTLS"
if client.Addons.Flow == XRS {
client.Addons.Flow = XRD
}
if client.Addons.Flow == XRD {
xtlsConn.DirectMode = true
if client.Addons.Flow == XRD {
xtlsConn.DirectMode = true
}
c.addons = client.Addons
} else {
return nil, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", client.Addons.Flow)
}
c.addons = client.Addons
} else {
return nil, fmt.Errorf("failed to use %s, maybe \"security\" is not \"xtls\"", client.Addons.Flow)
}
case XRV:
visionConn, err := vision.NewConn(c, c.id)
if err != nil {