fix: mux's udp should add write lock

This commit is contained in:
gVisor bot 2023-05-11 15:34:28 +08:00
parent 82be6a68ad
commit 0253db1a1a
4 changed files with 29 additions and 19 deletions

View file

@ -92,7 +92,7 @@ func (s *SingMux) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
if pc == 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 {

View file

@ -13,6 +13,7 @@ import (
"sync"
"github.com/Dreamacro/clash/common/convert"
N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/proxydialer"
"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 {
return newPacketConn(&threadSafePacketConn{
PacketConn: vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
}, v), nil
return newPacketConn(N.NewThreadSafePacketConn(
vmessSing.NewXUDPConn(c, M.SocksaddrFromNet(metadata.UDPAddr())),
), v), nil
} else if v.option.PacketAddr {
return newPacketConn(&threadSafePacketConn{
PacketConn: packetaddr.NewConn(&vlessPacketConn{
return newPacketConn(N.NewThreadSafePacketConn(
packetaddr.NewConn(&vlessPacketConn{
Conn: c, rAddr: metadata.UDPAddr(),
}, M.SocksaddrFromNet(metadata.UDPAddr())),
}, v), nil
), v), nil
}
return newPacketConn(&vlessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
}

View file

@ -379,7 +379,7 @@ func (v *Vmess) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metada
}
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
}
@ -489,17 +489,6 @@ func NewVmess(option VmessOption) (*Vmess, error) {
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 {
net.Conn
rAddr net.Addr

View file

@ -2,6 +2,7 @@ package net
import (
"net"
"sync"
"github.com/Dreamacro/clash/common/pool"
)
@ -66,3 +67,22 @@ func waitReadFrom(pc net.PacketConn) (data []byte, put func(), addr net.Addr, er
}
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}
}