diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go index 0b3c551c0..f07e4909e 100644 --- a/net/tstun/wrap.go +++ b/net/tstun/wrap.go @@ -413,6 +413,16 @@ func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response { return filter.DropSilently // don't pass on to OS; already handled } + // Issue 1526 workaround: if we sent disco packets over + // Tailscale from ourselves, then drop them, as that shouldn't + // happen unless a networking stack is confused, as it seems + // macOS in Network Extension mode might be. + if p.IPProto == ipproto.UDP && // disco is over UDP; avoid isSelfDisco call for TCP/etc + t.isSelfDisco(p) { + t.logf("[unexpected] received self disco out packet over tstun; dropping") + return filter.DropSilently + } + if t.PreFilterOut != nil { if res := t.PreFilterOut(p, t); res.IsDrop() { return res @@ -517,7 +527,7 @@ func (t *Wrapper) filterIn(buf []byte) filter.Response { // macOS in Network Extension mode might be. if p.IPProto == ipproto.UDP && // disco is over UDP; avoid isSelfDisco call for TCP/etc t.isSelfDisco(p) { - t.logf("[unexpected] received self disco package over tstun; dropping") + t.logf("[unexpected] received self disco in packet over tstun; dropping") return filter.DropSilently } diff --git a/net/tstun/wrap_test.go b/net/tstun/wrap_test.go index d83278f97..37a1eb175 100644 --- a/net/tstun/wrap_test.go +++ b/net/tstun/wrap_test.go @@ -514,7 +514,18 @@ func TestFilterDiscoLoop(t *testing.T) { if got != filter.DropSilently { t.Errorf("got %v; want DropSilently", got) } - if got, want := memLog.String(), "[unexpected] received self disco package over tstun; dropping\n"; got != want { + if got, want := memLog.String(), "[unexpected] received self disco in packet over tstun; dropping\n"; got != want { + t.Errorf("log output mismatch\n got: %q\nwant: %q\n", got, want) + } + + memLog.Reset() + pp := new(packet.Parsed) + pp.Decode(pkt) + got = tw.filterOut(pp) + if got != filter.DropSilently { + t.Errorf("got %v; want DropSilently", got) + } + if got, want := memLog.String(), "[unexpected] received self disco out packet over tstun; dropping\n"; got != want { t.Errorf("log output mismatch\n got: %q\nwant: %q\n", got, want) } }