net/tstun: block looped disco traffic, take 17

It was in the wrong filter direction before, per CPU profiles
we now have.

Updates #1526 (maybe fixes? time will tell)

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/2972/head
Brad Fitzpatrick 3 years ago committed by Brad Fitzpatrick
parent 3618e8d8ac
commit 080381c79f

@ -413,6 +413,16 @@ func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response {
return filter.DropSilently // don't pass on to OS; already handled 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 t.PreFilterOut != nil {
if res := t.PreFilterOut(p, t); res.IsDrop() { if res := t.PreFilterOut(p, t); res.IsDrop() {
return res return res
@ -517,7 +527,7 @@ func (t *Wrapper) filterIn(buf []byte) filter.Response {
// macOS in Network Extension mode might be. // macOS in Network Extension mode might be.
if p.IPProto == ipproto.UDP && // disco is over UDP; avoid isSelfDisco call for TCP/etc if p.IPProto == ipproto.UDP && // disco is over UDP; avoid isSelfDisco call for TCP/etc
t.isSelfDisco(p) { 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 return filter.DropSilently
} }

@ -514,7 +514,18 @@ func TestFilterDiscoLoop(t *testing.T) {
if got != filter.DropSilently { if got != filter.DropSilently {
t.Errorf("got %v; want DropSilently", got) 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) t.Errorf("log output mismatch\n got: %q\nwant: %q\n", got, want)
} }
} }

Loading…
Cancel
Save