Description
In
oute/route.go:709-768, the packet sniffing loop has a data race and potential use-after-close on \inputPacketConn:
The code pattern:
go for { // ... go func() { inputPacketConn.SetReadDeadline(time.Now().Add(sniffTimeout)) destination, err = inputPacketConn.ReadPacket(sniffBuffer) inputPacketConn.SetReadDeadline(time.Time{}) close(done) }() select { case <-done: case <-ctx.Done(): inputPacketConn.Close() // <-- closes while goroutine may be running fatalErr = ctx.Err() return } // ... if errors.Is(err, sniff.ErrNeedMoreData) { continue // <-- new goroutine created while old one may still be running } goto finally }
Issues:
-
Use-after-close: When \ctx.Done()\ fires, \inputPacketConn.Close()\ is called at line 728 while the goroutine may still be calling \ReadPacket()\ and \SetReadDeadline()\ at lines 720-722 on the same connection.
-
Concurrent SetReadDeadline: After \continue\ at line 764 (when sniffers return \ErrNeedMoreData), a new goroutine is spawned that calls \SetReadDeadline\ on \inputPacketConn. The old goroutine is guaranteed to have finished (we received from \done), but the \ctx.Done()\ path can race with the goroutine.
Location
oute/route.go:709-768\
Suggested Fix
Use proper synchronization to ensure the goroutine is finished before closing the connection. Options include:
- Track the goroutine with a \sync.WaitGroup\ and wait for it before closing
- Use a mutex to protect access to \inputPacketConn\
- Move the conn operations out of the goroutine and use \SetReadDeadline\ + \Read\ in the main goroutine with a timer
Description
In
oute/route.go:709-768, the packet sniffing loop has a data race and potential use-after-close on \inputPacketConn:
The code pattern:
go for { // ... go func() { inputPacketConn.SetReadDeadline(time.Now().Add(sniffTimeout)) destination, err = inputPacketConn.ReadPacket(sniffBuffer) inputPacketConn.SetReadDeadline(time.Time{}) close(done) }() select { case <-done: case <-ctx.Done(): inputPacketConn.Close() // <-- closes while goroutine may be running fatalErr = ctx.Err() return } // ... if errors.Is(err, sniff.ErrNeedMoreData) { continue // <-- new goroutine created while old one may still be running } goto finally }Issues:
Use-after-close: When \ctx.Done()\ fires, \inputPacketConn.Close()\ is called at line 728 while the goroutine may still be calling \ReadPacket()\ and \SetReadDeadline()\ at lines 720-722 on the same connection.
Concurrent SetReadDeadline: After \continue\ at line 764 (when sniffers return \ErrNeedMoreData), a new goroutine is spawned that calls \SetReadDeadline\ on \inputPacketConn. The old goroutine is guaranteed to have finished (we received from \done), but the \ctx.Done()\ path can race with the goroutine.
Location
oute/route.go:709-768\
Suggested Fix
Use proper synchronization to ensure the goroutine is finished before closing the connection. Options include: