feat: Add XUDP migration support
This commit is contained in:
parent
093453582f
commit
c3ef05b257
6 changed files with 55 additions and 25 deletions
|
@ -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(
|
||||
|
|
|
@ -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
13
common/utils/global_id.go
Normal 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
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue