* fix: resolve deadlock in `Flush` function when handling ENOBUFS error
* Simulate deadlock issue using reduced read/write buffers to verify the fix and ensure no regressions
Related: #242
After 7879d7ecf6, it seems that
any multi-message operation performed without CAP_SYS_ADMIN will
leads to forever block inside nftables.Conn.Flush.
For example:
```go
package main
import "github.com/google/nftables"
func main() {
conn, err := nftables.New()
if err != nil {
panic(err)
}
t := conn.AddTable(&nftables.Table{})
err = conn.AddSet(&nftables.Set{Table: t}, []nftables.SetElement{})
if err != nil {
panic(err)
}
conn.AddSet(&nftables.Set{Table: t}, []nftables.SetElement{})
if err != nil {
panic(err)
}
err = conn.Flush()
if err != nil {
panic(err)
}
return
}
```
That's because that although we send multiple messages on netlink
socket, kernel will only sends one permission error message as reply.
Signed-off-by: black-desk <me@black-desk.cn>
When you flush multiple messages/ops on a connection, and if flush fails
to apply, the netlink connection returns errors per command. Since we
are returning on noticing the first error, the rest of the errors are
buffered and leaks into the result of next flush.
This pull request invokes `conn.Receive()` * number of messages to drain
any buffered errors in the connection.
* Close receiver for lasting netlink connections while defaulting to existing temporary netlink connection usage
* add unit test for New lasting connection, Close and correct default connection handling behavior
* refactor tests to use New constructor
* make Conn mutex un-exported (#159)
fixes issue #157