mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-01 14:05:39 +00:00
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:
parent
3e4c46259d
commit
5041800ac6
@ -12,7 +12,6 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
type fakeTUN struct {
|
type fakeTUN struct {
|
||||||
datachan chan []byte
|
|
||||||
evchan chan tun.Event
|
evchan chan tun.Event
|
||||||
closechan chan struct{}
|
closechan chan struct{}
|
||||||
}
|
}
|
||||||
@ -22,7 +21,6 @@ type fakeTUN struct {
|
|||||||
// It primarily exists for testing.
|
// It primarily exists for testing.
|
||||||
func NewFakeTUN() tun.Device {
|
func NewFakeTUN() tun.Device {
|
||||||
return &fakeTUN{
|
return &fakeTUN{
|
||||||
datachan: make(chan []byte),
|
|
||||||
evchan: make(chan tun.Event),
|
evchan: make(chan tun.Event),
|
||||||
closechan: make(chan struct{}),
|
closechan: make(chan struct{}),
|
||||||
}
|
}
|
||||||
@ -39,22 +37,17 @@ func (t *fakeTUN) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *fakeTUN) Read(out []byte, offset int) (int, error) {
|
func (t *fakeTUN) Read(out []byte, offset int) (int, error) {
|
||||||
select {
|
<-t.closechan
|
||||||
case <-t.closechan:
|
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
case b := <-t.datachan:
|
|
||||||
copy(out[offset:offset+len(b)], b)
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *fakeTUN) Write(b []byte, n int) (int, error) {
|
func (t *fakeTUN) Write(b []byte, n int) (int, error) {
|
||||||
select {
|
select {
|
||||||
case <-t.closechan:
|
case <-t.closechan:
|
||||||
return 0, ErrClosed
|
return 0, ErrClosed
|
||||||
case t.datachan <- b[n:]:
|
default:
|
||||||
return len(b), nil
|
|
||||||
}
|
}
|
||||||
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *fakeTUN) Flush() error { return nil }
|
func (t *fakeTUN) Flush() error { return nil }
|
||||||
|
@ -274,39 +274,13 @@ func TestAllocs(t *testing.T) {
|
|||||||
ftun, tun := newFakeTUN(t.Logf, false)
|
ftun, tun := newFakeTUN(t.Logf, false)
|
||||||
defer tun.Close()
|
defer tun.Close()
|
||||||
|
|
||||||
go func() {
|
|
||||||
var buf []byte
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-tun.closed:
|
|
||||||
return
|
|
||||||
case buf = <-ftun.datachan:
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-tun.closed:
|
|
||||||
return
|
|
||||||
case ftun.datachan <- buf:
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
buf := []byte{0x00}
|
buf := []byte{0x00}
|
||||||
allocs := testing.AllocsPerRun(100, func() {
|
allocs := testing.AllocsPerRun(100, func() {
|
||||||
_, err := tun.Write(buf, 0)
|
_, err := ftun.Write(buf, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("write: error: %v", err)
|
t.Errorf("write: error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tun.Read(buf, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("read: error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if allocs > 0 {
|
if allocs > 0 {
|
||||||
@ -318,45 +292,9 @@ func BenchmarkWrite(b *testing.B) {
|
|||||||
ftun, tun := newFakeTUN(b.Logf, true)
|
ftun, tun := newFakeTUN(b.Logf, true)
|
||||||
defer tun.Close()
|
defer tun.Close()
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-tun.closed:
|
|
||||||
return
|
|
||||||
case <-ftun.datachan:
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
packet := udp(0x05060708, 0x01020304, 89, 89)
|
packet := udp(0x05060708, 0x01020304, 89, 89)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, err := tun.Write(packet, 0)
|
_, err := ftun.Write(packet, 0)
|
||||||
if err != nil {
|
|
||||||
b.Errorf("err = %v; want nil", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRead(b *testing.B) {
|
|
||||||
ftun, tun := newFakeTUN(b.Logf, true)
|
|
||||||
defer tun.Close()
|
|
||||||
|
|
||||||
packet := udp(0x05060708, 0x01020304, 89, 89)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-tun.closed:
|
|
||||||
return
|
|
||||||
case ftun.datachan <- packet:
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var buf [128]byte
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_, err := tun.Read(buf[:], 0)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Errorf("err = %v; want nil", err)
|
b.Errorf("err = %v; want nil", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user