fix: mux's udp should add write lock
This commit is contained in:
parent
82be6a68ad
commit
0253db1a1a
4 changed files with 29 additions and 19 deletions
|
@ -92,7 +92,7 @@ func (s *SingMux) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
|
||||||
if pc == nil {
|
if pc == nil {
|
||||||
return nil, E.New("packetConn is nil")
|
return nil, E.New("packetConn is nil")
|
||||||
}
|
}
|
||||||
return newPacketConn(CN.NewRefPacketConn(pc, s), s.ProxyAdapter), nil
|
return newPacketConn(CN.NewRefPacketConn(CN.NewThreadSafePacketConn(pc), s), s.ProxyAdapter), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SingMux) SupportUDP() bool {
|
func (s *SingMux) SupportUDP() bool {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/convert"
|
"github.com/Dreamacro/clash/common/convert"
|
||||||
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
"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"
|
||||||
|
@ -372,15 +373,15 @@ func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metada
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.option.XUDP {
|
if v.option.XUDP {
|
||||||
return newPacketConn(&threadSafePacketConn{
|
return newPacketConn(N.NewThreadSafePacketConn(
|
||||||
PacketConn: vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
|
vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
|
||||||
}, v), nil
|
), v), nil
|
||||||
} else if v.option.PacketAddr {
|
} else if v.option.PacketAddr {
|
||||||
return newPacketConn(&threadSafePacketConn{
|
return newPacketConn(N.NewThreadSafePacketConn(
|
||||||
PacketConn: packetaddr.NewConn(&vlessPacketConn{
|
packetaddr.NewConn(&vlessPacketConn{
|
||||||
Conn: c, rAddr: metadata.UDPAddr(),
|
Conn: c, rAddr: metadata.UDPAddr(),
|
||||||
}, M.SocksaddrFromNet(metadata.UDPAddr())),
|
}, M.SocksaddrFromNet(metadata.UDPAddr())),
|
||||||
}, v), nil
|
), v), nil
|
||||||
}
|
}
|
||||||
return newPacketConn(&vlessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
return newPacketConn(&vlessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,7 +379,7 @@ func (v *Vmess) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metada
|
||||||
}
|
}
|
||||||
|
|
||||||
if pc, ok := c.(net.PacketConn); ok {
|
if pc, ok := c.(net.PacketConn); ok {
|
||||||
return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil
|
return newPacketConn(N.NewThreadSafePacketConn(pc), v), nil
|
||||||
}
|
}
|
||||||
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
||||||
}
|
}
|
||||||
|
@ -489,17 +489,6 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type threadSafePacketConn struct {
|
|
||||||
net.PacketConn
|
|
||||||
access sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *threadSafePacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
|
||||||
c.access.Lock()
|
|
||||||
defer c.access.Unlock()
|
|
||||||
return c.PacketConn.WriteTo(b, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
type vmessPacketConn struct {
|
type vmessPacketConn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
rAddr net.Addr
|
rAddr net.Addr
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
)
|
)
|
||||||
|
@ -66,3 +67,22 @@ func waitReadFrom(pc net.PacketConn) (data []byte, put func(), addr net.Addr, er
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type threadSafePacketConn struct {
|
||||||
|
net.PacketConn
|
||||||
|
access sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *threadSafePacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
|
c.access.Lock()
|
||||||
|
defer c.access.Unlock()
|
||||||
|
return c.PacketConn.WriteTo(b, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *threadSafePacketConn) Upstream() any {
|
||||||
|
return c.PacketConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewThreadSafePacketConn(pc net.PacketConn) net.PacketConn {
|
||||||
|
return &threadSafePacketConn{PacketConn: pc}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue