fix: mux's udp should add write lock

This commit is contained in:
wwqgtxx 2023-05-11 15:34:28 +08:00
parent 75cd72385a
commit e404695a0d
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 { 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 {

View file

@ -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
} }

View file

@ -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

View file

@ -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}
}