wgengine/tstun/faketun: it's a null tunnel, not a loopback.

At some point faketun got implemented as a loopback (put a packet in
from wireguard, the same packet goes back to wireguard) which is not
useful. It's supposed to be an interface that just sinks all packets,
and then wgengine adds *only* and ICMP Echo responder as a layer on
top.

This caused extremely odd bugs on darwin, where the special case that
reinjects packets from local->local was filling the loopback channel
and creating an infinite loop (which became jammed since the reader and
writer were in the same goroutine).

Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This commit is contained in:
Avery Pennarun
2020-10-05 22:36:48 -04:00
parent 3e4c46259d
commit 5041800ac6
2 changed files with 6 additions and 75 deletions
+4 -11
View File
@@ -12,7 +12,6 @@ import (
)
type fakeTUN struct {
datachan chan []byte
evchan chan tun.Event
closechan chan struct{}
}
@@ -22,7 +21,6 @@ type fakeTUN struct {
// It primarily exists for testing.
func NewFakeTUN() tun.Device {
return &fakeTUN{
datachan: make(chan []byte),
evchan: make(chan tun.Event),
closechan: make(chan struct{}),
}
@@ -39,22 +37,17 @@ func (t *fakeTUN) Close() error {
}
func (t *fakeTUN) Read(out []byte, offset int) (int, error) {
select {
case <-t.closechan:
return 0, io.EOF
case b := <-t.datachan:
copy(out[offset:offset+len(b)], b)
return len(b), nil
}
<-t.closechan
return 0, io.EOF
}
func (t *fakeTUN) Write(b []byte, n int) (int, error) {
select {
case <-t.closechan:
return 0, ErrClosed
case t.datachan <- b[n:]:
return len(b), nil
default:
}
return len(b), nil
}
func (t *fakeTUN) Flush() error { return nil }