diff --git a/proxy/wireguard/netstack.go b/proxy/wireguard/netstack.go index e5a15cfb9..32f49593d 100644 --- a/proxy/wireguard/netstack.go +++ b/proxy/wireguard/netstack.go @@ -44,6 +44,7 @@ type netTun struct { events chan tun.Event notifyHandle *channel.NotificationHandle incomingPacket chan *buffer.View + closed chan struct{} mtu int dnsServers []netip.Addr hasV4, hasV6 bool @@ -60,6 +61,7 @@ func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int, handleLocal stack: stack.New(opts), events: make(chan tun.Event, 10), incomingPacket: make(chan *buffer.View), + closed: make(chan struct{}), dnsServers: dnsServers, 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) { - view, ok := <-tun.incomingPacket - if !ok { + var view *buffer.View + select { + case view = <-tun.incomingPacket: + case <-tun.closed: return 0, os.ErrClosed } @@ -168,7 +172,10 @@ func (tun *netTun) WriteNotify() { view := pkt.ToView() pkt.DecRef() - tun.incomingPacket <- view + select { + case tun.incomingPacket <- view: + case <-tun.closed: + } } func (tun *netTun) Close() error { @@ -181,8 +188,9 @@ func (tun *netTun) Close() error { close(tun.events) } - if tun.incomingPacket != nil { - close(tun.incomingPacket) + // we don't close incomingPacket, because WriteNotify may be mid-send on it (DNS lookup) and would panic. + if tun.closed != nil { + close(tun.closed) } return nil