Skip to content

Commit e6c219a

Browse files
committed
Fix race condition in ReadPacket
1 parent ddc824f commit e6c219a

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

tun_windows.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,23 +395,27 @@ retry:
395395

396396
func (t *NativeTun) ReadPacket() ([]byte, func(), error) {
397397
t.running.Add(1)
398-
defer t.running.Done()
399398
retry:
400399
if t.close.Load() == 1 {
400+
t.running.Done()
401401
return nil, nil, os.ErrClosed
402402
}
403403
start := nanotime()
404404
shouldSpin := t.rate.current.Load() >= spinloopRateThreshold && uint64(start-t.rate.nextStartTime.Load()) <= rateMeasurementGranularity*2
405405
for {
406406
if t.close.Load() == 1 {
407+
t.running.Done()
407408
return nil, nil, os.ErrClosed
408409
}
409410
packet, err := t.session.ReceivePacket()
410411
switch err {
411412
case nil:
412413
packetSize := len(packet)
413414
t.rate.update(uint64(packetSize))
414-
return packet, func() { t.session.ReleaseReceivePacket(packet) }, nil
415+
return packet, func() {
416+
t.session.ReleaseReceivePacket(packet)
417+
t.running.Done()
418+
}, nil
415419
case windows.ERROR_NO_MORE_ITEMS:
416420
if !shouldSpin || uint64(nanotime()-start) >= spinloopDuration {
417421
windows.WaitForSingleObject(t.readWait, windows.INFINITE)
@@ -420,10 +424,13 @@ retry:
420424
procyield(1)
421425
continue
422426
case windows.ERROR_HANDLE_EOF:
427+
t.running.Done()
423428
return nil, nil, os.ErrClosed
424429
case windows.ERROR_INVALID_DATA:
430+
t.running.Done()
425431
return nil, nil, errors.New("send ring corrupt")
426432
}
433+
t.running.Done()
427434
return nil, nil, fmt.Errorf("read failed: %w", err)
428435
}
429436
}

0 commit comments

Comments
 (0)