feat: Add XUDP migration support
This commit is contained in:
parent
f7362f82b5
commit
000197a706
6 changed files with 55 additions and 25 deletions
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/convert"
|
"github.com/Dreamacro/clash/common/convert"
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
"github.com/Dreamacro/clash/component/proxydialer"
|
"github.com/Dreamacro/clash/component/proxydialer"
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
"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 {
|
if v.option.XUDP {
|
||||||
return newPacketConn(N.NewThreadSafePacketConn(
|
return newPacketConn(N.NewThreadSafePacketConn(
|
||||||
vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
|
vmessSing.NewXUDPConn(c,
|
||||||
|
utils.GlobalID(metadata.SourceAddress()),
|
||||||
|
M.SocksaddrFromNet(metadata.UDPAddr())),
|
||||||
), v), nil
|
), v), nil
|
||||||
} else if v.option.PacketAddr {
|
} else if v.option.PacketAddr {
|
||||||
return newPacketConn(N.NewThreadSafePacketConn(
|
return newPacketConn(N.NewThreadSafePacketConn(
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
"github.com/Dreamacro/clash/component/proxydialer"
|
"github.com/Dreamacro/clash/component/proxydialer"
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
"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 metadata.NetWork == C.UDP {
|
||||||
if v.option.XUDP {
|
if v.option.XUDP {
|
||||||
if N.NeedHandshake(c) {
|
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 {
|
} 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 {
|
} else if v.option.PacketAddr {
|
||||||
if N.NeedHandshake(c) {
|
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 {
|
} 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)
|
conn = packetaddr.NewBindConn(conn)
|
||||||
} else {
|
} else {
|
||||||
if N.NeedHandshake(c) {
|
if N.NeedHandshake(c) {
|
||||||
conn = v.client.DialEarlyPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
conn = v.client.DialEarlyPacketConn(c,
|
||||||
|
M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
} else {
|
} else {
|
||||||
conn, err = v.client.DialPacketConn(c, M.SocksaddrFromNet(metadata.UDPAddr()))
|
conn, err = v.client.DialPacketConn(c,
|
||||||
|
M.SocksaddrFromNet(metadata.UDPAddr()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if N.NeedHandshake(c) {
|
if N.NeedHandshake(c) {
|
||||||
conn = v.client.DialEarlyConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
conn = v.client.DialEarlyConn(c,
|
||||||
|
M.ParseSocksaddr(metadata.RemoteAddress()))
|
||||||
} else {
|
} else {
|
||||||
conn, err = v.client.DialConn(c, M.ParseSocksaddr(metadata.RemoteAddress()))
|
conn, err = v.client.DialConn(c,
|
||||||
|
M.ParseSocksaddr(metadata.RemoteAddress()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
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 => 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-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 h1:7QlJQl4S3F3YXn48fYxjymMw8HkXg9bl++hLi4ZRyCY=
|
||||||
github.com/metacubex/sing-tun v0.1.5-0.20230530125750-171afb2dfd8e/go.mod h1:u9onX49LZPYuIPQ7SdM64Gnins8y5wg4Cn6ZYRSxWHU=
|
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.20230607134851-17f84aec22a1 h1:ARhfmDKWzOsDEX5oUiC8bnz7FxQFukLV6fBiNM73r/M=
|
||||||
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/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 h1:cWKym33Qvl6HA3hj4/YuYD8hHyqQPb47wT5cJRAPgco=
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a/go.mod h1:Bsw2BvKMMMY0FhZPseDI50ZOalvoUPMKYyGpyqvIIqY=
|
github.com/metacubex/sing-wireguard v0.0.0-20230426030325-41db09ae771a/go.mod h1:Bsw2BvKMMMY0FhZPseDI50ZOalvoUPMKYyGpyqvIIqY=
|
||||||
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
|
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,
|
needHandshake: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !dst.UDP && client.Addons != nil {
|
if client.Addons != nil {
|
||||||
switch client.Addons.Flow {
|
switch client.Addons.Flow {
|
||||||
case XRO, XRD, XRS:
|
case XRO, XRD, XRS:
|
||||||
if xtlsConn, ok := conn.(*xtls.Conn); ok {
|
if !dst.UDP {
|
||||||
xtlsConn.RPRX = true
|
if xtlsConn, ok := conn.(*xtls.Conn); ok {
|
||||||
xtlsConn.SHOW = client.XTLSShow
|
xtlsConn.RPRX = true
|
||||||
xtlsConn.MARK = "XTLS"
|
xtlsConn.SHOW = client.XTLSShow
|
||||||
if client.Addons.Flow == XRS {
|
xtlsConn.MARK = "XTLS"
|
||||||
client.Addons.Flow = XRD
|
if client.Addons.Flow == XRS {
|
||||||
}
|
client.Addons.Flow = XRD
|
||||||
|
}
|
||||||
|
|
||||||
if client.Addons.Flow == XRD {
|
if client.Addons.Flow == XRD {
|
||||||
xtlsConn.DirectMode = true
|
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:
|
case XRV:
|
||||||
visionConn, err := vision.NewConn(c, c.id)
|
visionConn, err := vision.NewConn(c, c.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue