Skip to content

Commit 781907b

Browse files
committed
tun: fix race during WriteNotify and Close
Signed-off-by: Spike Curtis <[email protected]>
1 parent cc193a0 commit 781907b

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

tun/netstack/tun.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type netTun struct {
4444
stack *stack.Stack
4545
events chan tun.Event
4646
incomingPacket chan *buffer.View
47+
closed chan struct{}
4748
mtu int
4849
dnsServers []netip.Addr
4950
hasV4, hasV6 bool
@@ -62,6 +63,7 @@ func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device,
6263
stack: stack.New(opts),
6364
events: make(chan tun.Event, 10),
6465
incomingPacket: make(chan *buffer.View),
66+
closed: make(chan struct{}),
6567
dnsServers: dnsServers,
6668
mtu: mtu,
6769
}
@@ -120,17 +122,17 @@ func (tun *netTun) Events() <-chan tun.Event {
120122
}
121123

122124
func (tun *netTun) Read(buf [][]byte, sizes []int, offset int) (int, error) {
123-
view, ok := <-tun.incomingPacket
124-
if !ok {
125+
select {
126+
case view := <-tun.incomingPacket:
127+
n, err := view.Read(buf[0][offset:])
128+
if err != nil {
129+
return 0, err
130+
}
131+
sizes[0] = n
132+
return 1, nil
133+
case <-tun.closed:
125134
return 0, os.ErrClosed
126135
}
127-
128-
n, err := view.Read(buf[0][offset:])
129-
if err != nil {
130-
return 0, err
131-
}
132-
sizes[0] = n
133-
return 1, nil
134136
}
135137

136138
func (tun *netTun) Write(buf [][]byte, offset int) (int, error) {
@@ -162,7 +164,10 @@ func (tun *netTun) WriteNotify() {
162164
view := pkt.ToView()
163165
pkt.DecRef()
164166

165-
tun.incomingPacket <- view
167+
select {
168+
case tun.incomingPacket <- view:
169+
case <-tun.closed:
170+
}
166171
}
167172

168173
func (tun *netTun) Close() error {
@@ -174,8 +179,8 @@ func (tun *netTun) Close() error {
174179

175180
tun.ep.Close()
176181

177-
if tun.incomingPacket != nil {
178-
close(tun.incomingPacket)
182+
if tun.closed != nil {
183+
close(tun.closed)
179184
}
180185

181186
return nil

0 commit comments

Comments
 (0)