WireGuard proxy: Prevent panic when closing netTun with a write in flight (#6778)

https://github.com/XTLS/Xray-core/pull/6778#pullrequestreview-5251957308
This commit is contained in:
Hossin Asaadi
2026-09-20 20:07:54 +00:00
committed by GitHub
parent efc9e6da62
commit dbb1ea30ba
+13 -5
View File
@@ -44,6 +44,7 @@ type netTun struct {
events chan tun.Event events chan tun.Event
notifyHandle *channel.NotificationHandle notifyHandle *channel.NotificationHandle
incomingPacket chan *buffer.View incomingPacket chan *buffer.View
closed chan struct{}
mtu int mtu int
dnsServers []netip.Addr dnsServers []netip.Addr
hasV4, hasV6 bool hasV4, hasV6 bool
@@ -60,6 +61,7 @@ func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int, handleLocal
stack: stack.New(opts), stack: stack.New(opts),
events: make(chan tun.Event, 10), events: make(chan tun.Event, 10),
incomingPacket: make(chan *buffer.View), incomingPacket: make(chan *buffer.View),
closed: make(chan struct{}),
dnsServers: dnsServers, dnsServers: dnsServers,
mtu: mtu, mtu: mtu,
} }
@@ -126,8 +128,10 @@ func (tun *netTun) Events() <-chan tun.Event {
} }
func (tun *netTun) Read(buf [][]byte, sizes []int, offset int) (int, error) { func (tun *netTun) Read(buf [][]byte, sizes []int, offset int) (int, error) {
view, ok := <-tun.incomingPacket var view *buffer.View
if !ok { select {
case view = <-tun.incomingPacket:
case <-tun.closed:
return 0, os.ErrClosed return 0, os.ErrClosed
} }
@@ -168,7 +172,10 @@ func (tun *netTun) WriteNotify() {
view := pkt.ToView() view := pkt.ToView()
pkt.DecRef() pkt.DecRef()
tun.incomingPacket <- view select {
case tun.incomingPacket <- view:
case <-tun.closed:
}
} }
func (tun *netTun) Close() error { func (tun *netTun) Close() error {
@@ -181,8 +188,9 @@ func (tun *netTun) Close() error {
close(tun.events) close(tun.events)
} }
if tun.incomingPacket != nil { // we don't close incomingPacket, because WriteNotify may be mid-send on it (DNS lookup) and would panic.
close(tun.incomingPacket) if tun.closed != nil {
close(tun.closed)
} }
return nil return nil