google / google/gopacket

Allow to cancel the PacketSource.Packets() underlying Goroutine

Open
#892 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
6.8k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

While working on [gitlab.com/inetmock/inetmock](https://gitlab.com/inetmock/inetmock) and making sure I don't have any race conditions I noticed some edge cases with gopacket's `EthernetHandle` and `PacketSource`.

Similar to issue #890 I wanted to stop the PCAP recording while the process continues. Therefore I'm closing the `EthernetHandle`. While this seems to work, the `-race` switch detects a problem because the underlying Goroutine of the `PacketSource.Packets()` call continues to use the file descriptor for the socket while the `Close() error` function closes the handle because `Close() error` does not lock the `EthernetHandle` instance.

Furthermore the `SYS_RECVMSG` syscall blocks if the `MSG_DONTWAIT` flag is not used which blocks the Goroutine from `PacketSource.Packets()` even if it has a `context.Context` to check if it shall continue the routine isn't returning and therefore not closing the upstream channel.

I prepared a patch to:

* lock the `EthernetHandle` instance while closing the file descriptor
* check in `EthernetHandle` if the underlying handle got closed and return an `io.EOF` error (this also stops the `PacketSource.Packets()` call)
* add `MSG_DONTWAIT` flag to the syscall to return if the handle got closed
* add an `PacketSource.PacketsCtx(ctx context.Context)` overload to allow cancellation of the underlying Goroutine by not breaking the current behavior by submitting a `context.Background()` in the original function
* replace `err == ...` calls with the Go 1.13 `errors.Is(...)` function to improve the error checking
* add some tests to make sure everything works as expected and to show how it works

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.