Fix concurrency vmess udp write
This commit is contained in:
parent
6664547f43
commit
6b44178108
1 changed files with 20 additions and 5 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/convert"
|
"github.com/Dreamacro/clash/common/convert"
|
||||||
"github.com/Dreamacro/clash/component/dialer"
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
|
@ -267,9 +268,9 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.option.PacketAddr {
|
if v.option.PacketAddr {
|
||||||
return newPacketConn(packetaddr.NewBindClient(c), v), nil
|
return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindClient(c)}, v), nil
|
||||||
} else if pc, ok := c.(net.PacketConn); ok {
|
} else if pc, ok := c.(net.PacketConn); ok {
|
||||||
return newPacketConn(pc, v), nil
|
return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil
|
||||||
}
|
}
|
||||||
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
||||||
}
|
}
|
||||||
|
@ -277,9 +278,9 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata, o
|
||||||
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
||||||
func (v *Vmess) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
func (v *Vmess) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||||
if v.option.PacketAddr {
|
if v.option.PacketAddr {
|
||||||
return newPacketConn(packetaddr.NewBindClient(c), v), nil
|
return newPacketConn(&threadSafePacketConn{PacketConn: packetaddr.NewBindClient(c)}, v), nil
|
||||||
} else if pc, ok := c.(net.PacketConn); ok {
|
} else if pc, ok := c.(net.PacketConn); ok {
|
||||||
return newPacketConn(pc, v), nil
|
return newPacketConn(&threadSafePacketConn{PacketConn: pc}, v), nil
|
||||||
}
|
}
|
||||||
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
return newPacketConn(&vmessPacketConn{Conn: c, rAddr: metadata.UDPAddr()}, v), nil
|
||||||
}
|
}
|
||||||
|
@ -357,12 +358,26 @@ 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
|
||||||
|
access sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uc *vmessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
func (uc *vmessPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
|
uc.access.Lock()
|
||||||
|
defer uc.access.Unlock()
|
||||||
return uc.Conn.Write(b)
|
return uc.Conn.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue