wgengine/magicsock: fix check for EPERM on macOS

Like Linux, macOS will reply to sendto(2) with EPERM if the firewall is
currently blocking writes, though this behavior is like Linux
undocumented. This is often caused by a faulting network extension or
content filter from EDR software.

Updates #11710
Updates #12891
Updates #13511

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2024-09-25 16:06:21 -07:00
committed by James Tucker
parent 717d589149
commit 9eb59c72c1
2 changed files with 12 additions and 7 deletions
+10 -5
View File
@@ -2965,26 +2965,31 @@ func TestMaybeRebindOnError(t *testing.T) {
tstest.PanicOnLog()
tstest.ResourceCheck(t)
conn := newTestConn(t)
defer conn.Close()
err := fmt.Errorf("outer err: %w", syscall.EPERM)
t.Run("darwin-rebind", func(t *testing.T) {
rebound := conn.maybeRebindOnError("darwin", syscall.EPERM)
conn := newTestConn(t)
defer conn.Close()
rebound := conn.maybeRebindOnError("darwin", err)
if !rebound {
t.Errorf("darwin should rebind on syscall.EPERM")
}
})
t.Run("linux-not-rebind", func(t *testing.T) {
rebound := conn.maybeRebindOnError("linux", syscall.EPERM)
conn := newTestConn(t)
defer conn.Close()
rebound := conn.maybeRebindOnError("linux", err)
if rebound {
t.Errorf("linux should not rebind on syscall.EPERM")
}
})
t.Run("no-frequent-rebind", func(t *testing.T) {
conn := newTestConn(t)
defer conn.Close()
conn.lastEPERMRebind.Store(time.Now().Add(-1 * time.Second))
rebound := conn.maybeRebindOnError("darwin", syscall.EPERM)
rebound := conn.maybeRebindOnError("darwin", err)
if rebound {
t.Errorf("darwin should not rebind on syscall.EPERM within 5 seconds of last")
}